1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20652 from leandrolanzieri/dev/lwm2m/ipso_objects

pkg/wakaama: implement IPSO sensor objects in LwM2M
This commit is contained in:
Leandro Lanzieri 2024-06-07 05:00:41 +00:00 committed by GitHub
commit 7a2b08fa8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 2092 additions and 2 deletions

View File

@ -19,6 +19,8 @@ config LWM2M_DTLS_PORT
endmenu # Remote server
rsource "contrib/objects/Kconfig"
config LWM2M_DEVICE_TTL
int "Lifetime of the device"
default 300
@ -60,6 +62,4 @@ config LWM2M_BOOTSTRAP
help
Say y to support using a bootstrap server to get server information.
rsource "contrib/objects/Kconfig"
endmenu # Wakaama LwM2M

View File

@ -12,6 +12,31 @@ USEMODULE += wakaama_objects
USEMODULE += wakaama_objects_device
USEMODULE += wakaama_objects_security
ifneq (,$(filter wakaama_objects_barometer,$(USEMODULE)))
USEMODULE += wakaama_objects_ipso_sensor_base
endif
ifneq (,$(filter wakaama_objects_current,$(USEMODULE)))
USEMODULE += wakaama_objects_ipso_sensor_base
endif
ifneq (,$(filter wakaama_objects_humidity,$(USEMODULE)))
USEMODULE += wakaama_objects_ipso_sensor_base
endif
ifneq (,$(filter wakaama_objects_illuminance,$(USEMODULE)))
USEMODULE += wakaama_objects_ipso_sensor_base
endif
ifneq (,$(filter wakaama_objects_temperature,$(USEMODULE)))
USEMODULE += wakaama_objects_ipso_sensor_base
endif
ifneq (,$(filter wakaama_objects_voltage,$(USEMODULE)))
USEMODULE += wakaama_objects_ipso_sensor_base
endif
USEMODULE += ztimer
USEMODULE += ztimer_sec
USEPKG += tlsf

View File

@ -5,6 +5,11 @@
# directory for more details.
#
menu "LwM2M objects"
rsource "Kconfig.device"
rsource "Kconfig.security"
rsource "Kconfig.ipso"
rsource "Kconfig.light_control"
endmenu

View File

@ -0,0 +1,62 @@
menu "IPSO sensor objects"
depends on USEMODULE_WAKAAMA_OBJECTS_IPSO_SENSOR_BASE
config LWM2M_IPSO_SENSOR_BASE_UNITS_MAX_SIZE
int "Maximum size of strings representing units"
default 4
menu "IPSO barometer object"
depends on USEMODULE_WAKAAMA_OBJECTS_BAROMETER
config LWM2M_BAROMETER_INSTANCES_MAX
int "Maximum number of barometer object instances"
default 1
endmenu
menu "IPSO current object"
depends on USEMODULE_WAKAAMA_OBJECTS_CURRENT
config LWM2M_CURRENT_INSTANCES_MAX
int "Maximum number of current object instances"
default 1
endmenu
menu "IPSO humidity object"
depends on USEMODULE_WAKAAMA_OBJECTS_HUMIDITY
config LWM2M_HUMIDITY_INSTANCES_MAX
int "Maximum number of humidity object instances"
default 1
endmenu
menu "IPSO illuminance object"
depends on USEMODULE_WAKAAMA_OBJECTS_ILLUMINANCE
config LWM2M_ILLUMINANCE_INSTANCES_MAX
int "Maximum number of illuminance object instances"
default 1
endmenu
menu "IPSO temperature object"
depends on USEMODULE_WAKAAMA_OBJECTS_TEMPERATURE
config LWM2M_TEMPERATURE_INSTANCES_MAX
int "Maximum number of temperature object instances"
default 1
endmenu
menu "IPSO voltage object"
depends on USEMODULE_WAKAAMA_OBJECTS_VOLTAGE
config LWM2M_VOLTAGE_INSTANCES_MAX
int "Maximum number of voltage object instances"
default 1
endmenu
endmenu # "IPSO objects"

View File

@ -0,0 +1,68 @@
/*
* 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_barometer
*
* @file
* @brief Barometer object implementation for LwM2M client using Wakaama
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/barometer.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @brief Barometer object implementation descriptor.
*/
static lwm2m_obj_ipso_sensor_base_t _barometer_object;
/**
* @brief Pool of object instances.
*/
static lwm2m_obj_ipso_sensor_base_inst_t _instances[CONFIG_LWM2M_BAROMETER_INSTANCES_MAX];
lwm2m_object_t *lwm2m_object_barometer_init(lwm2m_client_data_t *client_data)
{
assert(client_data);
int res = lwm2m_object_ipso_sensor_base_init_derived(client_data, &_barometer_object,
LWM2M_BAROMETER_OBJECT_ID,
_instances,
CONFIG_LWM2M_BAROMETER_INSTANCES_MAX);
if (res) {
DEBUG("[lwm2m:barometer]: failed to create object\n");
return NULL;
}
return &_barometer_object.object;
}
int32_t lwm2m_object_barometer_instance_create(const lwm2m_obj_barometer_args_t *args)
{
int32_t result = lwm2m_object_ipso_sensor_base_instance_create(&_barometer_object, args);
if (result) {
DEBUG("[lwm2m:barometer]: failed to create instance\n");
}
return result;
}
void lwm2m_object_barometer_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value)
{
lwm2m_object_ipso_sensor_base_update_value(client_data, &_barometer_object, instance_id, value);
}

View File

@ -0,0 +1,68 @@
/*
* 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_current
*
* @file
* @brief Current sensor object implementation for LwM2M client using Wakaama
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/current.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @brief Current Sensor object implementation descriptor.
*/
static lwm2m_obj_ipso_sensor_base_t _current_object;
/**
* @brief Pool of object instances.
*/
static lwm2m_obj_ipso_sensor_base_inst_t _instances[CONFIG_LWM2M_CURRENT_INSTANCES_MAX];
lwm2m_object_t *lwm2m_object_current_init(lwm2m_client_data_t *client_data)
{
assert(client_data);
int res = lwm2m_object_ipso_sensor_base_init_derived(client_data, &_current_object,
LWM2M_CURRENT_OBJECT_ID,
_instances,
CONFIG_LWM2M_CURRENT_INSTANCES_MAX);
if (res) {
DEBUG("[lwm2m:current]: failed to create object\n");
return NULL;
}
return &_current_object.object;
}
int32_t lwm2m_object_current_instance_create(const lwm2m_obj_current_args_t *args)
{
int32_t result = lwm2m_object_ipso_sensor_base_instance_create(&_current_object, args);
if (result) {
DEBUG("[lwm2m:current]: failed to create instance\n");
}
return result;
}
void lwm2m_object_current_update_value(const lwm2m_client_data_t *client_data, uint16_t instance_id,
int16_t value)
{
lwm2m_object_ipso_sensor_base_update_value(client_data, &_current_object, instance_id, value);
}

View File

@ -0,0 +1,69 @@
/*
* 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_humidity
*
* @file
* @brief Humidity Sensor object implementation for LwM2M client using Wakaama
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "mutex.h"
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/humidity.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 1
#include "debug.h"
/**
* @brief Humidity Sensor object implementation descriptor.
*/
static lwm2m_obj_ipso_sensor_base_t _humidity_object;
/**
* @brief Pool of object instances.
*/
static lwm2m_obj_ipso_sensor_base_inst_t _instances[CONFIG_LWM2M_HUMIDITY_INSTANCES_MAX];
lwm2m_object_t *lwm2m_object_humidity_init(lwm2m_client_data_t *client_data)
{
assert(client_data);
int res = lwm2m_object_ipso_sensor_base_init_derived(client_data, &_humidity_object,
LWM2M_HUMIDITY_OBJECT_ID,
_instances,
CONFIG_LWM2M_HUMIDITY_INSTANCES_MAX);
if (res) {
DEBUG("[lwm2m:humidity]: failed to create object\n");
return NULL;
}
return &_humidity_object.object;
}
int32_t lwm2m_object_humidity_instance_create(const lwm2m_obj_humidity_args_t *args)
{
int32_t result = lwm2m_object_ipso_sensor_base_instance_create(&_humidity_object, args);
if (result) {
DEBUG("[lwm2m:humidity]: failed to create instance\n");
}
return result;
}
void lwm2m_object_humidity_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value)
{
lwm2m_object_ipso_sensor_base_update_value(client_data, &_humidity_object, instance_id, value);
}

View File

@ -0,0 +1,70 @@
/*
* 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_illuminance
*
* @file
* @brief Illuminance Sensor object implementation for LwM2M client using Wakaama
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "mutex.h"
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/illuminance.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @brief Illuminance Sensor object implementation descriptor.
*/
static lwm2m_obj_ipso_sensor_base_t _illuminance_object;
/**
* @brief Pool of object instances.
*/
static lwm2m_obj_ipso_sensor_base_inst_t _instances[CONFIG_LWM2M_ILLUMINANCE_INSTANCES_MAX];
lwm2m_object_t *lwm2m_object_illuminance_init(lwm2m_client_data_t *client_data)
{
assert(client_data);
int res = lwm2m_object_ipso_sensor_base_init_derived(client_data, &_illuminance_object,
LWM2M_ILLUMINANCE_OBJECT_ID,
_instances,
CONFIG_LWM2M_ILLUMINANCE_INSTANCES_MAX);
if (res) {
DEBUG("[lwm2m:illuminance]: failed to create object\n");
return NULL;
}
return &_illuminance_object.object;
}
int32_t lwm2m_object_illuminance_instance_create(const lwm2m_obj_illuminance_args_t *args)
{
int32_t result = lwm2m_object_ipso_sensor_base_instance_create(&_illuminance_object, args);
if (result) {
DEBUG("[lwm2m:illuminance]: failed to create instance\n");
}
return result;
}
void lwm2m_object_illuminance_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value)
{
lwm2m_object_ipso_sensor_base_update_value(client_data, &_illuminance_object, instance_id,
value);
}

View File

@ -0,0 +1,417 @@
/*
* 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_ipso_sensor_base
*
* @file
* @brief Implementation of IPSO sensor base functionalities
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 0
#include "debug.h"
#define _USED_INSTANCES(obj) (obj->object.instanceList)
#define _FREE_INSTANCES(obj) (obj->free_instances)
/**
* @brief 'Read' callback for the LwM2M Illuminance Sensor 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 Illuminance Sensor 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 'Execute' callback for the LwM2M Illuminance Sensor object implementation.
*
* @param[in] instance_id ID of the instance to execute resource from.
* @param[in] resource_id ID of the resource to execute.
* @param[in] buffer Pointer to the buffer containing the payload.
* @param[in] length Length of the payload.
* @param[in] object Illuminance Sensor object handle
*
* @return COAP_204_CHANGED on success
* @return COAP_404_NOT_FOUND if the instance was not found
* @return COAP_405_METHOD_NOT_ALLOWED if the resource is not executable
*/
static uint8_t _exec_cb(uint16_t instance_id, uint16_t resource_id, uint8_t *buffer, int length,
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_ipso_sensor_base_inst_t *instance);
/**
* @brief Mark a resource as changed.
*
* @param[in] object Object to mark the resource from.
* @param[in] instance_id ID of the instance to mark the resource from.
* @param[in] resource_id ID of the resource to mark.
*/
static void _mark_resource_as_changed(const lwm2m_object_t *object, uint16_t instance_id,
uint16_t resource_id);
/**
* @brief Add an instance to the free instance list.
*
* @param[out] object IPSO sensor base object
* @param[in] instance Instance to add to the free list
*/
static void _put_instance_in_free_list(lwm2m_obj_ipso_sensor_base_t *object,
lwm2m_obj_ipso_sensor_base_inst_t *instance);
/**
* @brief Get a free instance from the list.
*
* @param[in] object IPSO sensor base object
*
* @return Instance if available, NULL otherwise
*/
static lwm2m_obj_ipso_sensor_base_inst_t *_get_instance_from_free_list(
lwm2m_obj_ipso_sensor_base_t *object);
static void _put_instance_in_free_list(lwm2m_obj_ipso_sensor_base_t *object,
lwm2m_obj_ipso_sensor_base_inst_t *instance)
{
assert(object);
assert(instance);
instance->list.id = UINT16_MAX;
instance->list.next = NULL;
_FREE_INSTANCES(object) = (lwm2m_obj_ipso_sensor_base_inst_t *)LWM2M_LIST_ADD(
_FREE_INSTANCES(object), instance
);
}
static lwm2m_obj_ipso_sensor_base_inst_t *_get_instance_from_free_list(
lwm2m_obj_ipso_sensor_base_t *object)
{
assert(object);
lwm2m_obj_ipso_sensor_base_inst_t *instance = NULL;
/* try to allocate an instance, by popping a free node from the list */
_FREE_INSTANCES(object) = (lwm2m_obj_ipso_sensor_base_inst_t *)lwm2m_list_remove(
(lwm2m_list_t *)_FREE_INSTANCES(object), UINT16_MAX, (lwm2m_list_t **)&instance
);
return instance;
}
int lwm2m_object_ipso_sensor_base_init_derived(lwm2m_client_data_t *client_data,
lwm2m_obj_ipso_sensor_base_t *object,
uint16_t object_id,
lwm2m_obj_ipso_sensor_base_inst_t *instances,
size_t instance_count)
{
assert(object);
assert(instances);
memset(object, 0, sizeof(lwm2m_obj_ipso_sensor_base_t));
/* initialize the wakaama LwM2M object */
object->object.objID = object_id;
object->object.readFunc = _read_cb;
object->object.executeFunc = _exec_cb;
object->object.userData = client_data;
/* initialize the instances and add them to the free instance list */
for (unsigned i = 0; i < instance_count; i++) {
_put_instance_in_free_list(object, &instances[i]);
}
return 0;
}
static uint8_t _get_value(lwm2m_data_t *data, lwm2m_obj_ipso_sensor_base_inst_t *instance)
{
assert(data);
assert(instance);
int res;
switch (data->id) {
case LWM2M_IPSO_BASE_SENSOR_VALUE_ID:
if (instance->read_cb) {
res = instance->read_cb(instance->read_cb_arg, &instance->sensor_value);
if (res) {
DEBUG("[lwm2m IPSO sensor base:read]: read callback failed\n");
return COAP_500_INTERNAL_SERVER_ERROR;
}
}
lwm2m_data_encode_float(instance->sensor_value, data);
break;
case LWM2M_IPSO_BASE_SENSOR_MIN_MEASURED_VALUE_ID:
lwm2m_data_encode_float(instance->min_sensor_value, data);
break;
case LWM2M_IPSO_BASE_SENSOR_MAX_MEASURED_VALUE_ID:
lwm2m_data_encode_float(instance->max_sensor_value, data);
break;
case LWM2M_IPSO_BASE_SENSOR_MIN_RANGE_VALUE_ID:
lwm2m_data_encode_float(instance->min_range_value, data);
break;
case LWM2M_IPSO_BASE_SENSOR_MAX_RANGE_VALUE_ID:
lwm2m_data_encode_float(instance->max_range_value, data);
break;
case LWM2M_IPSO_BASE_SENSOR_UNITS_ID:
lwm2m_data_encode_string(instance->units, 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_ipso_sensor_base_inst_t *instance;
uint8_t result;
int i = 0;
/* try to get the requested instance from the object list */
instance = (lwm2m_obj_ipso_sensor_base_inst_t *)lwm2m_list_find(object->instanceList,
instance_id);
if (!instance) {
DEBUG("[lwm2m IPSO sensor base:read]: can't find instance %d\n", instance_id);
result = COAP_404_NOT_FOUND;
goto out;
}
/* if the number of resources is not specified, we need to read all resources */
if (!*num_data) {
DEBUG("[lwm2m IPSO sensor base:read]: reading all resources\n");
uint16_t res_list[] = {
LWM2M_IPSO_BASE_SENSOR_VALUE_ID,
LWM2M_IPSO_BASE_SENSOR_MIN_MEASURED_VALUE_ID,
LWM2M_IPSO_BASE_SENSOR_MAX_MEASURED_VALUE_ID,
LWM2M_IPSO_BASE_SENSOR_MIN_RANGE_VALUE_ID,
LWM2M_IPSO_BASE_SENSOR_MAX_RANGE_VALUE_ID,
LWM2M_IPSO_BASE_SENSOR_UNITS_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 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 IPSO sensor base:read]: reading resource %d\n", (*data_array)[i].id);
result = _get_value(&(*data_array)[i], instance);
i++;
} while (i < *num_data && COAP_205_CONTENT == result);
out:
return result;
}
static uint8_t _exec_cb(uint16_t instance_id, uint16_t resource_id, uint8_t *buffer, int length,
lwm2m_object_t *object)
{
(void)buffer;
(void)length;
lwm2m_obj_ipso_sensor_base_inst_t *instance;
uint8_t result;
/* try to get the requested instance from the object list */
instance = (lwm2m_obj_ipso_sensor_base_inst_t *)lwm2m_list_find(object->instanceList,
instance_id);
if (!instance) {
DEBUG("[lwm2m IPSO sensor base:exec]: can't find instance %d\n", instance_id);
result = COAP_404_NOT_FOUND;
goto out;
}
switch (resource_id) {
case LWM2M_IPSO_BASE_SENSOR_RESET_MIN_MAX_MEASURED_VALUES_ID:
instance->min_sensor_value = instance->sensor_value;
instance->max_sensor_value = instance->sensor_value;
result = COAP_204_CHANGED;
break;
default:
result = COAP_405_METHOD_NOT_ALLOWED;
break;
}
out:
return result;
}
int32_t lwm2m_object_ipso_sensor_base_instance_create(lwm2m_obj_ipso_sensor_base_t *object,
const lwm2m_obj_ipso_base_sensor_args_t *args)
{
assert(object);
assert(args);
int32_t result = -ENOMEM;
lwm2m_obj_ipso_sensor_base_inst_t *instance = NULL;
uint16_t _instance_id;
if (object->free_instances == NULL) {
DEBUG("[lwm2m:IPSO sensor base]: object not initialized\n");
result = -EINVAL;
goto out;
}
mutex_lock(&object->mutex);
/* determine ID for new instance */
if (args->instance_id < 0) {
_instance_id = lwm2m_list_newId((lwm2m_list_t *)_USED_INSTANCES(object));
}
else {
/* sanity check */
if (args->instance_id >= (UINT16_MAX - 1)) {
DEBUG("[lwm2m:IPSO sensor base]: instance ID %" PRIi32 " is too big\n",
args->instance_id);
result = -EINVAL;
goto free_out;
}
_instance_id = (uint16_t)args->instance_id;
/* check that the ID is free to use */
if (LWM2M_LIST_FIND(_USED_INSTANCES(object), _instance_id ) != NULL) {
DEBUG("[lwm2m:IPSO sensor base]: instance ID %" PRIi32 " already in use\n",
args->instance_id);
goto free_out;
}
}
/* get a free instance */
instance = _get_instance_from_free_list(object);
if (!instance) {
DEBUG("[lwm2m:IPSO sensor base]: can't allocate new instance\n");
goto free_out;
}
memset(instance, 0, sizeof(lwm2m_obj_ipso_sensor_base_inst_t));
instance->list.id = _instance_id;
instance->sensor_value = 0;
instance->min_sensor_value = 0;
instance->max_sensor_value = 0;
instance->min_range_value = args->min_range_value;
instance->max_range_value = args->max_range_value;
instance->read_cb = args->read_cb;
instance->read_cb_arg = args->read_cb_arg;
/* if units are specified, copy locally */
if (args->units) {
if (args->units_len > CONFIG_LWM2M_IPSO_SENSOR_BASE_UNITS_MAX_SIZE) {
DEBUG("[lwm2m:IPSO sensor base]: not enough space for units string\n");
/* restore instance */
_put_instance_in_free_list(object, instance);
return -ENOBUFS;
}
memcpy(instance->units, args->units, args->units_len);
}
else {
memset(instance->units, 0, CONFIG_LWM2M_IPSO_SENSOR_BASE_UNITS_MAX_SIZE);
}
DEBUG("[lwm2m:IPSO sensor base]: new instance with ID %d\n", _instance_id);
/* add the new instance to the list */
object->object.instanceList = LWM2M_LIST_ADD(object->object.instanceList, instance);
result = instance->list.id;
free_out:
mutex_unlock(&object->mutex);
out:
return result;
}
static void _mark_resource_as_changed(const lwm2m_object_t *object, uint16_t instance_id,
uint16_t resource_id)
{
lwm2m_uri_t uri;
uri.objectId = object->objID;
uri.instanceId = instance_id;
uri.resourceId = resource_id;
uri.flag = LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID | LWM2M_URI_FLAG_RESOURCE_ID;
lwm2m_resource_value_changed(lwm2m_client_get_ctx(object->userData), &uri);
}
void lwm2m_object_ipso_sensor_base_update_value(const lwm2m_client_data_t *client_data,
const lwm2m_obj_ipso_sensor_base_t *object,
uint16_t instance_id, int16_t value)
{
(void)client_data;
lwm2m_obj_ipso_sensor_base_inst_t *instance;
/* try to get the requested instance from the object list */
instance = (lwm2m_obj_ipso_sensor_base_inst_t *)lwm2m_list_find(object->object.instanceList,
instance_id);
if (!instance) {
DEBUG("[lwm2m:IPSO sensor base:update]: can't find instance %" PRIiSIZE "\n", instance_id);
return;
}
instance->sensor_value = value;
_mark_resource_as_changed(&object->object, instance_id, LWM2M_IPSO_BASE_SENSOR_VALUE_ID);
if (value < instance->min_sensor_value) {
instance->min_sensor_value = value;
_mark_resource_as_changed(&object->object, instance_id,
LWM2M_IPSO_BASE_SENSOR_MIN_MEASURED_VALUE_ID);
}
if (value > instance->max_sensor_value) {
instance->max_sensor_value = value;
_mark_resource_as_changed(&object->object, instance_id,
LWM2M_IPSO_BASE_SENSOR_MAX_MEASURED_VALUE_ID);
}
}

View File

@ -0,0 +1,71 @@
/*
* 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_temperature
*
* @file
* @brief Temperature Sensor object implementation for LwM2M client using Wakaama
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "mutex.h"
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/temperature.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @brief Temperature Sensor object implementation descriptor.
*/
static lwm2m_obj_ipso_sensor_base_t _temperature_object;
/**
* @brief Pool of object instances.
*/
static lwm2m_obj_ipso_sensor_base_inst_t _instances[CONFIG_LWM2M_TEMPERATURE_INSTANCES_MAX];
lwm2m_object_t *lwm2m_object_temperature_init(lwm2m_client_data_t *client_data)
{
assert(client_data);
int res = lwm2m_object_ipso_sensor_base_init_derived(client_data, &_temperature_object,
LWM2M_TEMPERATURE_OBJECT_ID,
_instances,
CONFIG_LWM2M_TEMPERATURE_INSTANCES_MAX);
if (res) {
DEBUG("[lwm2m:temperature]: failed to create object\n");
return NULL;
}
return &_temperature_object.object;
}
int32_t lwm2m_object_temperature_instance_create(const lwm2m_obj_temperature_args_t *args)
{
int32_t result = lwm2m_object_ipso_sensor_base_instance_create(&_temperature_object, args);
if (result) {
DEBUG("[lwm2m:temperature]: failed to create instance\n");
}
return result;
}
void lwm2m_object_temperature_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id,
int16_t value)
{
lwm2m_object_ipso_sensor_base_update_value(client_data, &_temperature_object, instance_id,
value);
}

View File

@ -0,0 +1,69 @@
/*
* 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_voltage
*
* @file
* @brief Voltmeter object implementation for LwM2M client using Wakaama
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @}
*/
#include "mutex.h"
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/voltage.h"
#include "objects/ipso_sensor_base.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @brief Voltage Sensor object implementation descriptor.
*/
static lwm2m_obj_ipso_sensor_base_t _voltage_object;
/**
* @brief Pool of object instances.
*/
static lwm2m_obj_ipso_sensor_base_inst_t _instances[CONFIG_LWM2M_VOLTAGE_INSTANCES_MAX];
lwm2m_object_t *lwm2m_object_voltage_init(lwm2m_client_data_t *client_data)
{
assert(client_data);
int res = lwm2m_object_ipso_sensor_base_init_derived(client_data, &_voltage_object,
LWM2M_VOLTAGE_OBJECT_ID,
_instances,
CONFIG_LWM2M_VOLTAGE_INSTANCES_MAX);
if (res) {
DEBUG("[lwm2m:voltage]: failed to create object\n");
return NULL;
}
return &_voltage_object.object;
}
int32_t lwm2m_object_voltage_instance_create(const lwm2m_obj_voltage_args_t *args)
{
int32_t result = lwm2m_object_ipso_sensor_base_instance_create(&_voltage_object, args);
if (result) {
DEBUG("[lwm2m:voltage]: failed to create instance\n");
}
return result;
}
void lwm2m_object_voltage_update_value(const lwm2m_client_data_t *client_data, uint16_t instance_id,
int16_t value)
{
lwm2m_object_ipso_sensor_base_update_value(client_data, &_voltage_object, instance_id, value);
}

View File

@ -0,0 +1,161 @@
/*
* 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
* @defgroup lwm2m_objects_barometer Barometer
* @brief Barometer object implementation for LwM2M client using Wakaama
*
* @experimental
*
* This implements the LwM2M Barometer object (ID 3315) as specified in the LwM2M registry.
* This IPSO object should be used with an air pressure sensor to report a barometer measurement.
* It also provides resources for minimum/maximum measured values and the minimum/maximum range that
* can be measured by the barometer sensor. An example measurement unit is pascals.
*
* The sensor value can be updated by the application using the
* @ref lwm2m_object_barometer_update_value function, or polled when required if a callback is
* registered upon object instantiation via @ref lwm2m_obj_barometer_args_t::read_cb.
*
* To use this object add `USEMODULE += wakaama_objects_barometer` to the application Makefile.
*
* ## Resources
*
* For an XML description of the object see
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/version_history/3315-1_0.xml
*
* This object is based on the @ref lwm2m_objects_ipso_sensor_base, therefore it shares the same
* resources.
*
* ## Usage
*
* 1. Initialize the LwM2M object with an initialized client pointer.
*
* ~~~~~~~~~~~~~~~{.c}
* lwm2m_object_t *obj = lwm2m_object_barometer_init(&client_data);
* ~~~~~~~~~~~~~~~
*
* 2. Create a new instance of the object with a given configuration (@ref lwm2m_obj_barometer_args_t).
* Here, you can decide the way of updating the sensor values: polling or pushing. In this case,
* we register a callback function that is called whenever the sensor value is read.
*
* ~~~~~~~~~~~~~~~{.c}
*
* // callback function to read the sensor value
* int _read_cb(void *arg, int16_t *value)
* {
* (void)arg;
*
* // generate new value
* *value = 100;
*
* return 0;
* }
*
* // initialize an instance of barometer sensor object
* const lwm2m_obj_barometer_args_t barometer_args = {
* .min_range_value = 0.0,
* .max_range_value = 2000.0,
* .units = "hPa",
* .units_len = sizeof("hPa") - 1,
* .instance_id = 0,
* .read_cb = _read_cb,
* .read_cb_arg = NULL
* };
*
* int32_t res = lwm2m_object_barometer_instance_create(&barometer_args);
*
* if (res < 0) {
* puts("Could not create barometer object instance");
* }
* ~~~~~~~~~~~~~~~
*
* 3. You can now update the sensor values using the @ref lwm2m_object_barometer_update_value function.
*
* ~~~~~~~~~~~~~~~{.c}
* uint16_t instance_id = (uint16_t)res;
* lwm2m_object_barometer_update_value(&client_data, instance_id, new_value);
* ~~~~~~~~~~~~~~~
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_BAROMETER_H
#define OBJECTS_BAROMETER_H
#ifdef __cplusplus
extern "C" {
#endif
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
/**
* @defgroup lwm2m_objects_barometer_config LwM2M Barometer object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum number of instances of the object
*/
#ifndef CONFIG_LWM2M_BAROMETER_INSTANCES_MAX
#define CONFIG_LWM2M_BAROMETER_INSTANCES_MAX (1U)
#endif
/** @} */
/**
* @brief LwM2M Barometer object ID
*/
#define LWM2M_BAROMETER_OBJECT_ID 3315
/**
* @brief Arguments for the creation of a Barometer object instance.
*/
typedef lwm2m_obj_ipso_base_sensor_args_t lwm2m_obj_barometer_args_t;
/**
* @brief Initialize the Barometer object handle
*
* @param[in] client_data Pointer to the LwM2M client data.
*
* @return Pointer to the global handle of the Barometer object.
*/
lwm2m_object_t *lwm2m_object_barometer_init(lwm2m_client_data_t *client_data);
/**
* @brief Create a new Barometer instance.
*
* @param[in] args Initialize structure with the parameter for the instance. Must
* not be NULL.
*
* @return > 0 value representing the instance ID if the instance was created successfully.
* @return <0 otherwise
*/
int32_t lwm2m_object_barometer_instance_create(const lwm2m_obj_barometer_args_t *args);
/**
* @brief Update the value of the barometer sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_barometer_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_BAROMETER_H */
/** @} */

View File

@ -0,0 +1,159 @@
/*
* 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
* @defgroup lwm2m_objects_current Current
* @brief Current Sensor object implementation for LwM2M client using Wakaama
*
* @experimental
*
* This implements the LwM2M Current Sensor object (ID 3301) as specified in the LwM2M registry.
*
* The sensor value can be updated by the application using the
* @ref lwm2m_object_current_update_value function, or polled when required if a callback is
* registered upon object instantiation via @ref lwm2m_obj_current_args_t::read_cb.
*
* To use this object add `USEMODULE += wakaama_objects_current` to the application Makefile.
*
* ## Resources
*
* For an XML description of the object see
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/version_history/3317-1_0.xml
*
* This object is based on the @ref lwm2m_objects_ipso_sensor_base, therefore it shares the same
* resources. Note that the optional resources "Current Calibration" (ID 5821) and
* "Application Type" (ID 5750) are not implemented.
*
* ## Usage
*
* 1. Initialize the LwM2M object with an initialized client pointer.
*
* ~~~~~~~~~~~~~~~{.c}
* lwm2m_object_t *obj = lwm2m_object_current_init(&client_data);
* ~~~~~~~~~~~~~~~
*
* 2. Create a new instance of the object with a given configuration (@ref lwm2m_obj_current_args_t).
* Here, you can decide the way of updating the sensor values: polling or pushing. In this case,
* we register a callback function that is called whenever the sensor value is read.
*
* ~~~~~~~~~~~~~~~{.c}
*
* // callback function to read the sensor value
* int _read_cb(void *arg, int16_t *value)
* {
* (void)arg;
*
* // generate new value
* *value = 100;
*
* return 0;
* }
*
* // initialize an instance of current sensor object
* const lwm2m_obj_current_args_t current_args = {
* .min_range_value = 0.0,
* .max_range_value = 2000.0,
* .units = "mA",
* .units_len = sizeof("mA") - 1,
* .instance_id = 0,
* .read_cb = _read_cb,
* .read_cb_arg = NULL
* };
*
* int32_t res = lwm2m_object_current_instance_create(&current_args);
*
* if (res < 0) {
* puts("Could not create current object instance");
* }
* ~~~~~~~~~~~~~~~
*
* 3. You can now update the sensor values using the @ref lwm2m_object_current_update_value function.
*
* ~~~~~~~~~~~~~~~{.c}
* uint16_t instance_id = (uint16_t)res;
* lwm2m_object_current_update_value(&client_data, instance_id, new_value);
* ~~~~~~~~~~~~~~~
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_CURRENT_H
#define OBJECTS_CURRENT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
/**
* @defgroup lwm2m_objects_current_config LwM2M Current Sensor object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum number of instances of the object
*/
#ifndef CONFIG_LWM2M_CURRENT_INSTANCES_MAX
#define CONFIG_LWM2M_CURRENT_INSTANCES_MAX (1U)
#endif
/** @} */
/**
* @brief LwM2M Current Sensor object ID
*/
#define LWM2M_CURRENT_OBJECT_ID 3317
/**
* @brief Arguments for the creation of a Current Sensor object instance.
*/
typedef lwm2m_obj_ipso_base_sensor_args_t lwm2m_obj_current_args_t;
/**
* @brief Initialize the Current Sensor object handle
*
* @param[in] client_data Pointer to the LwM2M client data.
*
* @return Pointer to the global handle of the Current Sensor object.
*/
lwm2m_object_t *lwm2m_object_current_init(lwm2m_client_data_t *client_data);
/**
* @brief Create a new Current Sensor instance.
*
* @param[in] args Initialize structure with the parameter for the instance. Must
* not be NULL.
*
* @return > 0 value representing the instance ID if the instance was created successfully.
* @return <0 otherwise
*/
int32_t lwm2m_object_current_instance_create(const lwm2m_obj_current_args_t *args);
/**
* @brief Update the value of the current sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_current_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_CURRENT_H */
/** @} */

View File

@ -0,0 +1,162 @@
/*
* 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
* @defgroup lwm2m_objects_humidity Humidity
* @brief Humidity Sensor object implementation for LwM2M client using Wakaama
*
* @experimental
*
* This implements the LwM2M Humidity Sensor object (ID 3304) as specified in the LwM2M registry.
* This IPSO object should be used with a humidity sensor to report a humidity measurement.
* It also provides resources for minimum/maximum measured values and the minimum/maximum range that
* can be measured by the humidity sensor. An example measurement unit is relative humidity as a
* percentage.
*
* The sensor value can be updated by the application using the
* @ref lwm2m_object_humidity_update_value function, or polled when required if a callback is
* registered upon object instantiation via @ref lwm2m_obj_humidity_args_t::read_cb.
*
* To use this object add `USEMODULE += wakaama_objects_humidity` to the application Makefile.
*
* ## Resources
*
* For an XML description of the object see
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/version_history/3304-1_0.xml
*
* This object is based on the @ref lwm2m_objects_ipso_sensor_base, therefore it shares the same
* resources.
*
* ## Usage
*
* 1. Initialize the LwM2M object with an initialized client pointer.
*
* ~~~~~~~~~~~~~~~{.c}
* lwm2m_object_t *obj = lwm2m_object_humidity_init(&client_data);
* ~~~~~~~~~~~~~~~
*
* 2. Create a new instance of the object with a given configuration (@ref lwm2m_obj_humidity_args_t).
* Here, you can decide the way of updating the sensor values: polling or pushing. In this case,
* we register a callback function that is called whenever the sensor value is read.
*
* ~~~~~~~~~~~~~~~{.c}
*
* // callback function to read the sensor value
* int _read_cb(void *arg, int16_t *value)
* {
* (void)arg;
*
* // generate new value
* *value = 100;
*
* return 0;
* }
*
* // initialize an instance of humidity sensor object
* const lwm2m_obj_humidity_args_t humidity_args = {
* .min_range_value = 0.0,
* .max_range_value = 100.0,
* .units = "RH",
* .units_len = sizeof("RH") - 1,
* .instance_id = 0,
* .read_cb = _read_cb,
* .read_cb_arg = NULL
* };
*
* int32_t res = lwm2m_object_humidity_instance_create(&humidity_args);
*
* if (res < 0) {
* puts("Could not create humidity object instance");
* }
* ~~~~~~~~~~~~~~~
*
* 3. You can now update the sensor values using the @ref lwm2m_object_humidity_update_value function.
*
* ~~~~~~~~~~~~~~~{.c}
* uint16_t instance_id = (uint16_t)res;
* lwm2m_object_humidity_update_value(&client_data, instance_id, new_value);
* ~~~~~~~~~~~~~~~
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_HUMIDITY_H
#define OBJECTS_HUMIDITY_H
#ifdef __cplusplus
extern "C" {
#endif
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
/**
* @defgroup lwm2m_objects_humidity_config LwM2M Humidity Sensor object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum number of instances of the object
*/
#ifndef CONFIG_LWM2M_HUMIDITY_INSTANCES_MAX
#define CONFIG_LWM2M_HUMIDITY_INSTANCES_MAX (1U)
#endif
/** @} */
/**
* @brief LwM2M Humidity Sensor object ID
*/
#define LWM2M_HUMIDITY_OBJECT_ID 3304
/**
* @brief Arguments for the creation of a Humidity Sensor object instance.
*/
typedef lwm2m_obj_ipso_base_sensor_args_t lwm2m_obj_humidity_args_t;
/**
* @brief Initialize the Humidity Sensor object handle
*
* @param[in] client_data Pointer to the LwM2M client data.
*
* @return Pointer to the global handle of the Humidity Sensor object.
*/
lwm2m_object_t *lwm2m_object_humidity_init(lwm2m_client_data_t *client_data);
/**
* @brief Create a new Humidity Sensor instance.
*
* @param[in] args Initialize structure with the parameter for the instance. Must
* not be NULL.
*
* @return > 0 value representing the instance ID if the instance was created successfully.
* @return <0 otherwise
*/
int32_t lwm2m_object_humidity_instance_create(const lwm2m_obj_humidity_args_t *args);
/**
* @brief Update the value of the humidity sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_humidity_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_HUMIDITY_H */
/** @} */

View File

@ -0,0 +1,158 @@
/*
* 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
* @defgroup lwm2m_objects_illuminance Illuminance
* @brief Illuminance Sensor object implementation for LwM2M client using Wakaama
*
* @experimental
*
* This implements the LwM2M Illuminance Sensor object (ID 3301) as specified in the LwM2M registry.
*
* The sensor value can be updated by the application using the
* @ref lwm2m_object_illuminance_update_value function, or polled when required if a callback is
* registered upon object instantiation via @ref lwm2m_obj_illuminance_args_t::read_cb.
*
* To use this object add `USEMODULE += wakaama_objects_illuminance` to the application Makefile.
*
* ## Resources
*
* For an XML description of the object see
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/version_history/3301-1_0.xml
*
* This object is based on the @ref lwm2m_objects_ipso_sensor_base, therefore it shares the same
* resources.
*
* ## Usage
*
* 1. Initialize the LwM2M object with an initialized client pointer.
*
* ~~~~~~~~~~~~~~~{.c}
* lwm2m_object_t *obj = lwm2m_object_illuminance_init(&client_data);
* ~~~~~~~~~~~~~~~
*
* 2. Create a new instance of the object with a given configuration (@ref lwm2m_obj_illuminance_args_t).
* Here, you can decide the way of updating the sensor values: polling or pushing. In this case,
* we register a callback function that is called whenever the sensor value is read.
*
* ~~~~~~~~~~~~~~~{.c}
*
* // callback function to read the sensor value
* int _read_cb(void *arg, int16_t *value)
* {
* (void)arg;
*
* // generate new value
* *value = 100;
*
* return 0;
* }
*
* // initialize an instance of illuminance sensor object
* const lwm2m_obj_illuminance_args_t illuminance_args = {
* .min_range_value = 0.0,
* .max_range_value = 4000.0,
* .units = "lx",
* .units_len = sizeof("lx") - 1,
* .instance_id = 0,
* .read_cb = _read_cb,
* .read_cb_arg = NULL
* };
*
* int32_t res = lwm2m_object_illuminance_instance_create(&illuminance_args);
*
* if (res < 0) {
* puts("Could not create illuminance object instance");
* }
* ~~~~~~~~~~~~~~~
*
* 3. You can now update the sensor values using the @ref lwm2m_object_illuminance_update_value function.
*
* ~~~~~~~~~~~~~~~{.c}
* uint16_t instance_id = (uint16_t)res;
* lwm2m_object_illuminance_update_value(&client_data, instance_id, new_value);
* ~~~~~~~~~~~~~~~
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_ILLUMINANCE_H
#define OBJECTS_ILLUMINANCE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
/**
* @defgroup lwm2m_objects_illuminance_config LwM2M Illuminance Sensor object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum number of instances of the object
*/
#ifndef CONFIG_LWM2M_ILLUMINANCE_INSTANCES_MAX
#define CONFIG_LWM2M_ILLUMINANCE_INSTANCES_MAX (1U)
#endif
/** @} */
/**
* @brief LwM2M Illuminance Sensor object ID
*/
#define LWM2M_ILLUMINANCE_OBJECT_ID 3301
/**
* @brief Arguments for the creation of a Illuminance Sensor object instance.
*/
typedef lwm2m_obj_ipso_base_sensor_args_t lwm2m_obj_illuminance_args_t;
/**
* @brief Initialize the Illuminance Sensor object handle
*
* @param[in] client_data Pointer to the LwM2M client data.
*
* @return Pointer to the global handle of the Illuminance Sensor object.
*/
lwm2m_object_t *lwm2m_object_illuminance_init(lwm2m_client_data_t *client_data);
/**
* @brief Create a new Illuminance Sensor instance.
*
* @param[in] args Initialize structure with the parameter for the instance. Must
* not be NULL.
*
* @return > 0 value representing the instance ID if the instance was created successfully.
* @return <0 otherwise
*/
int32_t lwm2m_object_illuminance_instance_create(const lwm2m_obj_illuminance_args_t *args);
/**
* @brief Update the value of the illuminance sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_illuminance_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_ILLUMINANCE_H */
/** @} */

View File

@ -0,0 +1,202 @@
/*
* 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
* @defgroup lwm2m_objects_ipso_sensor_base IPSO Sensor base object
* @brief Base IPSO sensor functionality to implement similar IPSO objects
*
* @experimental
*
* This module is **not a complete object**, but provides common functionalities
* shared among different IPSO sensor objects. It should not be used directly,
* from the application, but rather be used as a dependency for other objects.
*
* To use this module add `USEMODULE += wakaama_objects_ipso_sensor_base` to the dependencies
* of your own object module.
*
* ## Resources
* Given that IPSO sensors share a common set of resources, these are implemented by this module.
*
| Name | ID | Mandatory | Type | Range | Units | Implemented |
|:-----------------------------------:|:----:|:---------:|:------:|:-----:|:--------:|:-----------:|
| Sensor Value | 5700 | Yes | Float | - | See 5701 | Yes |
| Min. Measured Value | 5601 | No | Float | - | See 5701 | Yes |
| Max. Measured Value | 5602 | No | Float | - | See 5701 | Yes |
| Min. Range Value | 5603 | No | Float | - | See 5701 | Yes |
| Max. Range Value | 5604 | No | Float | - | See 5701 | Yes |
| Reset Min. and Max. Measured Values | 5605 | No | - | - | - | Yes |
| Sensor Units | 5701 | No | String | - | - | Yes |
*
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_IPSO_SENSOR_BASE_H
#define OBJECTS_IPSO_SENSOR_BASE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mutex.h"
#include "liblwm2m.h"
#include "lwm2m_client.h"
/**
* @defgroup lwm2m_objects_ipso_sensor_base_config LwM2M IPSO Sensor base object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum size for the units resource string
*/
#ifndef CONFIG_LWM2M_IPSO_SENSOR_BASE_UNITS_MAX_SIZE
#define CONFIG_LWM2M_IPSO_SENSOR_BASE_UNITS_MAX_SIZE (4U)
#endif
/** @} */
/**
* @name IPSO sensor base object resource's IDs (shared among many IPSO sensor objects)
* @{
*/
/**
* @brief Sensor value resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_VALUE_ID 5700
/**
* @brief Min. measured value resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_MIN_MEASURED_VALUE_ID 5601
/**
* @brief Max. measured value resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_MAX_MEASURED_VALUE_ID 5602
/**
* @brief Min. range value resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_MIN_RANGE_VALUE_ID 5603
/**
* @brief Max. range value resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_MAX_RANGE_VALUE_ID 5604
/**
* @brief Reset min. and max. measured values resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_RESET_MIN_MAX_MEASURED_VALUES_ID 5605
/**
* @brief Sensor units resource ID.
*/
#define LWM2M_IPSO_BASE_SENSOR_UNITS_ID 5701
/** @} */
/**
* @brief Callback for reading the sensor value.
*
* @param[in] read_cb_arg Data passed for the read callback when the instance was created.
* @param[out] value Pointer to the variable where the value will be stored.
*
* @return 0 on success
* @return <0 otherwise
*/
typedef int lwm2m_obj_ipso_base_sensor_read_cb_t(void *read_cb_arg, int16_t *value);
/**
* @brief Arguments for the creation of an object based on the IPSO Sensor Base
* object instance.
*/
typedef struct lwm2m_obj_ipso_sensor_base_args {
int32_t 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. */
char *units; /**< Null-terminated string of the "Sensor Units" resource. May be NULL. */
size_t units_len; /**< Length of units */
int16_t min_range_value; /**< Minimum value that can be measured by the sensor. */
int16_t max_range_value; /**< Maximum value that can be measured by the sensor. */
void *read_cb_arg; /**< Data to pass to the read callback. May be NULL. */
lwm2m_obj_ipso_base_sensor_read_cb_t *read_cb; /**< Callback to read the sensor value. May be NULL. */
} lwm2m_obj_ipso_base_sensor_args_t;
/**
* @brief LwM2M IPSO sensor base instance
*/
typedef struct lwm2m_obj_ipso_sensor_base_inst {
lwm2m_list_t list; /**< list handle */
int16_t sensor_value; /**< sensor value */
int16_t min_sensor_value; /**< minimum sensor value */
int16_t max_sensor_value; /**< maximum sensor value */
int16_t min_range_value; /**< minimum range value */
int16_t max_range_value; /**< maximum range value */
char units[CONFIG_LWM2M_IPSO_SENSOR_BASE_UNITS_MAX_SIZE]; /**< units */
void *read_cb_arg; /**< Data to pass to the read callback. May be NULL. */
lwm2m_obj_ipso_base_sensor_read_cb_t *read_cb; /**< Callback to read the sensor value. May be NULL. */
} lwm2m_obj_ipso_sensor_base_inst_t;
/**
* @brief LwM2M IPSO sensor base object
*/
typedef struct lwm2m_obj_ipso_sensor_base {
lwm2m_object_t object; /**< LwM2M object base */
lwm2m_obj_ipso_sensor_base_inst_t *free_instances; /**< List of instances */
uint16_t object_id; /**< Object ID */
mutex_t mutex; /**< Mutex for the object */
} lwm2m_obj_ipso_sensor_base_t;
/**
* @brief Create a new object instance based on the IPSO Sensor Base and add it to the
* @p object list.
*
* @param[in, out] object Pointer to the LwM2M IPSO object.
* @param[in] args Initialize structure with the parameter for the instance. May
* not be NULL.
*
* @retval instance ID (>0) on success
* @retval <0 otherwise
*/
int32_t lwm2m_object_ipso_sensor_base_instance_create(lwm2m_obj_ipso_sensor_base_t *object,
const lwm2m_obj_ipso_base_sensor_args_t *args);
/**
* @brief Initialize the a LwM2M object derived from the IPSO Sensor Base object.
*
* @param[in, out] client_data Pointer to the LwM2M client.
* @param[in, out] object Pointer to the LwM2M IPSO object.
* @param[in] object_id Object ID.
* @param[in] instances List of allocated instances.
* @param[in] instance_count Number of allocated instances.
*
* @retval 0 on success
* @retval <0 otherwise
*/
int lwm2m_object_ipso_sensor_base_init_derived(lwm2m_client_data_t *client_data,
lwm2m_obj_ipso_sensor_base_t *object,
uint16_t object_id,
lwm2m_obj_ipso_sensor_base_inst_t *instances,
size_t instance_count);
/**
* @brief Update the value of the illuminance sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] object Pointer to the LwM2M IPSO object.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_ipso_sensor_base_update_value(const lwm2m_client_data_t *client_data,
const lwm2m_obj_ipso_sensor_base_t *object,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_IPSO_SENSOR_BASE_H */
/** @} */

View File

@ -0,0 +1,161 @@
/*
* 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
* @defgroup lwm2m_objects_temperature Temperature
* @brief Temperature Sensor object implementation for LwM2M client using Wakaama
*
* @experimental
*
* This implements the LwM2M Temperature Sensor object (ID 3303) as specified in the LwM2M registry.
* This IPSO object should be used with a temperature sensor to report a temperature measurement.
* It also provides resources for minimum/maximum measured values and the minimum/maximum range that
* can be measured by the temperature sensor. An example measurement unit is degrees Celsius.
*
* The sensor value can be updated by the application using the
* @ref lwm2m_object_temperature_update_value function, or polled when required if a callback is
* registered upon object instantiation via @ref lwm2m_obj_temperature_args_t::read_cb.
*
* To use this object add `USEMODULE += wakaama_objects_temperature` to the application Makefile.
*
* ## Resources
*
* For an XML description of the object see
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/version_history/3303-1_0.xml
*
* This object is based on the @ref lwm2m_objects_ipso_sensor_base, therefore it shares the same
* resources.
*
* ## Usage
*
* 1. Initialize the LwM2M object with an initialized client pointer.
*
* ~~~~~~~~~~~~~~~{.c}
* lwm2m_object_t *obj = lwm2m_object_temperature_init(&client_data);
* ~~~~~~~~~~~~~~~
*
* 2. Create a new instance of the object with a given configuration (@ref lwm2m_obj_temperature_args_t).
* Here, you can decide the way of updating the sensor values: polling or pushing. In this case,
* we register a callback function that is called whenever the sensor value is read.
*
* ~~~~~~~~~~~~~~~{.c}
*
* // callback function to read the sensor value
* int _read_cb(void *arg, int16_t *value)
* {
* (void)arg;
*
* // generate new value
* *value = 100;
*
* return 0;
* }
*
* // initialize an instance of temperature sensor object
* const lwm2m_obj_temperature_args_t temperature_args = {
* .min_range_value = -20.0,
* .max_range_value = 80.0,
* .units = "C",
* .units_len = sizeof("C") - 1,
* .instance_id = 0,
* .read_cb = _read_cb,
* .read_cb_arg = NULL
* };
*
* int32_t res = lwm2m_object_temperature_instance_create(&temperature_args);
*
* if (res < 0) {
* puts("Could not create temperature object instance");
* }
* ~~~~~~~~~~~~~~~
*
* 3. You can now update the sensor values using the @ref lwm2m_object_temperature_update_value function.
*
* ~~~~~~~~~~~~~~~{.c}
* uint16_t instance_id = (uint16_t)res;
* lwm2m_object_temperature_update_value(&client_data, instance_id, new_value);
* ~~~~~~~~~~~~~~~
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_TEMPERATURE_H
#define OBJECTS_TEMPERATURE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
/**
* @defgroup lwm2m_objects_temperature_config LwM2M Temperature Sensor object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum number of instances of the object
*/
#ifndef CONFIG_LWM2M_TEMPERATURE_INSTANCES_MAX
#define CONFIG_LWM2M_TEMPERATURE_INSTANCES_MAX (1U)
#endif
/** @} */
/**
* @brief LwM2M Temperature Sensor object ID
*/
#define LWM2M_TEMPERATURE_OBJECT_ID 3303
/**
* @brief Arguments for the creation of a Temperature Sensor object instance.
*/
typedef lwm2m_obj_ipso_base_sensor_args_t lwm2m_obj_temperature_args_t;
/**
* @brief Initialize the Temperature Sensor object handle
*
* @param[in] client_data Pointer to the LwM2M client data.
*
* @return Pointer to the global handle of the Temperature Sensor object.
*/
lwm2m_object_t *lwm2m_object_temperature_init(lwm2m_client_data_t *client_data);
/**
* @brief Create a new Temperature Sensor instance.
*
* @param[in] args Initialize structure with the parameter for the instance. Must
* not be NULL.
*
* @return > 0 value representing the instance ID if the instance was created successfully.
* @return <0 otherwise
*/
int32_t lwm2m_object_temperature_instance_create(const lwm2m_obj_temperature_args_t *args);
/**
* @brief Update the value of the temperature sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_temperature_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_TEMPERATURE_H */
/** @} */

View File

@ -0,0 +1,163 @@
/*
* 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
* @defgroup lwm2m_objects_voltage Voltage
* @brief Voltmeter object implementation for LwM2M client using Wakaama
*
* @experimental
*
* This implements the LwM2M Voltage Sensor object (ID 3316) as specified in the LwM2M registry.
* This IPSO object should be used with voltmeter sensor to report measured voltage between two
* points. It also provides resources for minimum and maximum measured values, as well as the
* minimum and maximum range that can be measured by the sensor. An example measurement unit is
* volts.
*
* The sensor value can be updated by the application using the
* @ref lwm2m_object_voltage_update_value function, or polled when required if a callback is
* registered upon object instantiation via @ref lwm2m_obj_voltage_args_t::read_cb.
*
* To use this object add `USEMODULE += wakaama_objects_voltage` to the application Makefile.
*
* ## Resources
*
* For an XML description of the object see
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/version_history/3316-1_0.xml
*
* This object is based on the @ref lwm2m_objects_ipso_sensor_base, therefore it shares the same
* resources. Note that the optional resources "Current Calibration" (ID 5821) and
* "Application Type" (ID 5750) are not implemented.
*
* ## Usage
*
* 1. Initialize the LwM2M object with an initialized client pointer.
*
* ~~~~~~~~~~~~~~~{.c}
* lwm2m_object_t *obj = lwm2m_object_voltage_init(&client_data);
* ~~~~~~~~~~~~~~~
*
* 2. Create a new instance of the object with a given configuration (@ref lwm2m_obj_voltage_args_t).
* Here, you can decide the way of updating the sensor values: polling or pushing. In this case,
* we register a callback function that is called whenever the sensor value is read.
*
* ~~~~~~~~~~~~~~~{.c}
*
* // callback function to read the sensor value
* int _read_cb(void *arg, int16_t *value)
* {
* (void)arg;
*
* // generate new value
* *value = 100;
*
* return 0;
* }
*
* // initialize an instance of voltage sensor object
* const lwm2m_obj_voltage_args_t voltage_args = {
* .min_range_value = -50.0,
* .max_range_value = 200.0,
* .units = "V",
* .units_len = sizeof("V") - 1,
* .instance_id = 0,
* .read_cb = _read_cb,
* .read_cb_arg = NULL
* };
*
* int32_t res = lwm2m_object_voltage_instance_create(&voltage_args);
*
* if (res < 0) {
* puts("Could not create voltage object instance");
* }
* ~~~~~~~~~~~~~~~
*
* 3. You can now update the sensor values using the @ref lwm2m_object_voltage_update_value function.
*
* ~~~~~~~~~~~~~~~{.c}
* uint16_t instance_id = (uint16_t)res;
* lwm2m_object_voltage_update_value(&client_data, instance_id, new_value);
* ~~~~~~~~~~~~~~~
* @{
*
* @file
*
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
*/
#ifndef OBJECTS_VOLTAGE_H
#define OBJECTS_VOLTAGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "liblwm2m.h"
#include "lwm2m_client.h"
#include "objects/ipso_sensor_base.h"
/**
* @defgroup lwm2m_objects_voltage_config LwM2M Voltage Sensor object compile configurations
* @ingroup lwm2m_client_config
* @{
*/
/**
* @brief Maximum number of instances of the object
*/
#ifndef CONFIG_LWM2M_VOLTAGE_INSTANCES_MAX
#define CONFIG_LWM2M_VOLTAGE_INSTANCES_MAX (1U)
#endif
/** @} */
/**
* @brief LwM2M Voltage Sensor object ID
*/
#define LWM2M_VOLTAGE_OBJECT_ID 3316
/**
* @brief Arguments for the creation of a Voltage Sensor object instance.
*/
typedef lwm2m_obj_ipso_base_sensor_args_t lwm2m_obj_voltage_args_t;
/**
* @brief Initialize the Voltage Sensor object handle
*
* @param[in] client_data Pointer to the LwM2M client data.
*
* @return Pointer to the global handle of the Voltage Sensor object.
*/
lwm2m_object_t *lwm2m_object_voltage_init(lwm2m_client_data_t *client_data);
/**
* @brief Create a new Voltage Sensor instance.
*
* @param[in] args Initialize structure with the parameter for the instance. May
* not be NULL.
*
* @return > 0 value representing the instance ID if the instance was created successfully.
* @return <0 otherwise
*/
int32_t lwm2m_object_voltage_instance_create(const lwm2m_obj_voltage_args_t *args);
/**
* @brief Update the value of the voltage sensor and trigger a notification
* to the observing servers, if any.
*
* @param[in] client_data Pointer to the LwM2M client.
* @param[in] instance_id ID of the instance to update.
* @param[in] value New value for the sensor.
*/
void lwm2m_object_voltage_update_value(const lwm2m_client_data_t *client_data,
uint16_t instance_id, int16_t value);
#ifdef __cplusplus
}
#endif
#endif /* OBJECTS_VOLTAGE_H */
/** @} */