net: lwm2m: rework resource instance storage / access methods
LwM2M allows for multiple instance resources such the power source resources in the device object. These types of resources have always been very hard to work with, and frankly were poorly implemented. This led to other issues where it was very hard to have non-sequential resource instances, and each resource of this type needed special getter / setter methods such as: lwm2m_device_add_pwrsrc() lwm2m_device_set_pwrsrc_voltage_mv() Going forward, as more LwM2M objects are implemented this just doesn't scale well. To fix this: - split the resource instance data out from the resource data. This includes the data pointer information and resource instance id. - add resource id and resource instance id to the event callback functions so user's can see in more detail what resources and resource instances are being handled. - allow generic functions like lwm2m_engine_get_*() and lwm2m_engine_set_*() to access resource instance data. - adjust object resource initialization macros to map resource instances to resources at the time of object instance creation. - fix up the lwm2m_client as a reflection of all of these changes. Signed-off-by: Michael Scott <mike@foundries.io>
This commit is contained in:
parent
6a2f362357
commit
8817d930a8
16 changed files with 861 additions and 419 deletions
|
@ -117,11 +117,15 @@ struct lwm2m_ctx {
|
|||
* lwm2m_engine_register_pre_write_callback()
|
||||
*
|
||||
* @param[in] obj_inst_id Object instance ID generating the callback.
|
||||
* @param[in] res_id Resource ID generating the callback.
|
||||
* @param[in] res_inst_id Resource instance ID generating the callback
|
||||
* (typically 0 for non-multi instance resources).
|
||||
* @param[out] data_len Length of the data buffer.
|
||||
*
|
||||
* @return Callback returns a pointer to the data buffer or NULL for failure.
|
||||
*/
|
||||
typedef void *(*lwm2m_engine_get_data_cb_t)(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
size_t *data_len);
|
||||
|
||||
/**
|
||||
|
@ -135,6 +139,9 @@ typedef void *(*lwm2m_engine_get_data_cb_t)(u16_t obj_inst_id,
|
|||
* lwm2m_engine_register_post_write_callback()
|
||||
*
|
||||
* @param[in] obj_inst_id Object instance ID generating the callback.
|
||||
* @param[in] res_id Resource ID generating the callback.
|
||||
* @param[in] res_inst_id Resource instance ID generating the callback
|
||||
* (typically 0 for non-multi instance resources).
|
||||
* @param[in] data Pointer to data.
|
||||
* @param[in] data_len Length of the data.
|
||||
* @param[in] last_block Flag used during block transfer to indicate the last
|
||||
|
@ -147,6 +154,7 @@ typedef void *(*lwm2m_engine_get_data_cb_t)(u16_t obj_inst_id,
|
|||
* reason of failure or 0 for success.
|
||||
*/
|
||||
typedef int (*lwm2m_engine_set_data_cb_t)(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size);
|
||||
|
||||
|
@ -221,7 +229,7 @@ typedef int (*lwm2m_engine_user_cb_t)(u16_t obj_inst_id);
|
|||
* @return The newly added index of the power source. The index is used
|
||||
* for removing the power source, setting voltage or setting current.
|
||||
*/
|
||||
int lwm2m_device_add_pwrsrc(u8_t pwr_src_type); /* returns index */
|
||||
__deprecated int lwm2m_device_add_pwrsrc(u8_t pwr_src_type);
|
||||
|
||||
/**
|
||||
* @brief Remove power source previously registered in the LwM2M Device object.
|
||||
|
@ -231,7 +239,7 @@ int lwm2m_device_add_pwrsrc(u8_t pwr_src_type); /* returns index */
|
|||
*
|
||||
* @return 0 for success or negative in case of error.
|
||||
*/
|
||||
int lwm2m_device_remove_pwrsrc(int index);
|
||||
__deprecated int lwm2m_device_remove_pwrsrc(int index);
|
||||
|
||||
/**
|
||||
* @brief Set power source voltage (in millivolts).
|
||||
|
@ -242,7 +250,7 @@ int lwm2m_device_remove_pwrsrc(int index);
|
|||
*
|
||||
* @return 0 for success or negative in case of error.
|
||||
*/
|
||||
int lwm2m_device_set_pwrsrc_voltage_mv(int index, int voltage_mv);
|
||||
__deprecated int lwm2m_device_set_pwrsrc_voltage_mv(int index, int voltage_mv);
|
||||
|
||||
/**
|
||||
* @brief Set power source current (in milliamps).
|
||||
|
@ -253,7 +261,7 @@ int lwm2m_device_set_pwrsrc_voltage_mv(int index, int voltage_mv);
|
|||
*
|
||||
* @return 0 for success or negative in case of error.
|
||||
*/
|
||||
int lwm2m_device_set_pwrsrc_current_ma(int index, int current_ma);
|
||||
__deprecated int lwm2m_device_set_pwrsrc_current_ma(int index, int current_ma);
|
||||
|
||||
/**
|
||||
* @brief Register a new error code with LwM2M Device object.
|
||||
|
@ -772,6 +780,30 @@ int lwm2m_engine_set_res_data(char *pathstr, void *data_ptr, u16_t data_len,
|
|||
int lwm2m_engine_get_res_data(char *pathstr, void **data_ptr, u16_t *data_len,
|
||||
u8_t *data_flags);
|
||||
|
||||
/**
|
||||
* @brief Create a resource instance
|
||||
*
|
||||
* LwM2M clients use this function to create multi-resource instances:
|
||||
* Example to create 0 instance of device available power sources:
|
||||
* lwm2m_engine_create_res_inst("3/0/6/0");
|
||||
*
|
||||
* @param[in] pathstr LwM2M path string "obj/obj-inst/res/res-inst"
|
||||
*
|
||||
* @return 0 for success or negative in case of error.
|
||||
*/
|
||||
int lwm2m_engine_create_res_inst(char *pathstr);
|
||||
|
||||
/**
|
||||
* @brief Delete a resource instance
|
||||
*
|
||||
* Use this function to remove an existing resource instance
|
||||
*
|
||||
* @param[in] pathstr LwM2M path string "obj/obj-inst/res/res-inst"
|
||||
*
|
||||
* @return 0 for success or negative in case of error.
|
||||
*/
|
||||
int lwm2m_engine_delete_res_inst(char *pathstr);
|
||||
|
||||
/**
|
||||
* @brief Start the LwM2M engine
|
||||
*
|
||||
|
|
|
@ -63,12 +63,16 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
#define LED_GPIO_PORT DT_ALIAS_LED0_GPIOS_CONTROLLER
|
||||
#define LED_GPIO_PIN DT_ALIAS_LED0_GPIOS_PIN
|
||||
|
||||
static int pwrsrc_bat;
|
||||
static int pwrsrc_usb;
|
||||
static int battery_voltage = 3800;
|
||||
static int battery_current = 125;
|
||||
static int usb_voltage = 5000;
|
||||
static int usb_current = 900;
|
||||
static u8_t bat_idx = LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT;
|
||||
static int bat_mv = 3800;
|
||||
static int bat_ma = 125;
|
||||
static u8_t usb_idx = LWM2M_DEVICE_PWR_SRC_TYPE_USB;
|
||||
static int usb_mv = 5000;
|
||||
static int usb_ma = 900;
|
||||
static u8_t bat_level = 95;
|
||||
static u8_t bat_status = LWM2M_DEVICE_BATTERY_STATUS_CHARGING;
|
||||
static int mem_free = 15;
|
||||
static int mem_total = 25;
|
||||
|
||||
static struct device *led_dev;
|
||||
static u32_t led_state;
|
||||
|
@ -94,7 +98,8 @@ static u8_t firmware_buf[64];
|
|||
#endif
|
||||
|
||||
/* TODO: Move to a pre write hook that can handle ret codes once available */
|
||||
static int led_on_off_cb(u16_t obj_inst_id, u8_t *data, u16_t data_len,
|
||||
static int led_on_off_cb(u16_t obj_inst_id, u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -150,7 +155,7 @@ static int device_reboot_cb(u16_t obj_inst_id)
|
|||
/* Add an error for testing */
|
||||
lwm2m_device_add_err(LWM2M_DEVICE_ERROR_LOW_POWER);
|
||||
/* Change the battery voltage for testing */
|
||||
lwm2m_device_set_pwrsrc_voltage_mv(pwrsrc_bat, --battery_voltage);
|
||||
lwm2m_engine_set_s32("3/0/7/0", (bat_mv - 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -161,7 +166,7 @@ static int device_factory_default_cb(u16_t obj_inst_id)
|
|||
/* Add an error for testing */
|
||||
lwm2m_device_add_err(LWM2M_DEVICE_ERROR_GPS_FAILURE);
|
||||
/* Change the USB current for testing */
|
||||
lwm2m_device_set_pwrsrc_current_ma(pwrsrc_usb, --usb_current);
|
||||
lwm2m_engine_set_s32("3/0/8/1", (usb_ma - 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -183,7 +188,8 @@ static int firmware_update_cb(u16_t obj_inst_id)
|
|||
#endif
|
||||
|
||||
|
||||
static void *temperature_get_buf(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *temperature_get_buf(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id, size_t *data_len)
|
||||
{
|
||||
/* Last read temperature value, will use 25.5C if no sensor available */
|
||||
static struct float32_value v = { 25, 500000 };
|
||||
|
@ -211,13 +217,15 @@ static void *temperature_get_buf(u16_t obj_inst_id, size_t *data_len)
|
|||
|
||||
|
||||
#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT)
|
||||
static void *firmware_get_buf(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *firmware_get_buf(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id, size_t *data_len)
|
||||
{
|
||||
*data_len = sizeof(firmware_buf);
|
||||
return firmware_buf;
|
||||
}
|
||||
|
||||
static int firmware_block_received_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -228,6 +236,7 @@ static int firmware_block_received_cb(u16_t obj_inst_id,
|
|||
#endif
|
||||
|
||||
static int timer_digital_state_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -291,34 +300,30 @@ static int lwm2m_setup(void)
|
|||
LWM2M_RES_DATA_FLAG_RO);
|
||||
lwm2m_engine_register_exec_callback("3/0/4", device_reboot_cb);
|
||||
lwm2m_engine_register_exec_callback("3/0/5", device_factory_default_cb);
|
||||
lwm2m_engine_set_u8("3/0/9", 95); /* battery level */
|
||||
lwm2m_engine_set_u32("3/0/10", 15); /* mem free */
|
||||
lwm2m_engine_set_res_data("3/0/9", &bat_level, sizeof(bat_level), 0);
|
||||
lwm2m_engine_set_res_data("3/0/10", &mem_free, sizeof(mem_free), 0);
|
||||
lwm2m_engine_set_res_data("3/0/17", CLIENT_DEVICE_TYPE,
|
||||
sizeof(CLIENT_DEVICE_TYPE),
|
||||
LWM2M_RES_DATA_FLAG_RO);
|
||||
lwm2m_engine_set_res_data("3/0/18", CLIENT_HW_VER,
|
||||
sizeof(CLIENT_HW_VER),
|
||||
LWM2M_RES_DATA_FLAG_RO);
|
||||
lwm2m_engine_set_u8("3/0/20", LWM2M_DEVICE_BATTERY_STATUS_CHARGING);
|
||||
lwm2m_engine_set_u32("3/0/21", 25); /* mem total */
|
||||
lwm2m_engine_set_res_data("3/0/20", &bat_status, sizeof(bat_status), 0);
|
||||
lwm2m_engine_set_res_data("3/0/21", &mem_total, sizeof(mem_total), 0);
|
||||
|
||||
pwrsrc_bat = lwm2m_device_add_pwrsrc(LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT);
|
||||
if (pwrsrc_bat < 0) {
|
||||
LOG_ERR("LWM2M battery power source enable error (err:%d)",
|
||||
pwrsrc_bat);
|
||||
return pwrsrc_bat;
|
||||
}
|
||||
lwm2m_device_set_pwrsrc_voltage_mv(pwrsrc_bat, battery_voltage);
|
||||
lwm2m_device_set_pwrsrc_current_ma(pwrsrc_bat, battery_current);
|
||||
|
||||
pwrsrc_usb = lwm2m_device_add_pwrsrc(LWM2M_DEVICE_PWR_SRC_TYPE_USB);
|
||||
if (pwrsrc_usb < 0) {
|
||||
LOG_ERR("LWM2M usb power source enable error (err:%d)",
|
||||
pwrsrc_usb);
|
||||
return pwrsrc_usb;
|
||||
}
|
||||
lwm2m_device_set_pwrsrc_voltage_mv(pwrsrc_usb, usb_voltage);
|
||||
lwm2m_device_set_pwrsrc_current_ma(pwrsrc_usb, usb_current);
|
||||
/* add power source resource instances */
|
||||
lwm2m_engine_create_res_inst("3/0/6/0");
|
||||
lwm2m_engine_set_res_data("3/0/6/0", &bat_idx, sizeof(bat_idx), 0);
|
||||
lwm2m_engine_create_res_inst("3/0/7/0");
|
||||
lwm2m_engine_set_res_data("3/0/7/0", &bat_mv, sizeof(bat_mv), 0);
|
||||
lwm2m_engine_create_res_inst("3/0/8/0");
|
||||
lwm2m_engine_set_res_data("3/0/8/0", &bat_ma, sizeof(bat_ma), 0);
|
||||
lwm2m_engine_create_res_inst("3/0/6/1");
|
||||
lwm2m_engine_set_res_data("3/0/6/1", &usb_idx, sizeof(usb_idx), 0);
|
||||
lwm2m_engine_create_res_inst("3/0/7/1");
|
||||
lwm2m_engine_set_res_data("3/0/7/1", &usb_mv, sizeof(usb_mv), 0);
|
||||
lwm2m_engine_create_res_inst("3/0/8/1");
|
||||
lwm2m_engine_set_res_data("3/0/8/1", &usb_ma, sizeof(usb_ma), 0);
|
||||
|
||||
/* setup FIRMWARE object */
|
||||
|
||||
|
|
|
@ -40,6 +40,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
#define LIGHT_STRING_SHORT 8
|
||||
#define LIGHT_STRING_LONG 64
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with LIGHT_MAX_ID
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (LIGHT_MAX_ID)
|
||||
|
||||
/* resource state variables */
|
||||
static bool on_off_value[MAX_INSTANCE_COUNT];
|
||||
static u8_t dimmer_value[MAX_INSTANCE_COUNT];
|
||||
|
@ -63,9 +69,12 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
|
||||
static struct lwm2m_engine_res_inst res[MAX_INSTANCE_COUNT][LIGHT_MAX_ID];
|
||||
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][LIGHT_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst
|
||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
static void *on_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *on_time_read_cb(u16_t obj_inst_id, u16_t res_id, u16_t res_inst_id,
|
||||
size_t *data_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -87,6 +96,7 @@ static void *on_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
|||
}
|
||||
|
||||
static int on_time_post_write_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -117,7 +127,7 @@ static int on_time_post_write_cb(u16_t obj_inst_id,
|
|||
|
||||
static struct lwm2m_engine_obj_inst *light_control_create(u16_t obj_inst_id)
|
||||
{
|
||||
int index, avail = -1, i = 0;
|
||||
int index, avail = -1, i = 0, j = 0;
|
||||
|
||||
/* Check that there is no other instance with this ID */
|
||||
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
|
||||
|
@ -151,24 +161,33 @@ static struct lwm2m_engine_obj_inst *light_control_create(u16_t obj_inst_id)
|
|||
colour[avail][0] = '\0';
|
||||
units[avail][0] = '\0';
|
||||
|
||||
init_res_instance(res_inst[avail], ARRAY_SIZE(res_inst[avail]));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES_DATA(res[avail], i, LIGHT_ON_OFF_ID,
|
||||
INIT_OBJ_RES_DATA(LIGHT_ON_OFF_ID, res[avail], i, res_inst[avail], j,
|
||||
&on_off_value[avail], sizeof(*on_off_value));
|
||||
INIT_OBJ_RES_DATA(res[avail], i, LIGHT_DIMMER_ID,
|
||||
INIT_OBJ_RES_DATA(LIGHT_DIMMER_ID, res[avail], i, res_inst[avail], j,
|
||||
&dimmer_value[avail], sizeof(*dimmer_value));
|
||||
INIT_OBJ_RES(res[avail], i, LIGHT_ON_TIME_ID, 0, &on_time_value[avail],
|
||||
sizeof(*on_time_value), on_time_read_cb,
|
||||
NULL, on_time_post_write_cb, NULL);
|
||||
INIT_OBJ_RES_DATA(res[avail], i, LIGHT_CUMULATIVE_ACTIVE_POWER_ID,
|
||||
INIT_OBJ_RES(LIGHT_ON_TIME_ID, res[avail], i,
|
||||
res_inst[avail], j, 1, true,
|
||||
&on_time_value[avail], sizeof(*on_time_value),
|
||||
on_time_read_cb, NULL, on_time_post_write_cb, NULL);
|
||||
INIT_OBJ_RES_DATA(LIGHT_CUMULATIVE_ACTIVE_POWER_ID, res[avail], i,
|
||||
res_inst[avail], j,
|
||||
&cumulative_active_value[avail],
|
||||
sizeof(*cumulative_active_value));
|
||||
INIT_OBJ_RES_DATA(res[avail], i, LIGHT_POWER_FACTOR_ID,
|
||||
&power_factor_value[avail], sizeof(*power_factor_value));
|
||||
INIT_OBJ_RES_DATA(res[avail], i, LIGHT_COLOUR_ID,
|
||||
INIT_OBJ_RES_DATA(LIGHT_POWER_FACTOR_ID, res[avail], i,
|
||||
res_inst[avail], j,
|
||||
&power_factor_value[avail],
|
||||
sizeof(*power_factor_value));
|
||||
INIT_OBJ_RES_DATA(LIGHT_COLOUR_ID, res[avail], i,
|
||||
res_inst[avail], j,
|
||||
colour[avail], LIGHT_STRING_LONG);
|
||||
INIT_OBJ_RES_DATA(res[avail], i, LIGHT_SENSOR_UNITS_ID,
|
||||
INIT_OBJ_RES_DATA(LIGHT_SENSOR_UNITS_ID, res[avail], i,
|
||||
res_inst[avail], j,
|
||||
units[avail], LIGHT_STRING_SHORT);
|
||||
INIT_OBJ_RES_DUMMY(res[avail], i, LIGHT_APPLICATION_TYPE_ID);
|
||||
INIT_OBJ_RES_OPTDATA(LIGHT_APPLICATION_TYPE_ID, res[avail], i,
|
||||
res_inst[avail], j);
|
||||
|
||||
inst[avail].resources = res[avail];
|
||||
inst[avail].resource_count = i;
|
||||
|
@ -182,7 +201,7 @@ static int ipso_light_control_init(struct device *dev)
|
|||
{
|
||||
/* Set default values */
|
||||
(void)memset(inst, 0, sizeof(*inst) * MAX_INSTANCE_COUNT);
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res_inst) *
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res) *
|
||||
MAX_INSTANCE_COUNT * LIGHT_MAX_ID);
|
||||
|
||||
light_control.obj_id = IPSO_OBJECT_LIGHT_CONTROL_ID;
|
||||
|
|
|
@ -38,6 +38,13 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
|
||||
#define TEMP_STRING_SHORT 8
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with TEMP_MAX_ID
|
||||
* subtract EXEC resources (1)
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (TEMP_MAX_ID - 1)
|
||||
|
||||
/* resource state variables */
|
||||
static float32_value_t sensor_value[MAX_INSTANCE_COUNT];
|
||||
static char units[MAX_INSTANCE_COUNT][TEMP_STRING_SHORT];
|
||||
|
@ -58,7 +65,9 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
|
||||
static struct lwm2m_engine_res_inst res[MAX_INSTANCE_COUNT][TEMP_MAX_ID];
|
||||
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][TEMP_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst
|
||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
static void update_min_measured(u16_t obj_inst_id, int index)
|
||||
{
|
||||
|
@ -93,6 +102,7 @@ static int reset_min_max_measured_values_cb(u16_t obj_inst_id)
|
|||
}
|
||||
|
||||
static int sensor_value_write_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -136,7 +146,7 @@ static int sensor_value_write_cb(u16_t obj_inst_id,
|
|||
|
||||
static struct lwm2m_engine_obj_inst *temp_sensor_create(u16_t obj_inst_id)
|
||||
{
|
||||
int index, i = 0;
|
||||
int index, i = 0, j = 0;
|
||||
|
||||
/* Check that there is no other instance with this ID */
|
||||
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
|
||||
|
@ -172,27 +182,29 @@ static struct lwm2m_engine_obj_inst *temp_sensor_create(u16_t obj_inst_id)
|
|||
max_range_value[index].val1 = 0;
|
||||
max_range_value[index].val2 = 0;
|
||||
|
||||
init_res_instance(res_inst[index], ARRAY_SIZE(res_inst[index]));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES(res[index], i, TEMP_SENSOR_VALUE_ID, 0,
|
||||
INIT_OBJ_RES(TEMP_SENSOR_VALUE_ID, res[index], i,
|
||||
res_inst[index], j, 1, true,
|
||||
&sensor_value[index], sizeof(*sensor_value),
|
||||
NULL, NULL, sensor_value_write_cb, NULL);
|
||||
INIT_OBJ_RES_DATA(res[index], i, TEMP_UNITS_ID,
|
||||
INIT_OBJ_RES_DATA(TEMP_UNITS_ID, res[index], i, res_inst[index], j,
|
||||
units[index], TEMP_STRING_SHORT);
|
||||
INIT_OBJ_RES_DATA(res[index], i, TEMP_MIN_MEASURED_VALUE_ID,
|
||||
&min_measured_value[index],
|
||||
INIT_OBJ_RES_DATA(TEMP_MIN_MEASURED_VALUE_ID, res[index], i,
|
||||
res_inst[index], j, &min_measured_value[index],
|
||||
sizeof(*min_measured_value));
|
||||
INIT_OBJ_RES_DATA(res[index], i, TEMP_MAX_MEASURED_VALUE_ID,
|
||||
&max_measured_value[index],
|
||||
INIT_OBJ_RES_DATA(TEMP_MAX_MEASURED_VALUE_ID, res[index], i,
|
||||
res_inst[index], j, &max_measured_value[index],
|
||||
sizeof(*max_measured_value));
|
||||
INIT_OBJ_RES_DATA(res[index], i, TEMP_MIN_RANGE_VALUE_ID,
|
||||
&min_range_value[index],
|
||||
INIT_OBJ_RES_DATA(TEMP_MIN_RANGE_VALUE_ID, res[index], i,
|
||||
res_inst[index], j, &min_range_value[index],
|
||||
sizeof(*min_range_value));
|
||||
INIT_OBJ_RES_DATA(res[index], i, TEMP_MAX_RANGE_VALUE_ID,
|
||||
&max_range_value[index],
|
||||
INIT_OBJ_RES_DATA(TEMP_MAX_RANGE_VALUE_ID, res[index], i,
|
||||
res_inst[index], j, &max_range_value[index],
|
||||
sizeof(*max_range_value));
|
||||
INIT_OBJ_RES_EXECUTE(res[index], i,
|
||||
TEMP_RESET_MIN_MAX_MEASURED_VALUES_ID,
|
||||
reset_min_max_measured_values_cb);
|
||||
INIT_OBJ_RES_EXECUTE(TEMP_RESET_MIN_MAX_MEASURED_VALUES_ID,
|
||||
res[index], i, reset_min_max_measured_values_cb);
|
||||
|
||||
inst[index].resources = res[index];
|
||||
inst[index].resource_count = i;
|
||||
|
@ -204,7 +216,7 @@ static int ipso_temp_sensor_init(struct device *dev)
|
|||
{
|
||||
/* Set default values */
|
||||
(void)memset(inst, 0, sizeof(*inst) * MAX_INSTANCE_COUNT);
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res_inst) *
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res) *
|
||||
MAX_INSTANCE_COUNT * TEMP_MAX_ID);
|
||||
|
||||
temp_sensor.obj_id = IPSO_OBJECT_TEMP_SENSOR_ID;
|
||||
|
|
|
@ -38,6 +38,13 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
|
||||
#define MAX_INSTANCE_COUNT CONFIG_LWM2M_IPSO_TIMER_INSTANCE_COUNT
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with TIMER_MAX_ID
|
||||
* subtract EXEC resources (1)
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (TIMER_MAX_ID - 1)
|
||||
|
||||
enum ipso_timer_mode {
|
||||
TIMER_MODE_OFF = 0,
|
||||
TIMER_MODE_ONE_SHOT,
|
||||
|
@ -83,7 +90,9 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
|
||||
static struct lwm2m_engine_res_inst res[MAX_INSTANCE_COUNT][TIMER_MAX_ID];
|
||||
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][TIMER_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst
|
||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
static int ms2float(u32_t ms, float64_value_t *f)
|
||||
{
|
||||
|
@ -170,7 +179,9 @@ static int stop_timer(struct ipso_timer_data *timer, bool cancel)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void *remaining_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *remaining_time_read_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
size_t *data_len)
|
||||
{
|
||||
u32_t temp = 0U;
|
||||
int i;
|
||||
|
@ -193,7 +204,9 @@ static void *remaining_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
|||
return &timer_data[i].remaining_time;
|
||||
}
|
||||
|
||||
static void *cumulative_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *cumulative_time_read_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
size_t *data_len)
|
||||
{
|
||||
int i;
|
||||
u32_t temp;
|
||||
|
@ -215,6 +228,7 @@ static void *cumulative_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
|||
}
|
||||
|
||||
static int cumulative_time_post_write_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -229,7 +243,9 @@ static int cumulative_time_post_write_cb(u16_t obj_inst_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int enabled_post_write_cb(u16_t obj_inst_id, u8_t *data, u16_t data_len,
|
||||
static int enabled_post_write_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
int i;
|
||||
|
@ -248,6 +264,7 @@ static int enabled_post_write_cb(u16_t obj_inst_id, u8_t *data, u16_t data_len,
|
|||
}
|
||||
|
||||
static int trigger_counter_post_write_cb(u16_t obj_inst_id,
|
||||
u16_t res_id, u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -284,7 +301,7 @@ static int timer_trigger_cb(u16_t obj_inst_id)
|
|||
|
||||
static struct lwm2m_engine_obj_inst *timer_create(u16_t obj_inst_id)
|
||||
{
|
||||
int index, avail = -1, i = 0;
|
||||
int index, avail = -1, i = 0, j = 0;
|
||||
|
||||
/* Check that there is no other instance with this ID */
|
||||
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
|
||||
|
@ -322,37 +339,46 @@ static struct lwm2m_engine_obj_inst *timer_create(u16_t obj_inst_id)
|
|||
timer_data[avail].timer_mode = TIMER_MODE_ONE_SHOT;
|
||||
timer_data[avail].obj_inst_id = obj_inst_id;
|
||||
|
||||
init_res_instance(res_inst[avail], ARRAY_SIZE(res_inst[avail]));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES_DATA(res[avail], i, TIMER_DELAY_DURATION_ID,
|
||||
&timer_data[avail].delay_duration,
|
||||
INIT_OBJ_RES_DATA(TIMER_DELAY_DURATION_ID, res[avail], i,
|
||||
res_inst[avail], j, &timer_data[avail].delay_duration,
|
||||
sizeof(timer_data[avail].delay_duration));
|
||||
INIT_OBJ_RES(res[avail], i, TIMER_REMAINING_TIME_ID, 0,
|
||||
INIT_OBJ_RES(TIMER_REMAINING_TIME_ID, res[avail], i,
|
||||
res_inst[avail], j, 1, true,
|
||||
&timer_data[avail].remaining_time,
|
||||
sizeof(timer_data[avail].remaining_time),
|
||||
remaining_time_read_cb, NULL, NULL, NULL);
|
||||
INIT_OBJ_RES_DATA(res[avail], i, TIMER_MINIMUM_OFF_TIME_ID,
|
||||
&timer_data[avail].min_off_time,
|
||||
INIT_OBJ_RES_DATA(TIMER_MINIMUM_OFF_TIME_ID, res[avail], i,
|
||||
res_inst[avail], j, &timer_data[avail].min_off_time,
|
||||
sizeof(timer_data[avail].min_off_time));
|
||||
INIT_OBJ_RES_EXECUTE(res[avail], i, TIMER_TRIGGER_ID,
|
||||
INIT_OBJ_RES_EXECUTE(TIMER_TRIGGER_ID, res[avail], i,
|
||||
timer_trigger_cb);
|
||||
INIT_OBJ_RES(res[avail], i, TIMER_ON_OFF_ID, 0,
|
||||
&timer_data[avail].enabled, sizeof(timer_data[avail].enabled),
|
||||
INIT_OBJ_RES(TIMER_ON_OFF_ID, res[avail], i,
|
||||
res_inst[avail], j, 1, true,
|
||||
&timer_data[avail].enabled,
|
||||
sizeof(timer_data[avail].enabled),
|
||||
NULL, NULL, enabled_post_write_cb, NULL);
|
||||
INIT_OBJ_RES(res[avail], i, TIMER_CUMULATIVE_TIME_ID, 0,
|
||||
INIT_OBJ_RES(TIMER_CUMULATIVE_TIME_ID, res[avail], i,
|
||||
res_inst[avail], j, 1, true,
|
||||
&timer_data[avail].cumulative_time,
|
||||
sizeof(timer_data[avail].cumulative_time),
|
||||
cumulative_time_read_cb, NULL, cumulative_time_post_write_cb,
|
||||
NULL);
|
||||
INIT_OBJ_RES_DATA(res[avail], i, TIMER_DIGITAL_STATE_ID,
|
||||
&timer_data[avail].active, sizeof(timer_data[avail].active));
|
||||
INIT_OBJ_RES(res[avail], i, TIMER_COUNTER_ID, 0,
|
||||
cumulative_time_read_cb, NULL,
|
||||
cumulative_time_post_write_cb, NULL);
|
||||
INIT_OBJ_RES_DATA(TIMER_DIGITAL_STATE_ID, res[avail], i,
|
||||
res_inst[avail], j, &timer_data[avail].active,
|
||||
sizeof(timer_data[avail].active));
|
||||
INIT_OBJ_RES(TIMER_COUNTER_ID, res[avail], i,
|
||||
res_inst[avail], j, 1, true,
|
||||
&timer_data[avail].trigger_counter,
|
||||
sizeof(timer_data[avail].trigger_counter),
|
||||
NULL, NULL, trigger_counter_post_write_cb, NULL);
|
||||
INIT_OBJ_RES_DATA(res[avail], i, TIMER_MODE_ID,
|
||||
INIT_OBJ_RES_DATA(TIMER_MODE_ID, res[avail], i, res_inst[avail], j,
|
||||
&timer_data[avail].timer_mode,
|
||||
sizeof(timer_data[avail].timer_mode));
|
||||
INIT_OBJ_RES_DUMMY(res[avail], i, TIMER_APPLICATION_TYPE_ID);
|
||||
INIT_OBJ_RES_OPTDATA(TIMER_APPLICATION_TYPE_ID, res[avail], i,
|
||||
res_inst[avail], j);
|
||||
|
||||
inst[avail].resources = res[avail];
|
||||
inst[avail].resource_count = i;
|
||||
|
@ -366,7 +392,7 @@ static int ipso_timer_init(struct device *dev)
|
|||
{
|
||||
/* Set default values */
|
||||
(void)memset(inst, 0, sizeof(*inst) * MAX_INSTANCE_COUNT);
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res_inst) *
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res) *
|
||||
MAX_INSTANCE_COUNT * TIMER_MAX_ID);
|
||||
|
||||
timer.obj_id = IPSO_OBJECT_TIMER_ID;
|
||||
|
|
|
@ -778,7 +778,7 @@ int lwm2m_delete_obj_inst(u16_t obj_id, u16_t obj_inst_id)
|
|||
for (i = 0; i < obj_inst->resource_count; i++) {
|
||||
clear_attrs(&obj_inst->resources[i]);
|
||||
(void)memset(obj_inst->resources + i, 0,
|
||||
sizeof(struct lwm2m_engine_res_inst));
|
||||
sizeof(struct lwm2m_engine_res));
|
||||
}
|
||||
|
||||
clear_attrs(obj_inst);
|
||||
|
@ -1246,11 +1246,13 @@ static int string_to_path(char *pathstr, struct lwm2m_obj_path *path,
|
|||
static int path_to_objs(const struct lwm2m_obj_path *path,
|
||||
struct lwm2m_engine_obj_inst **obj_inst,
|
||||
struct lwm2m_engine_obj_field **obj_field,
|
||||
struct lwm2m_engine_res_inst **res)
|
||||
struct lwm2m_engine_res **res,
|
||||
struct lwm2m_engine_res_inst **res_inst)
|
||||
{
|
||||
struct lwm2m_engine_obj_inst *oi;
|
||||
struct lwm2m_engine_obj_field *of;
|
||||
struct lwm2m_engine_res_inst *r = NULL;
|
||||
struct lwm2m_engine_res *r = NULL;
|
||||
struct lwm2m_engine_res_inst *ri = NULL;
|
||||
int i;
|
||||
|
||||
if (!path) {
|
||||
|
@ -1283,10 +1285,19 @@ static int path_to_objs(const struct lwm2m_obj_path *path,
|
|||
}
|
||||
|
||||
if (!r) {
|
||||
LOG_ERR("res instance %d not found", path->res_id);
|
||||
LOG_ERR("resource %d not found", path->res_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
for (i = 0; i < r->res_inst_count; i++) {
|
||||
if (r->res_instances[i].res_inst_id == path->res_inst_id) {
|
||||
ri = &r->res_instances[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* specifically don't complain about missing resource instance */
|
||||
|
||||
if (obj_inst) {
|
||||
*obj_inst = oi;
|
||||
}
|
||||
|
@ -1299,6 +1310,10 @@ static int path_to_objs(const struct lwm2m_obj_path *path,
|
|||
*res = r;
|
||||
}
|
||||
|
||||
if (ri && res_inst) {
|
||||
*res_inst = ri;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1328,7 +1343,7 @@ int lwm2m_engine_set_res_data(char *pathstr, void *data_ptr, u16_t data_len,
|
|||
u8_t data_flags)
|
||||
{
|
||||
struct lwm2m_obj_path path;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* translate path -> path_obj */
|
||||
|
@ -1338,20 +1353,25 @@ int lwm2m_engine_set_res_data(char *pathstr, void *data_ptr, u16_t data_len,
|
|||
}
|
||||
|
||||
if (path.level < 3) {
|
||||
LOG_ERR("path must have 3 parts");
|
||||
LOG_ERR("path must have at least 3 parts");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* look up resource obj */
|
||||
ret = path_to_objs(&path, NULL, NULL, &res);
|
||||
ret = path_to_objs(&path, NULL, NULL, NULL, &res_inst);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!res_inst) {
|
||||
LOG_ERR("res instance %d not found", path.res_inst_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* assign data elements */
|
||||
res->data_ptr = data_ptr;
|
||||
res->data_len = data_len;
|
||||
res->data_flags = data_flags;
|
||||
res_inst->data_ptr = data_ptr;
|
||||
res_inst->data_len = data_len;
|
||||
res_inst->data_flags = data_flags;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1361,7 +1381,8 @@ static int lwm2m_engine_set(char *pathstr, void *value, u16_t len)
|
|||
struct lwm2m_obj_path path;
|
||||
struct lwm2m_engine_obj_inst *obj_inst;
|
||||
struct lwm2m_engine_obj_field *obj_field;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
void *data_ptr = NULL;
|
||||
size_t data_len = 0;
|
||||
int ret = 0;
|
||||
|
@ -1376,44 +1397,46 @@ static int lwm2m_engine_set(char *pathstr, void *value, u16_t len)
|
|||
}
|
||||
|
||||
if (path.level < 3) {
|
||||
LOG_ERR("path must have 3 parts");
|
||||
LOG_ERR("path must have at least 3 parts");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* look up resource obj */
|
||||
ret = path_to_objs(&path, &obj_inst, &obj_field, &res);
|
||||
ret = path_to_objs(&path, &obj_inst, &obj_field, &res, &res_inst);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
LOG_ERR("res instance %d not found", path.res_id);
|
||||
if (!res_inst) {
|
||||
LOG_ERR("res instance %d not found", path.res_inst_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (LWM2M_HAS_RES_FLAG(res, LWM2M_RES_DATA_FLAG_RO)) {
|
||||
LOG_ERR("res data pointer is read-only");
|
||||
if (LWM2M_HAS_RES_FLAG(res_inst, LWM2M_RES_DATA_FLAG_RO)) {
|
||||
LOG_ERR("res instance data pointer is read-only");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* setup initial data elements */
|
||||
data_ptr = res->data_ptr;
|
||||
data_len = res->data_len;
|
||||
data_ptr = res_inst->data_ptr;
|
||||
data_len = res_inst->data_len;
|
||||
|
||||
/* allow user to override data elements via callback */
|
||||
if (res->pre_write_cb) {
|
||||
data_ptr = res->pre_write_cb(obj_inst->obj_inst_id, &data_len);
|
||||
data_ptr = res->pre_write_cb(obj_inst->obj_inst_id,
|
||||
res->res_id, res_inst->res_inst_id,
|
||||
&data_len);
|
||||
}
|
||||
|
||||
if (!data_ptr) {
|
||||
LOG_ERR("res data pointer is NULL");
|
||||
LOG_ERR("res instance data pointer is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check length (note: we add 1 to string length for NULL pad) */
|
||||
if (len > res->data_len -
|
||||
if (len > res_inst->data_len -
|
||||
(obj_field->data_type == LWM2M_RES_TYPE_STRING ? 1 : 0)) {
|
||||
LOG_ERR("length %u is too long for resource %d data",
|
||||
LOG_ERR("length %u is too long for res instance %d data",
|
||||
len, path.res_id);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -1491,8 +1514,9 @@ static int lwm2m_engine_set(char *pathstr, void *value, u16_t len)
|
|||
}
|
||||
|
||||
if (res->post_write_cb) {
|
||||
ret = res->post_write_cb(obj_inst->obj_inst_id, data_ptr, len,
|
||||
false, 0);
|
||||
ret = res->post_write_cb(obj_inst->obj_inst_id,
|
||||
res->res_id, res_inst->res_inst_id,
|
||||
data_ptr, len, false, 0);
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
|
@ -1575,7 +1599,7 @@ int lwm2m_engine_get_res_data(char *pathstr, void **data_ptr, u16_t *data_len,
|
|||
u8_t *data_flags)
|
||||
{
|
||||
struct lwm2m_obj_path path;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* translate path -> path_obj */
|
||||
|
@ -1585,19 +1609,24 @@ int lwm2m_engine_get_res_data(char *pathstr, void **data_ptr, u16_t *data_len,
|
|||
}
|
||||
|
||||
if (path.level < 3) {
|
||||
LOG_ERR("path must have 3 parts");
|
||||
LOG_ERR("path must have at least 3 parts");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* look up resource obj */
|
||||
ret = path_to_objs(&path, NULL, NULL, &res);
|
||||
ret = path_to_objs(&path, NULL, NULL, NULL, &res_inst);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*data_ptr = res->data_ptr;
|
||||
*data_len = res->data_len;
|
||||
*data_flags = res->data_flags;
|
||||
if (!res_inst) {
|
||||
LOG_ERR("res instance %d not found", path.res_inst_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
*data_ptr = res_inst->data_ptr;
|
||||
*data_len = res_inst->data_len;
|
||||
*data_flags = res_inst->data_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1608,7 +1637,8 @@ static int lwm2m_engine_get(char *pathstr, void *buf, u16_t buflen)
|
|||
struct lwm2m_obj_path path;
|
||||
struct lwm2m_engine_obj_inst *obj_inst;
|
||||
struct lwm2m_engine_obj_field *obj_field;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
void *data_ptr = NULL;
|
||||
size_t data_len = 0;
|
||||
|
||||
|
@ -1621,28 +1651,30 @@ static int lwm2m_engine_get(char *pathstr, void *buf, u16_t buflen)
|
|||
}
|
||||
|
||||
if (path.level < 3) {
|
||||
LOG_ERR("path must have 3 parts");
|
||||
LOG_ERR("path must have at least 3 parts");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* look up resource obj */
|
||||
ret = path_to_objs(&path, &obj_inst, &obj_field, &res);
|
||||
ret = path_to_objs(&path, &obj_inst, &obj_field, &res, &res_inst);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
LOG_ERR("res instance %d not found", path.res_id);
|
||||
if (!res_inst) {
|
||||
LOG_ERR("res instance %d not found", path.res_inst_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* setup initial data elements */
|
||||
data_ptr = res->data_ptr;
|
||||
data_len = res->data_len;
|
||||
data_ptr = res_inst->data_ptr;
|
||||
data_len = res_inst->data_len;
|
||||
|
||||
/* allow user to override data elements via callback */
|
||||
if (res->read_cb) {
|
||||
data_ptr = res->read_cb(obj_inst->obj_inst_id, &data_len);
|
||||
data_ptr = res->read_cb(obj_inst->obj_inst_id,
|
||||
res->res_id, res_inst->res_inst_id,
|
||||
&data_len);
|
||||
}
|
||||
|
||||
/* TODO: handle data_len > buflen case */
|
||||
|
@ -1797,7 +1829,7 @@ int lwm2m_engine_get_float64(char *pathstr, float64_value_t *buf)
|
|||
return lwm2m_engine_get(pathstr, buf, sizeof(float64_value_t));
|
||||
}
|
||||
|
||||
int lwm2m_engine_get_resource(char *pathstr, struct lwm2m_engine_res_inst **res)
|
||||
int lwm2m_engine_get_resource(char *pathstr, struct lwm2m_engine_res **res)
|
||||
{
|
||||
int ret;
|
||||
struct lwm2m_obj_path path;
|
||||
|
@ -1812,14 +1844,100 @@ int lwm2m_engine_get_resource(char *pathstr, struct lwm2m_engine_res_inst **res)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return path_to_objs(&path, NULL, NULL, res);
|
||||
return path_to_objs(&path, NULL, NULL, res, NULL);
|
||||
}
|
||||
|
||||
int lwm2m_engine_create_res_inst(char *pathstr)
|
||||
{
|
||||
int ret, i;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
struct lwm2m_obj_path path;
|
||||
|
||||
ret = string_to_path(pathstr, &path, '/');
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (path.level < 4) {
|
||||
LOG_ERR("path must have 4 parts");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = path_to_objs(&path, NULL, NULL, &res, &res_inst);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
LOG_ERR("resource %u not found", path.res_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (res_inst && res_inst->res_inst_id != RES_INSTANCE_NOT_CREATED) {
|
||||
LOG_ERR("res instance %u already exists", path.res_inst_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!res->res_instances || res->res_inst_count == 0) {
|
||||
LOG_ERR("no available res instances");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < res->res_inst_count; i++) {
|
||||
if (res->res_instances[i].res_inst_id ==
|
||||
RES_INSTANCE_NOT_CREATED) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= res->res_inst_count) {
|
||||
LOG_ERR("no available res instances");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res->res_instances[i].res_inst_id = path.res_inst_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwm2m_engine_delete_res_inst(char *pathstr)
|
||||
{
|
||||
int ret;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
struct lwm2m_obj_path path;
|
||||
|
||||
ret = string_to_path(pathstr, &path, '/');
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (path.level < 4) {
|
||||
LOG_ERR("path must have 4 parts");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = path_to_objs(&path, NULL, NULL, NULL, &res_inst);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!res_inst) {
|
||||
LOG_ERR("res instance %u not found", path.res_inst_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
res_inst->data_ptr = NULL;
|
||||
res_inst->data_len = 0U;
|
||||
res_inst->res_inst_id = RES_INSTANCE_NOT_CREATED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwm2m_engine_register_read_callback(char *pathstr,
|
||||
lwm2m_engine_get_data_cb_t cb)
|
||||
{
|
||||
int ret;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
|
||||
ret = lwm2m_engine_get_resource(pathstr, &res);
|
||||
if (ret < 0) {
|
||||
|
@ -1834,7 +1952,7 @@ int lwm2m_engine_register_pre_write_callback(char *pathstr,
|
|||
lwm2m_engine_get_data_cb_t cb)
|
||||
{
|
||||
int ret;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
|
||||
ret = lwm2m_engine_get_resource(pathstr, &res);
|
||||
if (ret < 0) {
|
||||
|
@ -1849,7 +1967,7 @@ int lwm2m_engine_register_post_write_callback(char *pathstr,
|
|||
lwm2m_engine_set_data_cb_t cb)
|
||||
{
|
||||
int ret;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
|
||||
ret = lwm2m_engine_get_resource(pathstr, &res);
|
||||
if (ret < 0) {
|
||||
|
@ -1864,7 +1982,7 @@ int lwm2m_engine_register_exec_callback(char *pathstr,
|
|||
lwm2m_engine_user_cb_t cb)
|
||||
{
|
||||
int ret;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
|
||||
ret = lwm2m_engine_get_resource(pathstr, &res);
|
||||
if (ret < 0) {
|
||||
|
@ -1908,11 +2026,11 @@ int lwm2m_engine_register_delete_callback(u16_t obj_id,
|
|||
/* generic data handlers */
|
||||
|
||||
static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||
struct lwm2m_engine_res_inst *res,
|
||||
struct lwm2m_engine_res *res,
|
||||
struct lwm2m_engine_obj_field *obj_field,
|
||||
struct lwm2m_message *msg)
|
||||
{
|
||||
int i, loop_max = 1;
|
||||
int i, loop_max = 1, found_values = 0;
|
||||
u16_t res_inst_id_tmp = 0U;
|
||||
void *data_ptr = NULL;
|
||||
size_t data_len = 0;
|
||||
|
@ -1921,33 +2039,50 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* setup initial data elements */
|
||||
data_ptr = res->data_ptr;
|
||||
data_len = res->data_len;
|
||||
|
||||
/* allow user to override data elements via callback */
|
||||
if (res->read_cb) {
|
||||
data_ptr = res->read_cb(obj_inst->obj_inst_id, &data_len);
|
||||
loop_max = res->res_inst_count;
|
||||
if (loop_max > 1) {
|
||||
/* search for valid resource instances */
|
||||
for (i = 0; i < loop_max; i++) {
|
||||
if (res->res_instances[i].res_inst_id !=
|
||||
RES_INSTANCE_NOT_CREATED) {
|
||||
found_values = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data_ptr || data_len == 0) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (res->multi_count_var != NULL) {
|
||||
/* if multi_count_var is 0 (none assigned) return NOT_FOUND */
|
||||
if (*res->multi_count_var == 0U) {
|
||||
if (!found_values) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
engine_put_begin_ri(&msg->out, &msg->path);
|
||||
loop_max = *res->multi_count_var;
|
||||
res_inst_id_tmp = msg->path.res_inst_id;
|
||||
}
|
||||
|
||||
for (i = 0; i < loop_max; i++) {
|
||||
if (res->multi_count_var != NULL) {
|
||||
msg->path.res_inst_id = (u16_t) i;
|
||||
if (res->res_instances[i].res_inst_id ==
|
||||
RES_INSTANCE_NOT_CREATED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res->res_inst_count > 1) {
|
||||
msg->path.res_inst_id =
|
||||
res->res_instances[i].res_inst_id;
|
||||
}
|
||||
|
||||
/* setup initial data elements */
|
||||
data_ptr = res->res_instances[i].data_ptr;
|
||||
data_len = res->res_instances[i].data_len;
|
||||
|
||||
/* allow user to override data elements via callback */
|
||||
if (res->read_cb) {
|
||||
data_ptr = res->read_cb(obj_inst->obj_inst_id,
|
||||
res->res_id,
|
||||
res->res_instances[i].res_inst_id,
|
||||
&data_len);
|
||||
}
|
||||
|
||||
if (!data_ptr || data_len == 0) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
switch (obj_field->data_type) {
|
||||
|
@ -1956,7 +2091,6 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
case LWM2M_RES_TYPE_OPAQUE:
|
||||
break;
|
||||
|
||||
/* TODO: handle multi count for string? */
|
||||
case LWM2M_RES_TYPE_STRING:
|
||||
engine_put_string(&msg->out, &msg->path,
|
||||
(u8_t *)data_ptr,
|
||||
|
@ -1965,58 +2099,58 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
|
||||
case LWM2M_RES_TYPE_U64:
|
||||
engine_put_s64(&msg->out, &msg->path,
|
||||
(s64_t)((u64_t *)data_ptr)[i]);
|
||||
(s64_t)*(u64_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_U32:
|
||||
case LWM2M_RES_TYPE_TIME:
|
||||
engine_put_s32(&msg->out, &msg->path,
|
||||
(s32_t)((u32_t *)data_ptr)[i]);
|
||||
(s32_t)*(u32_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_U16:
|
||||
engine_put_s16(&msg->out, &msg->path,
|
||||
(s16_t)((u16_t *)data_ptr)[i]);
|
||||
(s16_t)*(u16_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_U8:
|
||||
engine_put_s8(&msg->out, &msg->path,
|
||||
(s8_t)((u8_t *)data_ptr)[i]);
|
||||
(s8_t)*(u8_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_S64:
|
||||
engine_put_s64(&msg->out, &msg->path,
|
||||
((s64_t *)data_ptr)[i]);
|
||||
*(s64_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_S32:
|
||||
engine_put_s32(&msg->out, &msg->path,
|
||||
((s32_t *)data_ptr)[i]);
|
||||
*(s32_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_S16:
|
||||
engine_put_s16(&msg->out, &msg->path,
|
||||
((s16_t *)data_ptr)[i]);
|
||||
*(s16_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_S8:
|
||||
engine_put_s8(&msg->out, &msg->path,
|
||||
((s8_t *)data_ptr)[i]);
|
||||
*(s8_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_BOOL:
|
||||
engine_put_bool(&msg->out, &msg->path,
|
||||
((bool *)data_ptr)[i]);
|
||||
*(bool *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_FLOAT32:
|
||||
engine_put_float32fix(&msg->out, &msg->path,
|
||||
&((float32_value_t *)data_ptr)[i]);
|
||||
(float32_value_t *)data_ptr);
|
||||
break;
|
||||
|
||||
case LWM2M_RES_TYPE_FLOAT64:
|
||||
engine_put_float64fix(&msg->out, &msg->path,
|
||||
&((float64_value_t *)data_ptr)[i]);
|
||||
(float64_value_t *)data_ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2027,7 +2161,7 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
}
|
||||
}
|
||||
|
||||
if (res->multi_count_var != NULL) {
|
||||
if (res->res_inst_count > 1) {
|
||||
engine_put_end_ri(&msg->out, &msg->path);
|
||||
msg->path.res_inst_id = res_inst_id_tmp;
|
||||
}
|
||||
|
@ -2059,7 +2193,8 @@ size_t lwm2m_engine_get_opaque_more(struct lwm2m_input_context *in,
|
|||
}
|
||||
|
||||
static int lwm2m_write_handler_opaque(struct lwm2m_engine_obj_inst *obj_inst,
|
||||
struct lwm2m_engine_res_inst *res,
|
||||
struct lwm2m_engine_res *res,
|
||||
struct lwm2m_engine_res_inst *res_inst,
|
||||
struct lwm2m_input_context *in,
|
||||
void *data_ptr, size_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
|
@ -2090,6 +2225,8 @@ static int lwm2m_write_handler_opaque(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
|
||||
if (res->post_write_cb) {
|
||||
ret = res->post_write_cb(obj_inst->obj_inst_id,
|
||||
res->res_id,
|
||||
res_inst->res_inst_id,
|
||||
data_ptr, len,
|
||||
last_pkt_block && last_block,
|
||||
total_size);
|
||||
|
@ -2104,7 +2241,8 @@ static int lwm2m_write_handler_opaque(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
|
||||
/* This function is exposed for the content format writers */
|
||||
int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||
struct lwm2m_engine_res_inst *res,
|
||||
struct lwm2m_engine_res *res,
|
||||
struct lwm2m_engine_res_inst *res_inst,
|
||||
struct lwm2m_engine_obj_field *obj_field,
|
||||
struct lwm2m_message *msg)
|
||||
{
|
||||
|
@ -2120,21 +2258,23 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
u8_t tkl = 0U;
|
||||
bool last_block = true;
|
||||
|
||||
if (!obj_inst || !res || !obj_field || !msg) {
|
||||
if (!obj_inst || !res || !res_inst || !obj_field || !msg) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (LWM2M_HAS_RES_FLAG(res, LWM2M_RES_DATA_FLAG_RO)) {
|
||||
if (LWM2M_HAS_RES_FLAG(res_inst, LWM2M_RES_DATA_FLAG_RO)) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* setup initial data elements */
|
||||
data_ptr = res->data_ptr;
|
||||
data_len = res->data_len;
|
||||
data_ptr = res_inst->data_ptr;
|
||||
data_len = res_inst->data_len;
|
||||
|
||||
/* allow user to override data elements via callback */
|
||||
if (res->pre_write_cb) {
|
||||
data_ptr = res->pre_write_cb(obj_inst->obj_inst_id, &data_len);
|
||||
data_ptr = res->pre_write_cb(obj_inst->obj_inst_id,
|
||||
res->res_id, res_inst->res_inst_id,
|
||||
&data_len);
|
||||
}
|
||||
|
||||
if (res->post_write_cb) {
|
||||
|
@ -2161,7 +2301,7 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
|
||||
case LWM2M_RES_TYPE_OPAQUE:
|
||||
ret = lwm2m_write_handler_opaque(obj_inst, res,
|
||||
&msg->in,
|
||||
res_inst, &msg->in,
|
||||
data_ptr, data_len,
|
||||
last_block,
|
||||
total_size);
|
||||
|
@ -2252,7 +2392,9 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
|
||||
if (res->post_write_cb &&
|
||||
obj_field->data_type != LWM2M_RES_TYPE_OPAQUE) {
|
||||
ret = res->post_write_cb(obj_inst->obj_inst_id, data_ptr, len,
|
||||
ret = res->post_write_cb(obj_inst->obj_inst_id,
|
||||
res->res_id, res_inst->res_inst_id,
|
||||
data_ptr, len,
|
||||
last_block, total_size);
|
||||
}
|
||||
|
||||
|
@ -2269,7 +2411,7 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
|||
int nr_opt, i, ret = 0;
|
||||
struct coap_option options[NR_LWM2M_ATTR];
|
||||
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_attr *attr;
|
||||
struct notification_attrs nattrs = { 0 };
|
||||
struct observe_node *obs;
|
||||
|
@ -2298,7 +2440,7 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
|||
|
||||
/* get lwm2m_attr slist */
|
||||
if (msg->path.level == 3U) {
|
||||
ret = path_to_objs(&msg->path, NULL, NULL, &res);
|
||||
ret = path_to_objs(&msg->path, NULL, NULL, &res, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -2571,7 +2713,7 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
|||
|
||||
if (!res || res->res_id != obs->path.res_id) {
|
||||
ret = path_to_objs(&obs->path, NULL, NULL,
|
||||
&res);
|
||||
&res, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -2599,14 +2741,14 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
|||
static int lwm2m_exec_handler(struct lwm2m_message *msg)
|
||||
{
|
||||
struct lwm2m_engine_obj_inst *obj_inst;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
int ret;
|
||||
|
||||
if (!msg) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = path_to_objs(&msg->path, &obj_inst, NULL, &res);
|
||||
ret = path_to_objs(&msg->path, &obj_inst, NULL, &res, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -2666,7 +2808,7 @@ static int do_read_op(struct lwm2m_message *msg, u16_t content_format)
|
|||
int lwm2m_perform_read_op(struct lwm2m_message *msg, u16_t content_format)
|
||||
{
|
||||
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_obj_field *obj_field;
|
||||
struct lwm2m_obj_path temp_path;
|
||||
int ret = 0, index;
|
||||
|
|
|
@ -84,7 +84,8 @@ u16_t lwm2m_get_rd_data(u8_t *client_data, u16_t size);
|
|||
int lwm2m_perform_read_op(struct lwm2m_message *msg, u16_t content_format);
|
||||
|
||||
int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||
struct lwm2m_engine_res_inst *res,
|
||||
struct lwm2m_engine_res *res,
|
||||
struct lwm2m_engine_res_inst *res_inst,
|
||||
struct lwm2m_engine_obj_field *obj_field,
|
||||
struct lwm2m_message *msg);
|
||||
|
||||
|
@ -93,7 +94,7 @@ enum coap_block_size lwm2m_default_block_size(void);
|
|||
int lwm2m_engine_add_service(k_work_handler_t service, u32_t period_ms);
|
||||
|
||||
int lwm2m_engine_get_resource(char *pathstr,
|
||||
struct lwm2m_engine_res_inst **res);
|
||||
struct lwm2m_engine_res **res);
|
||||
|
||||
size_t lwm2m_engine_get_opaque_more(struct lwm2m_input_context *in,
|
||||
u8_t *buf, size_t buflen, bool *last_block);
|
||||
|
|
|
@ -67,21 +67,22 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
|
||||
#define DEVICE_SERVICE_INTERVAL K_SECONDS(10)
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with DEVICE_MAX_ID
|
||||
* subtract EXEC resources (3)
|
||||
* subtract MULTI resources because their counts include 0 resource (4)
|
||||
* add 3x DEVICE_PWRSRC_MAX for POWER SOURCES resource instances
|
||||
* add DEVICE_ERROR_CODE_MAX for ERROR CODE resource instances
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (DEVICE_MAX_ID - 3 - 4 + \
|
||||
DEVICE_PWRSRC_MAX*3 + DEVICE_ERROR_CODE_MAX)
|
||||
|
||||
/* resource state variables */
|
||||
static s8_t pwrsrc_available[DEVICE_PWRSRC_MAX];
|
||||
static s32_t pwrsrc_voltage_mv[DEVICE_PWRSRC_MAX];
|
||||
static s32_t pwrsrc_current_ma[DEVICE_PWRSRC_MAX];
|
||||
static u8_t battery_level;
|
||||
static s32_t mem_free_kb;
|
||||
static u8_t error_code_list[DEVICE_ERROR_CODE_MAX];
|
||||
static s32_t time_temp;
|
||||
static u32_t time_offset;
|
||||
static u8_t binding_mode[DEVICE_STRING_SHORT];
|
||||
static u8_t battery_status;
|
||||
static s32_t mem_total_kb;
|
||||
|
||||
static u8_t pwrsrc_count;
|
||||
static u8_t error_code_count;
|
||||
|
||||
/* only 1 instance of device object exists */
|
||||
static struct lwm2m_engine_obj device;
|
||||
|
@ -112,29 +113,29 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst;
|
||||
static struct lwm2m_engine_res_inst res[DEVICE_MAX_ID];
|
||||
static struct lwm2m_engine_res res[DEVICE_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst res_inst[RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
/* save error code resource instance point so we can easily clear later */
|
||||
static struct lwm2m_engine_res_inst *error_code_ri;
|
||||
|
||||
/* callbacks */
|
||||
|
||||
static int reboot_cb(u16_t obj_inst_id)
|
||||
{
|
||||
LOG_DBG("REBOOT");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int factory_default_cb(u16_t obj_inst_id)
|
||||
{
|
||||
LOG_DBG("FACTORY_DEFAULT");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int reset_error_list_cb(u16_t obj_inst_id)
|
||||
{
|
||||
error_code_count = 0U;
|
||||
int i;
|
||||
|
||||
/* "delete" error codes */
|
||||
for (i = 0; i < DEVICE_ERROR_CODE_MAX; i++) {
|
||||
error_code_list[i] = 0;
|
||||
error_code_ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *current_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *current_time_read_cb(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id, size_t *data_len)
|
||||
{
|
||||
time_temp = time_offset + (k_uptime_get() / 1000);
|
||||
*data_len = sizeof(time_temp);
|
||||
|
@ -142,13 +143,15 @@ static void *current_time_read_cb(u16_t obj_inst_id, size_t *data_len)
|
|||
return &time_temp;
|
||||
}
|
||||
|
||||
static void *current_time_pre_write_cb(u16_t obj_inst_id, size_t *data_len)
|
||||
static void *current_time_pre_write_cb(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id, size_t *data_len)
|
||||
{
|
||||
*data_len = sizeof(time_temp);
|
||||
return &time_temp;
|
||||
}
|
||||
|
||||
static int current_time_post_write_cb(u16_t obj_inst_id,
|
||||
static int current_time_post_write_cb(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
|
@ -163,108 +166,134 @@ static int current_time_post_write_cb(u16_t obj_inst_id,
|
|||
|
||||
/* special setter functions */
|
||||
|
||||
int lwm2m_device_add_pwrsrc(u8_t pwrsrc_type)
|
||||
__deprecated int lwm2m_device_add_pwrsrc(u8_t pwrsrc_type)
|
||||
{
|
||||
int index;
|
||||
int i;
|
||||
struct lwm2m_engine_res *res;
|
||||
|
||||
if (pwrsrc_type >= LWM2M_DEVICE_PWR_SRC_TYPE_MAX) {
|
||||
LOG_ERR("power source id %d is invalid", pwrsrc_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (index = 0; index < DEVICE_PWRSRC_MAX; index++) {
|
||||
if (pwrsrc_available[index] < 0) {
|
||||
i = lwm2m_engine_get_resource("3/0/6", &res);
|
||||
if (i < 0 || !res || !res->res_instances) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
for (i = 0; i < res->res_inst_count; i++) {
|
||||
if (res->res_instances[i].res_inst_id ==
|
||||
RES_INSTANCE_NOT_CREATED &&
|
||||
res->res_instances[i].data_ptr != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= DEVICE_PWRSRC_MAX) {
|
||||
if (i >= res->res_inst_count) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pwrsrc_available[index] = pwrsrc_type;
|
||||
pwrsrc_voltage_mv[index] = 0;
|
||||
pwrsrc_current_ma[index] = 0;
|
||||
pwrsrc_count++;
|
||||
*(u8_t *)res->res_instances[i].data_ptr = pwrsrc_type;
|
||||
res->res_instances[i].res_inst_id = i;
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0,
|
||||
DEVICE_AVAILABLE_POWER_SOURCES_ID);
|
||||
return index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: this will disable the index, but current printing function expects
|
||||
* all indexes to be in order up to pwrsrc_count
|
||||
*/
|
||||
int lwm2m_device_remove_pwrsrc(int index)
|
||||
__deprecated int lwm2m_device_remove_pwrsrc(int index)
|
||||
{
|
||||
if (index < 0 || index >= DEVICE_PWRSRC_MAX) {
|
||||
LOG_ERR("index is out of range: %d", index);
|
||||
int ret;
|
||||
struct lwm2m_engine_res *res;
|
||||
|
||||
ret = lwm2m_engine_get_resource("3/0/6", &res);
|
||||
if (ret < 0 || !res || !res->res_instances) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (index >= res->res_inst_count) {
|
||||
LOG_ERR("index %d is invalid", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pwrsrc_available[index] < 0) {
|
||||
LOG_ERR("Power source index %d isn't registered", index);
|
||||
return -EINVAL;
|
||||
if (res->res_instances[index].res_inst_id ==
|
||||
RES_INSTANCE_NOT_CREATED ||
|
||||
!res->res_instances[index].data_ptr) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pwrsrc_available[index] = -1;
|
||||
pwrsrc_voltage_mv[index] = 0;
|
||||
pwrsrc_current_ma[index] = 0;
|
||||
pwrsrc_count--;
|
||||
*(u8_t *)res->res_instances[index].data_ptr = 0;
|
||||
res->res_instances[index].res_inst_id = RES_INSTANCE_NOT_CREATED;
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0,
|
||||
DEVICE_AVAILABLE_POWER_SOURCES_ID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwm2m_device_set_pwrsrc_voltage_mv(int index, int voltage_mv)
|
||||
static int device_set_pwrsrc_value(char *pathstr, int index, s32_t value)
|
||||
{
|
||||
if (index < 0 || index >= DEVICE_PWRSRC_MAX) {
|
||||
LOG_ERR("index is out of range: %d", index);
|
||||
int ret;
|
||||
struct lwm2m_engine_res *res;
|
||||
|
||||
ret = lwm2m_engine_get_resource(pathstr, &res);
|
||||
if (ret < 0 || !res || !res->res_instances) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (index >= res->res_inst_count) {
|
||||
LOG_ERR("index %d is invalid", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pwrsrc_available[index] < 0) {
|
||||
LOG_ERR("Power source index %d isn't registered.", index);
|
||||
return -EINVAL;
|
||||
if (res->res_instances[index].res_inst_id ==
|
||||
RES_INSTANCE_NOT_CREATED ||
|
||||
!res->res_instances[index].data_ptr) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pwrsrc_voltage_mv[index] = voltage_mv;
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0,
|
||||
DEVICE_POWER_SOURCE_VOLTAGE_ID);
|
||||
*(s32_t *)res->res_instances[index].data_ptr = value;
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0, res->res_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwm2m_device_set_pwrsrc_current_ma(int index, int current_ma)
|
||||
__deprecated int lwm2m_device_set_pwrsrc_voltage_mv(int index, int voltage_mv)
|
||||
{
|
||||
if (index < 0 || index >= DEVICE_PWRSRC_MAX) {
|
||||
LOG_ERR("index is out of range: %d", index);
|
||||
return -EINVAL;
|
||||
return device_set_pwrsrc_value("3/0/7", index, voltage_mv);
|
||||
}
|
||||
|
||||
if (pwrsrc_available[index] < 0) {
|
||||
LOG_ERR("Power source index %d isn't registered.", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pwrsrc_current_ma[index] = current_ma;
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0,
|
||||
DEVICE_POWER_SOURCE_CURRENT_ID);
|
||||
return 0;
|
||||
__deprecated int lwm2m_device_set_pwrsrc_current_ma(int index, int current_ma)
|
||||
{
|
||||
return device_set_pwrsrc_value("3/0/8", index, current_ma);
|
||||
}
|
||||
|
||||
/* error code function */
|
||||
|
||||
int lwm2m_device_add_err(u8_t error_code)
|
||||
{
|
||||
if (error_code_count < DEVICE_ERROR_CODE_MAX) {
|
||||
error_code_list[error_code_count] = error_code;
|
||||
error_code_count++;
|
||||
return 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DEVICE_ERROR_CODE_MAX; i++) {
|
||||
if (error_code_ri[i].res_inst_id == RES_INSTANCE_NOT_CREATED) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= DEVICE_ERROR_CODE_MAX) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
error_code_list[i] = error_code;
|
||||
error_code_ri[i].res_inst_id = i;
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0, DEVICE_ERROR_CODE_ID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void device_periodic_service(struct k_work *work)
|
||||
{
|
||||
NOTIFY_OBSERVER(LWM2M_OBJECT_DEVICE_ID, 0, DEVICE_CURRENT_TIME_ID);
|
||||
|
@ -272,49 +301,46 @@ static void device_periodic_service(struct k_work *work)
|
|||
|
||||
static struct lwm2m_engine_obj_inst *device_create(u16_t obj_inst_id)
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0, j = 0;
|
||||
|
||||
init_res_instance(res_inst, ARRAY_SIZE(res_inst));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_MANUFACTURER_ID);
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_MODEL_NUMBER_ID);
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_SERIAL_NUMBER_ID);
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_FIRMWARE_VERSION_ID);
|
||||
INIT_OBJ_RES_EXECUTE(res, i, DEVICE_REBOOT_ID, reboot_cb);
|
||||
INIT_OBJ_RES_EXECUTE(res, i, DEVICE_FACTORY_DEFAULT_ID,
|
||||
factory_default_cb);
|
||||
INIT_OBJ_RES_MULTI_DATA(res, i, DEVICE_AVAILABLE_POWER_SOURCES_ID,
|
||||
&pwrsrc_count, pwrsrc_available,
|
||||
sizeof(*pwrsrc_available));
|
||||
INIT_OBJ_RES_MULTI_DATA(res, i, DEVICE_POWER_SOURCE_VOLTAGE_ID,
|
||||
&pwrsrc_count, pwrsrc_voltage_mv,
|
||||
sizeof(*pwrsrc_voltage_mv));
|
||||
INIT_OBJ_RES_MULTI_DATA(res, i, DEVICE_POWER_SOURCE_CURRENT_ID,
|
||||
&pwrsrc_count, pwrsrc_current_ma,
|
||||
sizeof(*pwrsrc_current_ma));
|
||||
INIT_OBJ_RES_DATA(res, i, DEVICE_BATTERY_LEVEL_ID,
|
||||
&battery_level, sizeof(battery_level));
|
||||
INIT_OBJ_RES_DATA(res, i, DEVICE_MEMORY_FREE_ID,
|
||||
&mem_free_kb, sizeof(mem_free_kb));
|
||||
INIT_OBJ_RES_MULTI_DATA(res, i, DEVICE_ERROR_CODE_ID,
|
||||
&error_code_count, error_code_list,
|
||||
sizeof(*error_code_list));
|
||||
INIT_OBJ_RES_EXECUTE(res, i, DEVICE_RESET_ERROR_CODE_ID,
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_MANUFACTURER_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_MODEL_NUMBER_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_SERIAL_NUMBER_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_FIRMWARE_VERSION_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_EXECUTE(DEVICE_REBOOT_ID, res, i, NULL);
|
||||
INIT_OBJ_RES_EXECUTE(DEVICE_FACTORY_DEFAULT_ID, res, i, NULL);
|
||||
INIT_OBJ_RES_MULTI_OPTDATA(DEVICE_AVAILABLE_POWER_SOURCES_ID, res, i,
|
||||
res_inst, j, DEVICE_PWRSRC_MAX, false);
|
||||
INIT_OBJ_RES_MULTI_OPTDATA(DEVICE_POWER_SOURCE_VOLTAGE_ID, res, i,
|
||||
res_inst, j, DEVICE_PWRSRC_MAX, false);
|
||||
INIT_OBJ_RES_MULTI_OPTDATA(DEVICE_POWER_SOURCE_CURRENT_ID, res, i,
|
||||
res_inst, j, DEVICE_PWRSRC_MAX, false);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_BATTERY_LEVEL_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_MEMORY_FREE_ID, res, i, res_inst, j);
|
||||
error_code_ri = &res_inst[j];
|
||||
INIT_OBJ_RES_MULTI_DATA(DEVICE_ERROR_CODE_ID, res, i,
|
||||
res_inst, j, DEVICE_ERROR_CODE_MAX, false,
|
||||
error_code_list, sizeof(*error_code_list));
|
||||
INIT_OBJ_RES_EXECUTE(DEVICE_RESET_ERROR_CODE_ID, res, i,
|
||||
reset_error_list_cb);
|
||||
INIT_OBJ_RES(res, i, DEVICE_CURRENT_TIME_ID, 0, NULL, 0,
|
||||
current_time_read_cb, current_time_pre_write_cb,
|
||||
INIT_OBJ_RES_OPT(DEVICE_CURRENT_TIME_ID, res, i, res_inst, j, 1, true,
|
||||
current_time_read_cb,
|
||||
current_time_pre_write_cb,
|
||||
current_time_post_write_cb, NULL);
|
||||
INIT_OBJ_RES_DATA(res, i, DEVICE_SUPPORTED_BINDING_MODES_ID,
|
||||
binding_mode, DEVICE_STRING_SHORT);
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_TYPE_ID);
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_HARDWARE_VERSION_ID);
|
||||
INIT_OBJ_RES_DUMMY(res, i, DEVICE_SOFTWARE_VERSION_ID);
|
||||
INIT_OBJ_RES_DATA(res, i, DEVICE_BATTERY_STATUS_ID,
|
||||
&battery_status, sizeof(battery_status));
|
||||
INIT_OBJ_RES_DATA(res, i, DEVICE_MEMORY_TOTAL_ID,
|
||||
&mem_total_kb, sizeof(mem_total_kb));
|
||||
INIT_OBJ_RES_DATA(DEVICE_SUPPORTED_BINDING_MODES_ID, res, i,
|
||||
res_inst, j, binding_mode, DEVICE_STRING_SHORT);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_TYPE_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_HARDWARE_VERSION_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_SOFTWARE_VERSION_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_BATTERY_STATUS_ID, res, i, res_inst, j);
|
||||
INIT_OBJ_RES_OPTDATA(DEVICE_MEMORY_TOTAL_ID, res, i, res_inst, j);
|
||||
|
||||
inst.resources = res;
|
||||
inst.resource_count = i;
|
||||
|
||||
LOG_DBG("Create LWM2M device instance: %d", obj_inst_id);
|
||||
return &inst;
|
||||
}
|
||||
|
@ -322,21 +348,13 @@ static struct lwm2m_engine_obj_inst *device_create(u16_t obj_inst_id)
|
|||
static int lwm2m_device_init(struct device *dev)
|
||||
{
|
||||
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||
int ret = 0, i;
|
||||
int ret = 0;
|
||||
|
||||
/* Set default values */
|
||||
time_offset = 0U;
|
||||
mem_total_kb = 0;
|
||||
mem_free_kb = -1;
|
||||
pwrsrc_count = 0U;
|
||||
error_code_count = 0U;
|
||||
/* currently only support UDP binding mode (no SMS or Queue mode) */
|
||||
strcpy(binding_mode, "U");
|
||||
|
||||
for (i = 0; i < DEVICE_PWRSRC_MAX; i++) {
|
||||
pwrsrc_available[i] = -1;
|
||||
}
|
||||
|
||||
/* initialize the device field data */
|
||||
device.obj_id = LWM2M_OBJECT_DEVICE_ID;
|
||||
device.fields = fields;
|
||||
|
|
|
@ -36,6 +36,13 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
|
||||
#define PACKAGE_URI_LEN 255
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with FIRMWARE_MAX_ID
|
||||
* subtract EXEC resources (1)
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (FIRMWARE_MAX_ID - 1)
|
||||
|
||||
/* resource state variables */
|
||||
static u8_t update_state;
|
||||
static u8_t update_result;
|
||||
|
@ -57,7 +64,8 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst;
|
||||
static struct lwm2m_engine_res_inst res[FIRMWARE_MAX_ID];
|
||||
static struct lwm2m_engine_res res[FIRMWARE_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst res_inst[RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
static lwm2m_engine_set_data_cb_t write_cb;
|
||||
static lwm2m_engine_user_cb_t update_cb;
|
||||
|
@ -179,8 +187,8 @@ void lwm2m_firmware_set_update_result(u8_t result)
|
|||
LOG_DBG("Update result = %d", update_result);
|
||||
}
|
||||
|
||||
static int package_write_cb(u16_t obj_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
static int package_write_cb(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id, u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
u8_t state;
|
||||
|
@ -203,7 +211,8 @@ static int package_write_cb(u16_t obj_inst_id,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
ret = write_cb ? write_cb(obj_inst_id, data, data_len,
|
||||
ret = write_cb ? write_cb(obj_inst_id, res_id, res_inst_id,
|
||||
data, data_len,
|
||||
last_block, total_size) : 0;
|
||||
if (ret >= 0) {
|
||||
if (last_block) {
|
||||
|
@ -227,8 +236,8 @@ static int package_write_cb(u16_t obj_inst_id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int package_uri_write_cb(u16_t obj_inst_id,
|
||||
u8_t *data, u16_t data_len,
|
||||
static int package_uri_write_cb(u16_t obj_inst_id, u16_t res_id,
|
||||
u16_t res_inst_id, u8_t *data, u16_t data_len,
|
||||
bool last_block, size_t total_size)
|
||||
{
|
||||
LOG_DBG("PACKAGE_URI WRITE: %s", log_strdup(package_uri));
|
||||
|
@ -301,25 +310,27 @@ static int firmware_update_cb(u16_t obj_inst_id)
|
|||
|
||||
static struct lwm2m_engine_obj_inst *firmware_create(u16_t obj_inst_id)
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0, j = 0;
|
||||
|
||||
init_res_instance(res_inst, ARRAY_SIZE(res_inst));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES(res, i, FIRMWARE_PACKAGE_ID, 0, NULL, 0,
|
||||
INIT_OBJ_RES_OPT(FIRMWARE_PACKAGE_ID, res, i, res_inst, j, 1, true,
|
||||
NULL, NULL, package_write_cb, NULL);
|
||||
INIT_OBJ_RES(res, i, FIRMWARE_PACKAGE_URI_ID, 0,
|
||||
INIT_OBJ_RES(FIRMWARE_PACKAGE_URI_ID, res, i, res_inst, j, 1, true,
|
||||
package_uri, PACKAGE_URI_LEN,
|
||||
NULL, NULL, package_uri_write_cb, NULL);
|
||||
INIT_OBJ_RES_EXECUTE(res, i, FIRMWARE_UPDATE_ID,
|
||||
firmware_update_cb);
|
||||
INIT_OBJ_RES_DATA(res, i, FIRMWARE_STATE_ID,
|
||||
INIT_OBJ_RES_EXECUTE(FIRMWARE_UPDATE_ID, res, i, firmware_update_cb);
|
||||
INIT_OBJ_RES_DATA(FIRMWARE_STATE_ID, res, i, res_inst, j,
|
||||
&update_state, sizeof(update_state));
|
||||
INIT_OBJ_RES_DATA(res, i, FIRMWARE_UPDATE_RESULT_ID,
|
||||
INIT_OBJ_RES_DATA(FIRMWARE_UPDATE_RESULT_ID, res, i, res_inst, j,
|
||||
&update_result, sizeof(update_result));
|
||||
INIT_OBJ_RES_DATA(res, i, FIRMWARE_UPDATE_DELIV_METHOD_ID,
|
||||
INIT_OBJ_RES_DATA(FIRMWARE_UPDATE_DELIV_METHOD_ID, res, i, res_inst, j,
|
||||
&delivery_method, sizeof(delivery_method));
|
||||
|
||||
inst.resources = res;
|
||||
inst.resource_count = i;
|
||||
|
||||
LOG_DBG("Create LWM2M firmware instance: %d", obj_inst_id);
|
||||
return &inst;
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
|
|||
u8_t tkl;
|
||||
u16_t payload_len, payload_offset, len;
|
||||
struct coap_packet *check_response = (struct coap_packet *)response;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
lwm2m_engine_set_data_cb_t write_cb;
|
||||
size_t write_buflen;
|
||||
u8_t resp_code, *write_buf;
|
||||
|
@ -311,12 +311,12 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
|
|||
}
|
||||
|
||||
/* get buffer data */
|
||||
write_buf = res->data_ptr;
|
||||
write_buflen = res->data_len;
|
||||
write_buf = res->res_instances->data_ptr;
|
||||
write_buflen = res->res_instances->data_len;
|
||||
|
||||
/* check for user override to buffer */
|
||||
if (res->pre_write_cb) {
|
||||
write_buf = res->pre_write_cb(0, &write_buflen);
|
||||
write_buf = res->pre_write_cb(0, 0, 0, &write_buflen);
|
||||
}
|
||||
|
||||
write_cb = lwm2m_firmware_get_write_cb();
|
||||
|
@ -335,7 +335,8 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
|
|||
goto error;
|
||||
}
|
||||
|
||||
ret = write_cb(0, write_buf, len, last_block,
|
||||
ret = write_cb(0, 0, 0,
|
||||
write_buf, len, last_block,
|
||||
firmware_block_ctx.total_size);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
|
|
|
@ -40,6 +40,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
#define IDENTITY_LEN 128
|
||||
#define KEY_LEN CONFIG_LWM2M_SECURITY_KEY_SIZE
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with SECURITY_MAX_ID
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (SECURITY_MAX_ID)
|
||||
|
||||
/* resource state variables */
|
||||
static char security_uri[MAX_INSTANCE_COUNT][SECURITY_URI_LEN];
|
||||
static u8_t client_identity[MAX_INSTANCE_COUNT][IDENTITY_LEN];
|
||||
|
@ -67,11 +73,13 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
|
||||
static struct lwm2m_engine_res_inst res[MAX_INSTANCE_COUNT][SECURITY_MAX_ID];
|
||||
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][SECURITY_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst
|
||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
static struct lwm2m_engine_obj_inst *security_create(u16_t obj_inst_id)
|
||||
{
|
||||
int index, i = 0;
|
||||
int index, i = 0, j = 0;
|
||||
|
||||
/* Check that there is no other instance with this ID */
|
||||
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
|
||||
|
@ -101,25 +109,35 @@ static struct lwm2m_engine_obj_inst *security_create(u16_t obj_inst_id)
|
|||
security_mode[index] = 0U;
|
||||
short_server_id[index] = 0U;
|
||||
|
||||
init_res_instance(res_inst[index], ARRAY_SIZE(res_inst[index]));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_SERVER_URI_ID,
|
||||
INIT_OBJ_RES_DATA(SECURITY_SERVER_URI_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
security_uri[index], SECURITY_URI_LEN);
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_BOOTSTRAP_FLAG_ID,
|
||||
INIT_OBJ_RES_DATA(SECURITY_BOOTSTRAP_FLAG_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&bootstrap_flag[index], sizeof(*bootstrap_flag));
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_MODE_ID,
|
||||
INIT_OBJ_RES_DATA(SECURITY_MODE_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&security_mode[index], sizeof(*security_mode));
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_CLIENT_PK_ID,
|
||||
&client_identity[index], IDENTITY_LEN),
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_SERVER_PK_ID,
|
||||
&server_pk[index], KEY_LEN),
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_SECRET_KEY_ID,
|
||||
&secret_key[index], KEY_LEN),
|
||||
INIT_OBJ_RES_DATA(res[index], i, SECURITY_SHORT_SERVER_ID,
|
||||
INIT_OBJ_RES_DATA(SECURITY_CLIENT_PK_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&client_identity[index], IDENTITY_LEN);
|
||||
INIT_OBJ_RES_DATA(SECURITY_SERVER_PK_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&server_pk[index], KEY_LEN);
|
||||
INIT_OBJ_RES_DATA(SECURITY_SECRET_KEY_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&secret_key[index], KEY_LEN);
|
||||
INIT_OBJ_RES_DATA(SECURITY_SHORT_SERVER_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&short_server_id[index], sizeof(*short_server_id));
|
||||
|
||||
inst[index].resources = res[index];
|
||||
inst[index].resource_count = i;
|
||||
LOG_DBG("Create LWM2M security instance: %d", obj_inst_id);
|
||||
|
||||
return &inst[index];
|
||||
}
|
||||
|
||||
|
@ -157,7 +175,7 @@ static int lwm2m_security_init(struct device *dev)
|
|||
|
||||
/* Set default values */
|
||||
(void)memset(inst, 0, sizeof(*inst) * MAX_INSTANCE_COUNT);
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res_inst) *
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res) *
|
||||
MAX_INSTANCE_COUNT * SECURITY_MAX_ID);
|
||||
|
||||
security.obj_id = LWM2M_OBJECT_SECURITY_ID;
|
||||
|
|
|
@ -41,6 +41,13 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
|
||||
#define TRANSPORT_BINDING_LEN 4
|
||||
|
||||
/*
|
||||
* Calculate resource instances as follows:
|
||||
* start with SERVER_MAX_ID
|
||||
* subtract EXEC resources (2)
|
||||
*/
|
||||
#define RESOURCE_INSTANCE_COUNT (SERVER_MAX_ID - 2)
|
||||
|
||||
/* resource state variables */
|
||||
static u16_t server_id[MAX_INSTANCE_COUNT];
|
||||
static u32_t lifetime[MAX_INSTANCE_COUNT];
|
||||
|
@ -71,7 +78,9 @@ static struct lwm2m_engine_obj_field fields[] = {
|
|||
};
|
||||
|
||||
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
|
||||
static struct lwm2m_engine_res_inst res[MAX_INSTANCE_COUNT][SERVER_MAX_ID];
|
||||
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][SERVER_MAX_ID];
|
||||
static struct lwm2m_engine_res_inst
|
||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
||||
|
||||
static int disable_cb(u16_t obj_inst_id)
|
||||
{
|
||||
|
@ -126,7 +135,7 @@ s32_t lwm2m_server_get_pmax(u16_t obj_inst_id)
|
|||
|
||||
static struct lwm2m_engine_obj_inst *server_create(u16_t obj_inst_id)
|
||||
{
|
||||
int index, i = 0;
|
||||
int index, i = 0, j = 0;
|
||||
|
||||
/* Check that there is no other instance with this ID */
|
||||
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
|
||||
|
@ -159,28 +168,37 @@ static struct lwm2m_engine_obj_inst *server_create(u16_t obj_inst_id)
|
|||
disabled_timeout[index] = 86400U;
|
||||
strcpy(transport_binding[index], "U");
|
||||
|
||||
init_res_instance(res_inst[index], ARRAY_SIZE(res_inst[index]));
|
||||
|
||||
/* initialize instance resource data */
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_SHORT_SERVER_ID,
|
||||
INIT_OBJ_RES_DATA(SERVER_SHORT_SERVER_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&server_id[index], sizeof(*server_id));
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_LIFETIME_ID,
|
||||
INIT_OBJ_RES_DATA(SERVER_LIFETIME_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&lifetime[index], sizeof(*lifetime));
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_DEFAULT_MIN_PERIOD_ID,
|
||||
INIT_OBJ_RES_DATA(SERVER_DEFAULT_MIN_PERIOD_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&default_min_period[index],
|
||||
sizeof(*default_min_period));
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_DEFAULT_MAX_PERIOD_ID,
|
||||
INIT_OBJ_RES_DATA(SERVER_DEFAULT_MAX_PERIOD_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&default_max_period[index],
|
||||
sizeof(*default_max_period));
|
||||
INIT_OBJ_RES_EXECUTE(res[index], i, SERVER_DISABLE_ID, disable_cb);
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_DISABLE_TIMEOUT_ID,
|
||||
INIT_OBJ_RES_EXECUTE(SERVER_DISABLE_ID, res[index], i, disable_cb);
|
||||
INIT_OBJ_RES_DATA(SERVER_DISABLE_TIMEOUT_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&disabled_timeout[index],
|
||||
sizeof(*disabled_timeout));
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_STORE_NOTIFY_ID,
|
||||
INIT_OBJ_RES_DATA(SERVER_STORE_NOTIFY_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
&server_flag_store_notify[index],
|
||||
sizeof(*server_flag_store_notify));
|
||||
/* Mark Transport Binding RO as we only support UDP atm */
|
||||
INIT_OBJ_RES_DATA(res[index], i, SERVER_TRANSPORT_BINDING_ID,
|
||||
INIT_OBJ_RES_DATA(SERVER_TRANSPORT_BINDING_ID, res[index], i,
|
||||
res_inst[index], j,
|
||||
transport_binding[index], TRANSPORT_BINDING_LEN);
|
||||
INIT_OBJ_RES_EXECUTE(res[index], i, SERVER_REG_UPDATE_TRIGGER_ID,
|
||||
INIT_OBJ_RES_EXECUTE(SERVER_REG_UPDATE_TRIGGER_ID, res[index], i,
|
||||
update_trigger_cb);
|
||||
|
||||
inst[index].resources = res[index];
|
||||
|
@ -196,7 +214,7 @@ static int lwm2m_server_init(struct device *dev)
|
|||
|
||||
/* Set default values */
|
||||
(void)memset(inst, 0, sizeof(*inst) * MAX_INSTANCE_COUNT);
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res_inst) *
|
||||
(void)memset(res, 0, sizeof(struct lwm2m_engine_res) *
|
||||
MAX_INSTANCE_COUNT * SERVER_MAX_ID);
|
||||
|
||||
server.obj_id = LWM2M_OBJECT_SERVER_ID;
|
||||
|
|
|
@ -192,32 +192,112 @@ struct lwm2m_engine_obj {
|
|||
u16_t max_instance_count;
|
||||
};
|
||||
|
||||
#define INIT_OBJ_RES(res_var, index_var, id_val, multi_var, \
|
||||
data_val, data_val_len, r_cb, pre_w_cb, post_w_cb, ex_cb) \
|
||||
res_var[index_var].res_id = id_val; \
|
||||
res_var[index_var].multi_count_var = multi_var; \
|
||||
res_var[index_var].data_ptr = data_val; \
|
||||
res_var[index_var].data_len = data_val_len; \
|
||||
res_var[index_var].read_cb = r_cb; \
|
||||
res_var[index_var].pre_write_cb = pre_w_cb; \
|
||||
res_var[index_var].post_write_cb = post_w_cb; \
|
||||
res_var[index_var++].execute_cb = ex_cb
|
||||
/* Resource instances with this value are considered "not created" yet */
|
||||
#define RES_INSTANCE_NOT_CREATED 65535
|
||||
|
||||
#define INIT_OBJ_RES_MULTI_DATA(res_var, index_var, id_val, multi_var, \
|
||||
data_val, data_val_len) \
|
||||
INIT_OBJ_RES(res_var, index_var, id_val, multi_var, data_val, \
|
||||
data_val_len, NULL, NULL, NULL, NULL)
|
||||
/* Resource macros */
|
||||
#define _INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_count, \
|
||||
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
|
||||
_r_ptr[_r_idx].res_id = _id; \
|
||||
_r_ptr[_r_idx].res_instances = _ri_ptr; \
|
||||
_r_ptr[_r_idx].res_inst_count = _ri_count; \
|
||||
_r_ptr[_r_idx].read_cb = _r_cb; \
|
||||
_r_ptr[_r_idx].pre_write_cb = _pre_w_cb; \
|
||||
_r_ptr[_r_idx].post_write_cb = _post_w_cb; \
|
||||
_r_ptr[_r_idx].execute_cb = _ex_cb
|
||||
|
||||
#define INIT_OBJ_RES_DATA(res_var, index_var, id_val, data_val, data_val_len) \
|
||||
INIT_OBJ_RES_MULTI_DATA(res_var, index_var, id_val, NULL, \
|
||||
data_val, data_val_len)
|
||||
#define _INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
_data_ptr, _data_len) \
|
||||
do { \
|
||||
if (_ri_ptr != NULL && _ri_count > 0) { \
|
||||
for (int _i = 0; _i < _ri_count; _i++) { \
|
||||
_ri_ptr[_ri_idx + _i].data_ptr = \
|
||||
(_data_ptr + _i); \
|
||||
_ri_ptr[_ri_idx + _i].data_len = \
|
||||
_data_len; \
|
||||
if (_ri_create) { \
|
||||
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
||||
_i; \
|
||||
} else { \
|
||||
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
||||
RES_INSTANCE_NOT_CREATED; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
_ri_idx += _ri_count; \
|
||||
} while (false)
|
||||
|
||||
#define INIT_OBJ_RES_DUMMY(res_var, index_var, id_val) \
|
||||
INIT_OBJ_RES_MULTI_DATA(res_var, index_var, id_val, NULL, NULL, 0)
|
||||
#define _INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create) \
|
||||
do { \
|
||||
if (_ri_count > 0) { \
|
||||
for (int _i = 0; _i < _ri_count; _i++) { \
|
||||
_ri_ptr[_ri_idx + _i].data_ptr = NULL; \
|
||||
_ri_ptr[_ri_idx + _i].data_len = 0; \
|
||||
if (_ri_create) { \
|
||||
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
||||
_i; \
|
||||
} else { \
|
||||
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
||||
RES_INSTANCE_NOT_CREATED; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
_ri_idx += _ri_count; \
|
||||
} while (false)
|
||||
|
||||
#define INIT_OBJ_RES_EXECUTE(res_var, index_var, id_val, ex_cb) \
|
||||
INIT_OBJ_RES(res_var, index_var, id_val, NULL, NULL, 0, \
|
||||
NULL, NULL, NULL, ex_cb)
|
||||
#define INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
||||
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
_data_ptr, _data_len, \
|
||||
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
|
||||
do { \
|
||||
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
||||
(_ri_ptr + _ri_idx), _ri_count, \
|
||||
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb); \
|
||||
_INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
_data_ptr, _data_len); \
|
||||
++_r_idx; \
|
||||
} while (false)
|
||||
|
||||
|
||||
#define INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
|
||||
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
|
||||
do { \
|
||||
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
||||
(_ri_ptr + _ri_idx), _ri_count, \
|
||||
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb); \
|
||||
_INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create); \
|
||||
++_r_idx; \
|
||||
} while (false)
|
||||
|
||||
#define INIT_OBJ_RES_MULTI_DATA(_id, _r_ptr, _r_idx, \
|
||||
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
_data_ptr, _data_len) \
|
||||
INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
||||
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
_data_ptr, _data_len, NULL, NULL, NULL, NULL)
|
||||
|
||||
#define INIT_OBJ_RES_MULTI_OPTDATA(_id, _r_ptr, _r_idx, \
|
||||
_ri_ptr, _ri_idx, _ri_count, _ri_create) \
|
||||
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
|
||||
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
||||
NULL, NULL, NULL, NULL)
|
||||
|
||||
#define INIT_OBJ_RES_DATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, \
|
||||
_data_ptr, _data_len) \
|
||||
INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, true, \
|
||||
_data_ptr, _data_len, NULL, NULL, NULL, NULL)
|
||||
|
||||
#define INIT_OBJ_RES_OPTDATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx) \
|
||||
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, true, \
|
||||
NULL, NULL, NULL, NULL)
|
||||
|
||||
#define INIT_OBJ_RES_EXECUTE(_id, _r_ptr, _r_idx, _ex_cb) \
|
||||
do { \
|
||||
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, NULL, 0, \
|
||||
NULL, NULL, NULL, _ex_cb); \
|
||||
++_r_idx; \
|
||||
} while (false)
|
||||
|
||||
|
||||
#define LWM2M_ATTR_PMIN 0
|
||||
|
@ -241,17 +321,21 @@ struct lwm2m_attr {
|
|||
};
|
||||
|
||||
struct lwm2m_engine_res_inst {
|
||||
/* callbacks set by user code on obj instance */
|
||||
void *data_ptr;
|
||||
u16_t data_len;
|
||||
u16_t res_inst_id; /* 65535 == not "created" */
|
||||
u8_t data_flags;
|
||||
};
|
||||
|
||||
struct lwm2m_engine_res {
|
||||
lwm2m_engine_get_data_cb_t read_cb;
|
||||
lwm2m_engine_get_data_cb_t pre_write_cb;
|
||||
lwm2m_engine_set_data_cb_t post_write_cb;
|
||||
lwm2m_engine_user_cb_t execute_cb;
|
||||
|
||||
u8_t *multi_count_var;
|
||||
void *data_ptr;
|
||||
u16_t data_len;
|
||||
struct lwm2m_engine_res_inst *res_instances;
|
||||
u16_t res_id;
|
||||
u8_t data_flags;
|
||||
u8_t res_inst_count;
|
||||
};
|
||||
|
||||
struct lwm2m_engine_obj_inst {
|
||||
|
@ -259,13 +343,25 @@ struct lwm2m_engine_obj_inst {
|
|||
sys_snode_t node;
|
||||
|
||||
struct lwm2m_engine_obj *obj;
|
||||
struct lwm2m_engine_res_inst *resources;
|
||||
struct lwm2m_engine_res *resources;
|
||||
|
||||
/* object instance member data */
|
||||
u16_t obj_inst_id;
|
||||
u16_t resource_count;
|
||||
};
|
||||
|
||||
/* Initialize resource instances prior to use */
|
||||
static inline void init_res_instance(struct lwm2m_engine_res_inst *ri,
|
||||
size_t ri_len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
memset(ri, 0, sizeof(*ri) * ri_len);
|
||||
for (i = 0; i < ri_len; i++) {
|
||||
ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED;
|
||||
}
|
||||
}
|
||||
|
||||
struct lwm2m_output_context {
|
||||
const struct lwm2m_writer *writer;
|
||||
struct coap_packet *out_cpkt;
|
||||
|
|
|
@ -747,6 +747,8 @@ static int parse_path(const u8_t *buf, u16_t buflen,
|
|||
path->obj_inst_id = val;
|
||||
} else if (ret == 2) {
|
||||
path->res_id = val;
|
||||
} else if (ret == 3) {
|
||||
path->res_inst_id = val;
|
||||
}
|
||||
|
||||
ret++;
|
||||
|
@ -763,9 +765,10 @@ static int parse_path(const u8_t *buf, u16_t buflen,
|
|||
|
||||
int do_write_op_json(struct lwm2m_message *msg)
|
||||
{
|
||||
struct lwm2m_engine_obj_field *obj_field;
|
||||
struct lwm2m_engine_obj_field *obj_field = NULL;
|
||||
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
struct lwm2m_obj_path orig_path;
|
||||
struct json_in_formatter_data fd;
|
||||
int ret = 0, index;
|
||||
|
@ -881,11 +884,24 @@ int do_write_op_json(struct lwm2m_message *msg)
|
|||
ret = -ENOENT;
|
||||
break;
|
||||
}
|
||||
} else if (res) {
|
||||
|
||||
for (index = 0; index < res->res_inst_count; index++) {
|
||||
if (res->res_instances[index].res_inst_id ==
|
||||
msg->path.res_inst_id) {
|
||||
res_inst = &res->res_instances[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res_inst) {
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
}
|
||||
} else if (res && res_inst) {
|
||||
/* handle value assignment */
|
||||
ret = lwm2m_write_handler(obj_inst, res, obj_field,
|
||||
msg);
|
||||
if (orig_path.level == 3U && ret < 0) {
|
||||
ret = lwm2m_write_handler(obj_inst, res, res_inst,
|
||||
obj_field, msg);
|
||||
if (orig_path.level >= 3U && ret < 0) {
|
||||
/* return errors on a single write */
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -492,7 +492,7 @@ static size_t put_string(struct lwm2m_output_context *out,
|
|||
}
|
||||
|
||||
tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
|
||||
path->res_id, (u32_t)buflen);
|
||||
tlv_calc_id(fd->writer_flags, path), (u32_t)buflen);
|
||||
len = oma_tlv_put(&tlv, out, (u8_t *)buf, false);
|
||||
return len;
|
||||
}
|
||||
|
@ -807,7 +807,8 @@ static int do_write_op_tlv_dummy_read(struct lwm2m_message *msg)
|
|||
static int do_write_op_tlv_item(struct lwm2m_message *msg)
|
||||
{
|
||||
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
struct lwm2m_engine_obj_field *obj_field = NULL;
|
||||
u8_t created = 0U;
|
||||
int ret, i;
|
||||
|
@ -841,7 +842,17 @@ static int do_write_op_tlv_item(struct lwm2m_message *msg)
|
|||
}
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
if (res) {
|
||||
for (i = 0; i < res->res_inst_count; i++) {
|
||||
if (res->res_instances[i].res_inst_id ==
|
||||
msg->path.res_inst_id) {
|
||||
res_inst = &res->res_instances[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!res || !res_inst) {
|
||||
/* if OPTIONAL and BOOTSTRAP-WRITE or CREATE use ENOTSUP */
|
||||
if ((msg->ctx->bootstrap_mode ||
|
||||
msg->operation == LWM2M_OP_CREATE) &&
|
||||
|
@ -854,7 +865,7 @@ static int do_write_op_tlv_item(struct lwm2m_message *msg)
|
|||
goto error;
|
||||
}
|
||||
|
||||
ret = lwm2m_write_handler(obj_inst, res, obj_field, msg);
|
||||
ret = lwm2m_write_handler(obj_inst, res, res_inst, obj_field, msg);
|
||||
if (ret == -EACCES || ret == -ENOENT) {
|
||||
/* if read-only or non-existent data buffer move on */
|
||||
do_write_op_tlv_dummy_read(msg);
|
||||
|
|
|
@ -330,7 +330,8 @@ int do_write_op_plain_text(struct lwm2m_message *msg)
|
|||
{
|
||||
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||
struct lwm2m_engine_obj_field *obj_field;
|
||||
struct lwm2m_engine_res_inst *res = NULL;
|
||||
struct lwm2m_engine_res *res = NULL;
|
||||
struct lwm2m_engine_res_inst *res_inst = NULL;
|
||||
int ret, i;
|
||||
u8_t created = 0U;
|
||||
|
||||
|
@ -363,6 +364,21 @@ int do_write_op_plain_text(struct lwm2m_message *msg)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
msg->path.level = 3U;
|
||||
return lwm2m_write_handler(obj_inst, res, obj_field, msg);
|
||||
for (i = 0; i < res->res_inst_count; i++) {
|
||||
if (res->res_instances[i].res_inst_id ==
|
||||
msg->path.res_inst_id) {
|
||||
res_inst = &res->res_instances[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res_inst) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (msg->path.level < 3) {
|
||||
msg->path.level = 3U;
|
||||
}
|
||||
|
||||
return lwm2m_write_handler(obj_inst, res, res_inst, obj_field, msg);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue