mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #16204 from leandrolanzieri/pr/pkg/wakaama_add_obj_light_ctrl
pkg/wakaama: add Light Control object implementation
This commit is contained in:
commit
d3ec7cf70d
@ -32,6 +32,7 @@ SERVER_URI ?= '"coap://[fd00:dead:beef::1]"'
|
||||
|
||||
# NOTE: Add the package for wakaama
|
||||
USEPKG += wakaama
|
||||
USEMODULE += wakaama_objects_light_control
|
||||
# Uncomment to enable Wakaama debug log
|
||||
#CFLAGS += -DCONFIG_LWM2M_WITH_LOGS=1
|
||||
|
||||
|
@ -6,10 +6,10 @@ on the node with instances of the following objects:
|
||||
- [Security object](http://www.openmobilealliance.org/tech/profiles/LWM2M_Security-v1_0.xml)
|
||||
- [Server object](http://www.openmobilealliance.org/tech/profiles/LWM2M_Server-v1_0.xml)
|
||||
- [Device object](http://www.openmobilealliance.org/tech/profiles/LWM2M_Device-v1_0_3.xml)
|
||||
- [Light control object](https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/3311.xml)
|
||||
|
||||
The application is based on the Eclipse Wakaama
|
||||
[example client](https://github.com/eclipse/wakaama/tree/master/examples/client)
|
||||
.
|
||||
[example client](https://github.com/eclipse/wakaama/tree/master/examples/client).
|
||||
|
||||
## Usage
|
||||
|
||||
@ -18,10 +18,13 @@ To test the client a LwM2M server where to register is needed.
|
||||
[Eclipse Leshan](https://github.com/eclipse/leshan) demo is a good option for
|
||||
running one locally.
|
||||
|
||||
To run the demo server:
|
||||
To run the demo server, download the jar file:
|
||||
```shell
|
||||
wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-server-demo.jar
|
||||
```
|
||||
|
||||
And run it:
|
||||
```shell
|
||||
java -jar ./leshan-server-demo.jar
|
||||
```
|
||||
It will output the addresses where it is listening:
|
||||
@ -48,11 +51,15 @@ By default the bootstrap server option is disabled, it can be enabled by definin
|
||||
To run the bootstrap server, make sure that the ports it uses are different
|
||||
from the ones of previous server (default are 5683 for CoAP, 5684 for CoAPs,
|
||||
and 8080 for the webserver), and that it corresponds to the one set in
|
||||
`lwm2m.h` as `CONFIG_LWM2M_BSSERVER_PORT`:
|
||||
```shell
|
||||
# download demo
|
||||
wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar
|
||||
`lwm2m.h` as `CONFIG_LWM2M_BSSERVER_PORT`.
|
||||
|
||||
Download the jar file:
|
||||
```shell
|
||||
wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar
|
||||
```
|
||||
|
||||
And run it:
|
||||
```shell# download demo
|
||||
# set CoAP, CoAPs and webserver ports for bootstrap server
|
||||
BS_COAPPORT=5685
|
||||
BS_COAPSPORT=5686
|
||||
@ -111,3 +118,7 @@ BOARD=<board> make clean all flash term
|
||||
#### Shell commands
|
||||
- `lwm2m start`: Starts the LwM2M by configuring the module and registering to
|
||||
the server.
|
||||
- `lwm2m light <on|off> <dimmer> [color]`: Sets the light state to on or off,
|
||||
with a given dimmer value and optional color.
|
||||
- `lwm2m mem`: (Only available if `DEVELHELP` is enabled in your Makefile) Prints the memory
|
||||
usage of the LwM2M module.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
* Copyright (C) 2024 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -11,23 +11,47 @@
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Wakaama LwM2M Client CLI support
|
||||
* @brief Wakaama LwM2M Client example CLI support
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "board.h"
|
||||
#include "lwm2m_client.h"
|
||||
#include "lwm2m_client_objects.h"
|
||||
#include "lwm2m_platform.h"
|
||||
#include "objects/light_control.h"
|
||||
#include "objects/common.h"
|
||||
|
||||
#define OBJ_COUNT (3)
|
||||
#define LED_COLOR "FFFFFF"
|
||||
#define LED_APP_TYPE "LED 0"
|
||||
# define OBJ_COUNT (4)
|
||||
|
||||
uint8_t connected = 0;
|
||||
lwm2m_object_t *obj_list[OBJ_COUNT];
|
||||
lwm2m_client_data_t client_data;
|
||||
|
||||
void _light_cb(lwm2m_object_t *object, uint16_t instance_id, bool status, uint8_t dimmer,
|
||||
const char* color, const char* app_type, void *arg)
|
||||
{
|
||||
(void)object;
|
||||
(void)instance_id;
|
||||
(void)arg;
|
||||
|
||||
printf("LED (%s) is now %s, with color %s and intensity %d%%\n", app_type, status? "ON":"OFF",
|
||||
color, dimmer);
|
||||
|
||||
#ifdef LED0_ON
|
||||
if (status) {
|
||||
LED0_ON;
|
||||
}
|
||||
else {
|
||||
LED0_OFF;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void lwm2m_cli_init(void)
|
||||
{
|
||||
/* this call is needed before creating any objects */
|
||||
@ -37,12 +61,56 @@ void lwm2m_cli_init(void)
|
||||
obj_list[0] = lwm2m_client_get_security_object(&client_data);
|
||||
obj_list[1] = lwm2m_client_get_server_object(&client_data);
|
||||
obj_list[2] = lwm2m_client_get_device_object(&client_data);
|
||||
obj_list[3] = lwm2m_object_light_control_init(&client_data);
|
||||
|
||||
lwm2m_obj_light_control_args_t args = {
|
||||
.cb = _light_cb,
|
||||
.cb_arg = NULL,
|
||||
.color = LED_COLOR,
|
||||
.color_len = sizeof(LED_COLOR) - 1,
|
||||
.app_type = LED_APP_TYPE,
|
||||
.app_type_len = sizeof(LED_APP_TYPE) - 1
|
||||
};
|
||||
|
||||
int res = lwm2m_object_light_control_instance_create(&args, 0);
|
||||
|
||||
if (res < 0) {
|
||||
puts("Error instantiating light control");
|
||||
}
|
||||
|
||||
if (!obj_list[0] || !obj_list[1] || !obj_list[2]) {
|
||||
puts("Could not create mandatory objects");
|
||||
}
|
||||
}
|
||||
|
||||
static int _parse_lwm2m_light_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc < 4) {
|
||||
printf("usage: %s light <on|off> <dimmer> [color]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
puts("LwM2M client not connected");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool status = !strcmp(argv[2], "on");
|
||||
uint8_t dimmer = atoi(argv[3]);
|
||||
|
||||
if (argc > 4) {
|
||||
char* color = argv[4];
|
||||
lwm2m_object_light_control_update_color(0, color, strlen(color), false);
|
||||
}
|
||||
|
||||
lwm2m_object_light_control_update_status(0, status, false);
|
||||
|
||||
/* call the callback now to actually update the light */
|
||||
lwm2m_object_light_control_update_dimmer(0, dimmer, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwm2m_cli_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
@ -57,17 +125,21 @@ int lwm2m_cli_cmd(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ACTIVE(DEVELHELP) && !strcmp(argv[1],"mem")) {
|
||||
if (IS_ACTIVE(DEVELHELP) && !strcmp(argv[1], "mem")) {
|
||||
lwm2m_tlsf_status();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "light")) {
|
||||
return _parse_lwm2m_light_cmd(argc, argv);
|
||||
}
|
||||
|
||||
help_error:
|
||||
if (IS_ACTIVE(DEVELHELP)) {
|
||||
printf("usage: %s <start|mem>\n", argv[0]);
|
||||
printf("usage: %s <start|mem|light>\n", argv[0]);
|
||||
}
|
||||
else {
|
||||
printf("usage: %s <start>\n", argv[0]);
|
||||
printf("usage: %s <start|light>\n", argv[0]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -126,4 +126,6 @@ config LWM2M_TLSF_BUFFER
|
||||
int "Allocation buffer size"
|
||||
default 5120
|
||||
|
||||
rsource "contrib/objects/Kconfig"
|
||||
|
||||
endif # KCONFIG_USEPKG_WAKAAMA
|
||||
|
8
pkg/wakaama/contrib/objects/Kconfig
Normal file
8
pkg/wakaama/contrib/objects/Kconfig
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
rsource "Kconfig.light_control"
|
22
pkg/wakaama/contrib/objects/Kconfig.light_control
Normal file
22
pkg/wakaama/contrib/objects/Kconfig.light_control
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2021 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
menu "Light Control object"
|
||||
|
||||
config LWM2M_LIGHT_INSTANCES_MAX
|
||||
int "Maximum number of Light Control object instances"
|
||||
default 3
|
||||
|
||||
config LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE
|
||||
int "Maximum size of a Light Control color string"
|
||||
default 16
|
||||
|
||||
config LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE
|
||||
int "Maximum size of a Light Control application type string"
|
||||
default 16
|
||||
|
||||
endmenu # Light Control object
|
619
pkg/wakaama/contrib/objects/light_control.c
Normal file
619
pkg/wakaama/contrib/objects/light_control.c
Normal file
@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright (C) 2024 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @{
|
||||
* @ingroup lwm2m_objects_light_control
|
||||
*
|
||||
* @file
|
||||
* @brief Light Control object implementation for LwM2M client using Wakaama
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "mutex.h"
|
||||
#include "inttypes.h"
|
||||
#include "liblwm2m.h"
|
||||
#include "lwm2m_client.h"
|
||||
#include "objects/light_control.h"
|
||||
#include "ztimer.h"
|
||||
#include "ztimer/stopwatch.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define _USED_INSTANCES(_obj) (_obj.wakaama_object.instanceList)
|
||||
#define _FREE_INSTANCES(_obj) (_obj.free_instances)
|
||||
|
||||
/**
|
||||
* @brief LwM2M Light Control object instance
|
||||
*/
|
||||
typedef struct lwm2m_obj_light_control_inst {
|
||||
lwm2m_list_t list; /**< list handle */
|
||||
bool status; /**< light status */
|
||||
uint8_t dimmer; /**< dimmer value */
|
||||
ztimer_stopwatch_t stopwatch; /**< stopwatch for on_time */
|
||||
lwm2m_obj_light_control_cb_t cb; /**< application callback */
|
||||
void *cb_arg; /**< callback argument */
|
||||
char color[CONFIG_LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE]; /**< light color */
|
||||
char app_type[CONFIG_LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE]; /**< application type */
|
||||
} lwm2m_obj_light_control_inst_t;
|
||||
|
||||
/**
|
||||
* @brief 'Read' callback for the LwM2M Light Control object implementation.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to read resource from.
|
||||
* @param[in] num_data Number of elements in @p data_array.
|
||||
* @param[in, out] data_array IDs of resources to read. Array of data structures to place values.
|
||||
* @param[in] object Light Control object handle
|
||||
*
|
||||
* @return COAP_205_CONTENT on success
|
||||
* @return COAP_404_NOT_FOUND if the instance was not found
|
||||
* @return COAP_500_INTERNAL_SERVER_ERROR otherwise
|
||||
*/
|
||||
static uint8_t _read_cb(uint16_t instance_id, int *num_data, lwm2m_data_t **data_array,
|
||||
lwm2m_object_t *object);
|
||||
|
||||
/**
|
||||
* @brief 'Write' callback for the LwM2M Light Control object implementation.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to write resource to.
|
||||
* @param[in] num_data Number of elements in @p data_array.
|
||||
* @param[in] data_array IDs of resources to write and values.
|
||||
* @param[in] object Light Control object handle
|
||||
*
|
||||
* @return COAP_204_CHANGED on success
|
||||
* @return COAP_404_NOT_FOUND if the instance was not found
|
||||
* @return COAP_400_BAD_REQUEST if a value is not encoded correctly
|
||||
* @return COAP_500_INTERNAL_SERVER_ERROR otherwise
|
||||
*/
|
||||
static uint8_t _write_cb(uint16_t instance_id, int num_data, lwm2m_data_t * data_array,
|
||||
lwm2m_object_t * object);
|
||||
|
||||
/**
|
||||
* @brief Gets the current value of a given @p instance.
|
||||
*
|
||||
* @param[in, out] data Initialized data structure.
|
||||
* @param[in] instance Pointer to the instance to get the value from.
|
||||
*
|
||||
* @return COAP_205_CONTENT on success
|
||||
* @return COAP_404_NOT_FOUND if the value is not found
|
||||
*/
|
||||
static uint8_t _get_value(lwm2m_data_t *data, lwm2m_obj_light_control_inst_t *instance);
|
||||
|
||||
/**
|
||||
* @brief Mark a resource as changed on the LwM2M engine.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to mark the resource as changed.
|
||||
* @param[in] resource_id ID of the resource to mark as changed.
|
||||
*/
|
||||
static void _mark_resource_changed(uint16_t instance_id, uint16_t resource_id);
|
||||
|
||||
struct lwm2m_light_control_object {
|
||||
lwm2m_object_t wakaama_object; /**< Wakaama internal object */
|
||||
mutex_t lock; /**< mutex for the instances access */
|
||||
lwm2m_obj_light_control_inst_t *free_instances; /**< list of free instances */
|
||||
lwm2m_obj_light_control_inst_t instances[CONFIG_LWM2M_LIGHT_INSTANCES_MAX]; /**< instances */
|
||||
};
|
||||
|
||||
struct lwm2m_light_control_object _light_control_object = {
|
||||
.lock = MUTEX_INIT,
|
||||
.wakaama_object = {
|
||||
.objID = LWM2M_LIGHT_CONTROL_OBJECT_ID,
|
||||
.instanceList = NULL,
|
||||
.readFunc = _read_cb,
|
||||
.writeFunc = _write_cb,
|
||||
.executeFunc = NULL,
|
||||
.createFunc = NULL,
|
||||
.deleteFunc = NULL,
|
||||
.discoverFunc = NULL,
|
||||
.userData = NULL
|
||||
}
|
||||
};
|
||||
|
||||
static uint8_t _get_value(lwm2m_data_t *data, lwm2m_obj_light_control_inst_t *instance)
|
||||
{
|
||||
assert(data);
|
||||
assert(instance);
|
||||
|
||||
switch (data->id) {
|
||||
case LWM2M_LIGHT_CONTROL_ON_OFF_ID:
|
||||
lwm2m_data_encode_bool(instance->status, data);
|
||||
break;
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_DIMMER_ID:
|
||||
lwm2m_data_encode_int(instance->dimmer, data);
|
||||
break;
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_ON_TIME_ID:
|
||||
if (instance->status) {
|
||||
int64_t time = (int64_t) ztimer_stopwatch_measure(&instance->stopwatch);
|
||||
lwm2m_data_encode_int(time, data);
|
||||
}
|
||||
else {
|
||||
lwm2m_data_encode_int(0, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_COLOUR_ID:
|
||||
lwm2m_data_encode_string(instance->color, data);
|
||||
break;
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_APP_TYPE_ID:
|
||||
lwm2m_data_encode_string(instance->app_type, data);
|
||||
break;
|
||||
|
||||
default:
|
||||
return COAP_404_NOT_FOUND;
|
||||
}
|
||||
return COAP_205_CONTENT;
|
||||
}
|
||||
|
||||
static uint8_t _read_cb(uint16_t instance_id, int *num_data, lwm2m_data_t **data_array,
|
||||
lwm2m_object_t *object)
|
||||
{
|
||||
lwm2m_obj_light_control_inst_t *instance;
|
||||
uint8_t result = COAP_404_NOT_FOUND;
|
||||
int i = 0;
|
||||
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
/* try to get the requested instance from the object list */
|
||||
instance = (lwm2m_obj_light_control_inst_t *)lwm2m_list_find(object->instanceList, instance_id);
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control:read]: can't find instance %" PRId16 "\n", instance_id);
|
||||
result = COAP_404_NOT_FOUND;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
/* if the number of resources is not specified, we need to read all resources */
|
||||
if (!*num_data) {
|
||||
DEBUG("[lwm2m:light_control:read]: reading all resources\n");
|
||||
|
||||
uint16_t res_list[] = {
|
||||
LWM2M_LIGHT_CONTROL_ON_OFF_ID,
|
||||
LWM2M_LIGHT_CONTROL_DIMMER_ID,
|
||||
LWM2M_LIGHT_CONTROL_ON_TIME_ID,
|
||||
LWM2M_LIGHT_CONTROL_COLOUR_ID,
|
||||
LWM2M_LIGHT_CONTROL_APP_TYPE_ID
|
||||
};
|
||||
|
||||
/* allocate structures to return resources */
|
||||
int res_num = ARRAY_SIZE(res_list);
|
||||
*data_array = lwm2m_data_new(res_num);
|
||||
|
||||
if (NULL == *data_array) {
|
||||
result = COAP_500_INTERNAL_SERVER_ERROR;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
/* return the number of resources being read */
|
||||
*num_data = res_num;
|
||||
|
||||
/* set the IDs of the resources in the data structures */
|
||||
for (i = 0; i < res_num; i++) {
|
||||
(*data_array)[i].id = res_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* now get the values */
|
||||
i = 0;
|
||||
do {
|
||||
DEBUG("[lwm2m:light_control:read]: reading resource %" PRId16 "\n", (*data_array)[i].id);
|
||||
result = _get_value(&(*data_array)[i], instance);
|
||||
i++;
|
||||
} while (i < *num_data && COAP_205_CONTENT == result);
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint8_t _write_cb(uint16_t instance_id, int num_data, lwm2m_data_t * data_array,
|
||||
lwm2m_object_t * object)
|
||||
{
|
||||
lwm2m_obj_light_control_inst_t *instance;
|
||||
uint8_t result = COAP_204_CHANGED;
|
||||
bool call_cb = false;
|
||||
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
/* try to get the requested instance from the object list */
|
||||
instance = (lwm2m_obj_light_control_inst_t *)lwm2m_list_find(object->instanceList, instance_id);
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control:write]: can't find instance %" PRId16 "\n", instance_id);
|
||||
result = COAP_404_NOT_FOUND;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_data && result == COAP_204_CHANGED; i++) {
|
||||
switch (data_array[i].id) {
|
||||
case LWM2M_LIGHT_CONTROL_ON_OFF_ID: {
|
||||
bool prev_status = instance->status;
|
||||
|
||||
lwm2m_data_decode_bool(&data_array[i], &instance->status);
|
||||
|
||||
/* reset timer on OFF -> ON transitions */
|
||||
if (instance->status && !prev_status) {
|
||||
ztimer_stopwatch_reset(&instance->stopwatch);
|
||||
}
|
||||
|
||||
call_cb = true;
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_ON_OFF_ID);
|
||||
break;
|
||||
}
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_ON_TIME_ID:
|
||||
{
|
||||
int64_t val;
|
||||
lwm2m_data_decode_int(&data_array[i], &val);
|
||||
if (val != 0) {
|
||||
DEBUG("[lwm2m:light_control:write]: invalid on_time value, only can write 0\n");
|
||||
result = COAP_400_BAD_REQUEST;
|
||||
} else {
|
||||
ztimer_stopwatch_reset(&instance->stopwatch);
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_ON_TIME_ID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_DIMMER_ID:
|
||||
{
|
||||
int64_t val;
|
||||
lwm2m_data_decode_int(&data_array[i], &val);
|
||||
if (val < 0 || val > 100) {
|
||||
DEBUG("[lwm2m:light_control:write]: invalid dimmer value\n");
|
||||
result = COAP_400_BAD_REQUEST;
|
||||
} else {
|
||||
instance->dimmer = (uint8_t)val;
|
||||
call_cb = true;
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_DIMMER_ID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_COLOUR_ID:
|
||||
if (data_array[i].type != LWM2M_TYPE_STRING && data_array[i].type != LWM2M_TYPE_OPAQUE) {
|
||||
DEBUG("[lwm2m:light_control:write]: invalid type for color"
|
||||
"(%" PRId8 ")\n", (uint8_t)(data_array[i].type));
|
||||
result = COAP_400_BAD_REQUEST;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_array[i].value.asBuffer.length >
|
||||
CONFIG_LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE - 1) {
|
||||
DEBUG("[lwm2m:light_control:write]: value too big for color\n");
|
||||
result = COAP_500_INTERNAL_SERVER_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(instance->color, data_array[i].value.asBuffer.buffer,
|
||||
data_array[i].value.asBuffer.length);
|
||||
instance->color[data_array[i].value.asBuffer.length] = '\0';
|
||||
call_cb = true;
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_COLOUR_ID);
|
||||
break;
|
||||
|
||||
case LWM2M_LIGHT_CONTROL_APP_TYPE_ID:
|
||||
if (data_array[i].type != LWM2M_TYPE_STRING && data_array[i].type != LWM2M_TYPE_OPAQUE) {
|
||||
DEBUG("[lwm2m:light_control:write]: invalid type for app_type"
|
||||
"(%" PRId8 ")\n", (uint8_t)(data_array[i].type));
|
||||
result = COAP_400_BAD_REQUEST;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_array[i].value.asBuffer.length >
|
||||
CONFIG_LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE - 1) {
|
||||
DEBUG("[lwm2m:light_control:write]: value too big for app_type\n");
|
||||
result = COAP_500_INTERNAL_SERVER_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(instance->app_type, data_array[i].value.asBuffer.buffer,
|
||||
data_array[i].value.asBuffer.length);
|
||||
instance->app_type[data_array[i].value.asBuffer.length] = '\0';
|
||||
call_cb = true;
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_APP_TYPE_ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (call_cb && instance->cb) {
|
||||
instance->cb(object, instance_id, instance->status, instance->dimmer, instance->color,
|
||||
instance->app_type, instance->cb_arg);
|
||||
}
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _mark_resource_changed(uint16_t instance_id, uint16_t resource_id)
|
||||
{
|
||||
lwm2m_uri_t uri;
|
||||
uri.flag = LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID | LWM2M_URI_FLAG_RESOURCE_ID;
|
||||
uri.objectId = LWM2M_LIGHT_CONTROL_OBJECT_ID;
|
||||
uri.instanceId = instance_id;
|
||||
uri.resourceId = resource_id;
|
||||
|
||||
lwm2m_client_data_t *client_data;
|
||||
client_data = (lwm2m_client_data_t *)_light_control_object.wakaama_object.userData;
|
||||
lwm2m_resource_value_changed(client_data->lwm2m_ctx, &uri);
|
||||
}
|
||||
|
||||
|
||||
lwm2m_object_t *lwm2m_object_light_control_init(lwm2m_client_data_t *client_data)
|
||||
{
|
||||
/* initialize the instances */
|
||||
for (unsigned i = 0; i < CONFIG_LWM2M_LIGHT_INSTANCES_MAX; i++) {
|
||||
_light_control_object.instances[i].list.next = NULL;
|
||||
_light_control_object.instances[i].list.id = UINT16_MAX;
|
||||
|
||||
_FREE_INSTANCES(_light_control_object) = (lwm2m_obj_light_control_inst_t *) LWM2M_LIST_ADD(
|
||||
_FREE_INSTANCES(_light_control_object),
|
||||
&(_light_control_object.instances[i])
|
||||
);
|
||||
}
|
||||
|
||||
_light_control_object.wakaama_object.userData = client_data;
|
||||
|
||||
return &(_light_control_object.wakaama_object);
|
||||
}
|
||||
|
||||
int lwm2m_object_light_control_instance_create(const lwm2m_obj_light_control_args_t *args,
|
||||
int32_t instance_id)
|
||||
{
|
||||
assert(args);
|
||||
int result = -ENOMEM;
|
||||
lwm2m_obj_light_control_inst_t *instance = NULL;
|
||||
uint16_t _instance_id;
|
||||
|
||||
/* lock object */
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
/* determine ID for new instance */
|
||||
if (instance_id < 0) {
|
||||
_instance_id = lwm2m_list_newId((lwm2m_list_t *)_USED_INSTANCES(_light_control_object));
|
||||
}
|
||||
else {
|
||||
/* sanity check */
|
||||
if (instance_id >= (UINT16_MAX - 1)) {
|
||||
DEBUG("[lwm2m:light_control]: instance ID %" PRIi32 " is too big\n", instance_id);
|
||||
result = -EINVAL;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
_instance_id = (uint16_t)instance_id;
|
||||
|
||||
/* check that the ID is free to use */
|
||||
if (LWM2M_LIST_FIND(_USED_INSTANCES(_light_control_object), _instance_id ) != NULL)
|
||||
{
|
||||
DEBUG("[lwm2m:light_control]: instance ID %" PRIi32 " already in use\n", instance_id);
|
||||
goto free_out;
|
||||
}
|
||||
}
|
||||
|
||||
/* try to allocate an instance, by popping a free node from the list */
|
||||
_FREE_INSTANCES(_light_control_object) = (lwm2m_obj_light_control_inst_t *) lwm2m_list_remove(
|
||||
(lwm2m_list_t *) _FREE_INSTANCES(_light_control_object),
|
||||
UINT16_MAX,
|
||||
(lwm2m_list_t **) &instance
|
||||
);
|
||||
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control]: can't allocate new instance\n");
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
memset(instance, 0, sizeof(lwm2m_obj_light_control_inst_t));
|
||||
|
||||
instance->list.id = _instance_id;
|
||||
instance->status = false;
|
||||
|
||||
ztimer_stopwatch_init(ZTIMER_SEC, &instance->stopwatch);
|
||||
ztimer_stopwatch_start(&instance->stopwatch);
|
||||
|
||||
/* if callback specified set it */
|
||||
if (args->cb) {
|
||||
instance->cb = args->cb;
|
||||
}
|
||||
|
||||
/* if callback argument specified set it */
|
||||
if (args->cb_arg) {
|
||||
instance->cb_arg = args->cb_arg;
|
||||
}
|
||||
|
||||
/* if color is specified, copy locally */
|
||||
if (args->color) {
|
||||
if (args->color_len > CONFIG_LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE) {
|
||||
DEBUG("[lwm2m:light_control]: not enough space for color string\n");
|
||||
goto free_out;
|
||||
}
|
||||
memcpy(instance->color, args->color, args->color_len);
|
||||
}
|
||||
|
||||
/* if app is specified, copy locally */
|
||||
if (args->app_type) {
|
||||
if (args->app_type_len > CONFIG_LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE) {
|
||||
DEBUG("[lwm2m:light_control]: not enough space for app_type string\n");
|
||||
goto free_out;
|
||||
}
|
||||
memcpy(instance->app_type, args->app_type, args->app_type_len);
|
||||
}
|
||||
|
||||
DEBUG("[lwm2m:light_control]: new instance with ID %" PRIu16 "\n", _instance_id);
|
||||
|
||||
/* add the new instance to the list */
|
||||
_USED_INSTANCES(_light_control_object) = LWM2M_LIST_ADD(
|
||||
_USED_INSTANCES(_light_control_object),
|
||||
instance
|
||||
);
|
||||
|
||||
result = 0;
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int lwm2m_object_light_control_update_dimmer(uint16_t instance_id, uint8_t dimmer, bool call_cb)
|
||||
{
|
||||
int result = -EINVAL;
|
||||
lwm2m_obj_light_control_inst_t *instance;
|
||||
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
if (dimmer > 100) {
|
||||
DEBUG("[lwm2m:light_control]: invalid dimmer value\n");
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
instance = (lwm2m_obj_light_control_inst_t *)LWM2M_LIST_FIND(
|
||||
_USED_INSTANCES(_light_control_object),
|
||||
instance_id
|
||||
);
|
||||
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control]: can't find instance %" PRId16 "\n", instance_id);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
instance->dimmer = dimmer;
|
||||
|
||||
if (call_cb && instance->cb) {
|
||||
instance->cb(&_light_control_object.wakaama_object, instance_id, instance->status,
|
||||
instance->dimmer, instance->color, instance->app_type, instance->cb_arg);
|
||||
}
|
||||
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_DIMMER_ID);
|
||||
|
||||
result = 0;
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int lwm2m_object_light_control_update_status(uint16_t instance_id, bool status, bool call_cb)
|
||||
{
|
||||
int result = -EINVAL;
|
||||
lwm2m_obj_light_control_inst_t *instance;
|
||||
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
instance = (lwm2m_obj_light_control_inst_t *)LWM2M_LIST_FIND(
|
||||
_USED_INSTANCES(_light_control_object),
|
||||
instance_id
|
||||
);
|
||||
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control]: can't find instance %" PRId16 "\n", instance_id);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
if (status && !instance->status) {
|
||||
ztimer_stopwatch_start(&instance->stopwatch);
|
||||
}
|
||||
|
||||
instance->status = status;
|
||||
|
||||
if (call_cb && instance->cb) {
|
||||
instance->cb(&_light_control_object.wakaama_object, instance_id, instance->status,
|
||||
instance->dimmer, instance->color, instance->app_type, instance->cb_arg);
|
||||
}
|
||||
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_ON_OFF_ID);
|
||||
|
||||
result = 0;
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int lwm2m_object_light_control_update_color(uint16_t instance_id, const char *color, size_t len,
|
||||
bool call_cb)
|
||||
{
|
||||
int result = -EINVAL;
|
||||
lwm2m_obj_light_control_inst_t *instance;
|
||||
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
if (len > CONFIG_LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE - 1) {
|
||||
DEBUG("[lwm2m:light_control]: color string too long\n");
|
||||
result = -ENOBUFS;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
instance = (lwm2m_obj_light_control_inst_t *)LWM2M_LIST_FIND(
|
||||
_USED_INSTANCES(_light_control_object),
|
||||
instance_id
|
||||
);
|
||||
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control]: can't find instance %" PRId16 "\n", instance_id);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
memcpy(instance->color, color, len);
|
||||
instance->color[len] = '\0';
|
||||
|
||||
if (call_cb && instance->cb) {
|
||||
instance->cb(&_light_control_object.wakaama_object, instance_id, instance->status,
|
||||
instance->dimmer, instance->color, instance->app_type, instance->cb_arg);
|
||||
}
|
||||
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_COLOUR_ID);
|
||||
|
||||
result = 0;
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int lwm2m_object_light_control_update_app_type(uint16_t instance_id, const char *app_type,
|
||||
size_t len, bool call_cb)
|
||||
{
|
||||
int result = -EINVAL;
|
||||
lwm2m_obj_light_control_inst_t *instance;
|
||||
|
||||
mutex_lock(&_light_control_object.lock);
|
||||
|
||||
if (len > CONFIG_LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE - 1) {
|
||||
DEBUG("[lwm2m:light_control]: app_type string too long\n");
|
||||
result = -ENOBUFS;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
instance = (lwm2m_obj_light_control_inst_t *)LWM2M_LIST_FIND(
|
||||
_USED_INSTANCES(_light_control_object),
|
||||
instance_id
|
||||
);
|
||||
|
||||
if (!instance) {
|
||||
DEBUG("[lwm2m:light_control]: can't find instance %" PRId16 "\n", instance_id);
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
memcpy(instance->app_type, app_type, len);
|
||||
instance->app_type[len] = '\0';
|
||||
|
||||
if (call_cb && instance->cb) {
|
||||
instance->cb(&_light_control_object.wakaama_object, instance_id, instance->status,
|
||||
instance->dimmer, instance->color, instance->app_type, instance->cb_arg);
|
||||
}
|
||||
|
||||
_mark_resource_changed(instance_id, LWM2M_LIGHT_CONTROL_APP_TYPE_ID);
|
||||
|
||||
result = 0;
|
||||
|
||||
free_out:
|
||||
mutex_unlock(&_light_control_object.lock);
|
||||
return result;
|
||||
}
|
302
pkg/wakaama/include/objects/light_control.h
Normal file
302
pkg/wakaama/include/objects/light_control.h
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup lwm2m_objects
|
||||
* @defgroup lwm2m_objects_light_control Light Control
|
||||
* @brief Light Control object implementation for LwM2M client using Wakaama
|
||||
*
|
||||
* @experimental This API is considered experimental and may change in future releases without
|
||||
* deprecation process.
|
||||
*
|
||||
* This implements the LwM2M Light Control object (ID 3311) as specified in the LwM2M registry.
|
||||
*
|
||||
* This Object is used to control a light source, such as a LED or other light. It allows a light to
|
||||
* be turned on or off and dim it.
|
||||
*
|
||||
* To use this object add `USEMODULE += wakaama_objects_light_control` to the application Makefile.
|
||||
*
|
||||
* ## Resources
|
||||
*
|
||||
* For an XML description of the object see
|
||||
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/3311.xml
|
||||
*
|
||||
| Name | ID | Mandatory | Type | Range | Units | Implemented |
|
||||
|-------------------------|:----:|:---------:|:-------:|:-------:|:-----:|:-----------:|
|
||||
| On/Off | 5850 | Yes | Boolean | - | - | Yes[1] |
|
||||
| Dimmer | 5851 | No | Integer | 0 - 100 | /100 | Yes[1] |
|
||||
| On time | 5852 | No | Integer | - | s | Yes |
|
||||
| Cumulative active power | 5805 | No | Float | - | Wh | No |
|
||||
| Power factor | 5820 | No | Float | - | - | No |
|
||||
| Colour | 5706 | No | String | - | - | Yes |
|
||||
| Sensor Units | 5701 | No | String | - | - | No |
|
||||
| Application Type | 5750 | No | String | - | - | Yes |
|
||||
*
|
||||
* [1]: The handling of these resources are implemented, but its actual impact on the light state
|
||||
* depends on the application.
|
||||
* ## Usage
|
||||
*
|
||||
* 1. Initialize the LwM2M client with @ref lwm2m_object_light_control_init, by passing a pointer
|
||||
* to the LwM2M client data.
|
||||
*
|
||||
* 2. Now you can create instances of the Light Control object with
|
||||
* @ref lwm2m_object_light_control_instance_create. As part of the arguments,
|
||||
* you can pass a callback that will be called when the light resources are updated
|
||||
* (i.e. status, dimmer, color, app_type), as well as an user argument.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* #define LIGHT_COLOR "FFFFFF"
|
||||
* #define LIGHT_APP_TYPE "LED 0"
|
||||
*
|
||||
* // ... ///
|
||||
*
|
||||
* void _light_cb(lwm2m_object_t *object, uint16_t instance_id, bool status, uint8_t dimmer,
|
||||
* const char* color, const char* app_type, void *arg)
|
||||
* {
|
||||
* (void)object;
|
||||
* (void)instance_id;
|
||||
* (void)arg;
|
||||
*
|
||||
* printf("%s is now %s, ", app_type, status? "ON":"OFF");
|
||||
* printf("with color %s and intensity %d%%\n", color, dimmer);
|
||||
* }
|
||||
*
|
||||
* // ... ///
|
||||
*
|
||||
* lwm2m_object_t *light_control;
|
||||
* lwm2m_client_data_t client_data;
|
||||
*
|
||||
* lwm2m_client_init(&client_data);
|
||||
* light_control = lwm2m_object_light_control_init(&client_data);
|
||||
*
|
||||
* lwm2m_obj_light_control_args_t args = {
|
||||
* .cb = _light_cb,
|
||||
* .cb_arg = NULL,
|
||||
* .color = LIGHT_COLOR,
|
||||
* .color_len = sizeof(LIGHT_COLOR) - 1,
|
||||
* .app_type = LIGHT_APP_TYPE,
|
||||
* .app_type_len = sizeof(LIGHT_APP_TYPE) - 1
|
||||
* };
|
||||
*
|
||||
* int result = lwm2m_object_light_control_instance_create(&args, 0);
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* 3. You can update the status, dimmer, color and app_type of the light control instance with
|
||||
* @ref lwm2m_object_light_control_update_status, @ref lwm2m_object_light_control_update_dimmer,
|
||||
* @ref lwm2m_object_light_control_update_color and
|
||||
* @ref lwm2m_object_light_control_update_app_type respectively. This will make sure to send
|
||||
* notifications to servers that may be observing these resources.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* lwm2m_object_light_control_update_status(0, true, false);
|
||||
* lwm2m_object_light_control_update_dimmer(0, 50, false);
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef OBJECTS_LIGHT_CONTROL_H
|
||||
#define OBJECTS_LIGHT_CONTROL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "liblwm2m.h"
|
||||
|
||||
/**
|
||||
* @defgroup lwm2m_objects_light_control_config LwM2M Light Control object compile configurations
|
||||
* @ingroup lwm2m_client_config
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Maximum number of instances of the object
|
||||
*/
|
||||
#ifndef CONFIG_LWM2M_LIGHT_INSTANCES_MAX
|
||||
#define CONFIG_LWM2M_LIGHT_INSTANCES_MAX (3U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum size for the color string
|
||||
*/
|
||||
#ifndef CONFIG_LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE
|
||||
#define CONFIG_LWM2M_LIGHT_CONTROL_COLOR_MAX_SIZE (16U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum size for the application type string
|
||||
*/
|
||||
#ifndef CONFIG_LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE
|
||||
#define CONFIG_LWM2M_LIGHT_CONTROL_APP_TYPE_MAX_SIZE (16U)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Light Control object ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_OBJECT_ID 3311
|
||||
|
||||
/**
|
||||
* @name Light Control object resource's IDs.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Light status resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_ON_OFF_ID 5850
|
||||
/**
|
||||
* @brief Dimmer value resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_DIMMER_ID 5851
|
||||
/**
|
||||
* @brief On Time resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_ON_TIME_ID 5852
|
||||
/**
|
||||
* @brief Light active power resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_ACT_PWR_ID 5805
|
||||
/**
|
||||
* @brief Light power factor resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_PWR_FACTOR_ID 5820
|
||||
/**
|
||||
* @brief Light color resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_COLOUR_ID 5706
|
||||
/**
|
||||
* @brief Units of the power sensing resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_UNITS_ID 5701
|
||||
/**
|
||||
* @brief Light application type resource ID.
|
||||
*/
|
||||
#define LWM2M_LIGHT_CONTROL_APP_TYPE_ID 5750
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Signature of the callback called when the light resources are updated.
|
||||
*
|
||||
* @param[in] object Light Control object handle.
|
||||
* @param[in] instance_id ID of the instance where the resource changed.
|
||||
* @param[in] status Light status.
|
||||
* @param[in] dimmer Dimmer value.
|
||||
* @param[in] color Light color NULL-terminated string.
|
||||
* @param[in] app_type Light application type NULL-terminated string.
|
||||
* @param[in] arg Argument registered in
|
||||
* @ref lwm2m_object_light_control_instance_create.
|
||||
*/
|
||||
typedef void (*lwm2m_obj_light_control_cb_t)(lwm2m_object_t *object, uint16_t instance_id,
|
||||
bool status, uint8_t dimmer, const char* color,
|
||||
const char* app_type, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Arguments for the creation of a Light Control object instance.
|
||||
*/
|
||||
typedef struct lwm2m_obj_light_control_args {
|
||||
lwm2m_obj_light_control_cb_t cb; /**< Callback for status and dimmer changes. May be NULL. */
|
||||
void *cb_arg; /**< Argument to call cb with. May be NULL. */
|
||||
const char *color; /**< Array of chars with the light color. May be NULL. */
|
||||
size_t color_len; /**< Length of color */
|
||||
const char *app_type; /**< Array of chars with the light app type. May be NULL. */
|
||||
size_t app_type_len; /**< Length of app_type */
|
||||
} lwm2m_obj_light_control_args_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the Light Control object.
|
||||
*
|
||||
* @param[in] client_data LwM2M client data.
|
||||
*
|
||||
* @return Pointer to the Light Control object on success
|
||||
*/
|
||||
lwm2m_object_t *lwm2m_object_light_control_init(lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Create a new Light Control instance and add it to the @p object list.
|
||||
*
|
||||
* @param[in] args Initialize structure with the parameter for the instance. May
|
||||
* not be NULL.
|
||||
* @param[in] instance_id ID for the new instance. It must be between 0 and
|
||||
* (UINT16_MAX - 1), if -1 the next available ID will be used.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if an invalid @p instance_id is given
|
||||
* @return -ENOMEM if no memory is available to create a new instance
|
||||
*/
|
||||
int lwm2m_object_light_control_instance_create(const lwm2m_obj_light_control_args_t *args,
|
||||
int32_t instance_id);
|
||||
|
||||
/**
|
||||
* @brief Update the status of a light control instance.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to update.
|
||||
* @param[in] status New status of the light.
|
||||
* @param[in] call_cb If true, the callback @ref lwm2m_obj_light_control_args_t::cb will be
|
||||
* called.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if the instance does not exist
|
||||
*/
|
||||
int lwm2m_object_light_control_update_status(uint16_t instance_id, bool status, bool call_cb);
|
||||
|
||||
/**
|
||||
* @brief Update the dimmer value of a light control instance.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to update.
|
||||
* @param[in] dimmer New dimmer value.
|
||||
* @param[in] call_cb If true, the callback @ref lwm2m_obj_light_control_args_t::cb will be
|
||||
* called.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if the instance does not exist
|
||||
*/
|
||||
int lwm2m_object_light_control_update_dimmer(uint16_t instance_id, uint8_t dimmer, bool call_cb);
|
||||
|
||||
/**
|
||||
* @brief Update the color of a light control instance.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to update.
|
||||
* @param[in] color New color of the light.
|
||||
* @param[in] len Length of the color string.
|
||||
* @param[in] call_cb If true, the callback @ref lwm2m_obj_light_control_args_t::cb will be
|
||||
* called.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if the instance does not exist
|
||||
* @return -ENOBUFS if the color string is too long
|
||||
*/
|
||||
int lwm2m_object_light_control_update_color(uint16_t instance_id, const char *color, size_t len,
|
||||
bool call_cb);
|
||||
|
||||
/**
|
||||
* @brief Update the application type of a light control instance.
|
||||
*
|
||||
* @param[in] instance_id ID of the instance to update.
|
||||
* @param[in] app_type New application type of the light.
|
||||
* @param[in] len Length of the app_type string.
|
||||
* @param[in] call_cb If true, the callback @ref lwm2m_obj_light_control_args_t::cb will be
|
||||
* called.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if the instance does not exist
|
||||
* @return -ENOBUFS if the app_type string is too long
|
||||
*/
|
||||
int lwm2m_object_light_control_update_app_type(uint16_t instance_id, const char *app_type,
|
||||
size_t len, bool call_cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OBJECTS_LIGHT_CONTROL_H */
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user