diff --git a/doc/releases/release-notes-3.0.rst b/doc/releases/release-notes-3.0.rst index d02b4d16a93..55c93473baa 100644 --- a/doc/releases/release-notes-3.0.rst +++ b/doc/releases/release-notes-3.0.rst @@ -34,6 +34,8 @@ Changes in this release * :c:func:`uart_tx` * :c:func:`uart_rx_enable` +* Replaced custom LwM2M :c:struct:`float32_value` type with a native double type. + ========================== Removed APIs in this release diff --git a/include/net/lwm2m.h b/include/net/lwm2m.h index e874376372b..ccc8e42881b 100644 --- a/include/net/lwm2m.h +++ b/include/net/lwm2m.h @@ -357,27 +357,6 @@ struct coap_block_context *lwm2m_firmware_get_block_context(); #endif #endif -/** - * @brief Data structure used to represent the LwM2M float type: - * val1 is the whole number portion of the decimal - * val2 is the decimal portion *1000000 for 32bit, *1000000000 for 64bit - * Example: 123.456 == val1: 123, val2:456000 - * Example: 123.000456 = val1: 123, val2:456 - */ - -/** - * @brief Maximum precision value for 32-bit LwM2M float val2 - */ -#define LWM2M_FLOAT32_DEC_MAX 1000000 - -/** - * @brief 32-bit variant of the LwM2M float structure - */ -typedef struct float32_value { - int32_t val1; - int32_t val2; -} float32_value_t; - /** * @brief Maximum value for ObjLnk resource fields */ @@ -557,14 +536,14 @@ int lwm2m_engine_set_s64(char *pathstr, int64_t value); int lwm2m_engine_set_bool(char *pathstr, bool value); /** - * @brief Set resource (instance) value (32-bit float structure) + * @brief Set resource (instance) value (double) * * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)" - * @param[in] value 32-bit float value + * @param[in] value double value * * @return 0 for success or negative in case of error. */ -int lwm2m_engine_set_float32(char *pathstr, float32_value_t *value); +int lwm2m_engine_set_float(char *pathstr, double *value); /** * @brief Set resource (instance) value (ObjLnk) @@ -689,14 +668,14 @@ int lwm2m_engine_get_s64(char *pathstr, int64_t *value); int lwm2m_engine_get_bool(char *pathstr, bool *value); /** - * @brief Get resource (instance) value (32-bit float structure) + * @brief Get resource (instance) value (double) * * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)" - * @param[out] buf 32-bit float buffer to copy data into + * @param[out] buf double buffer to copy data into * * @return 0 for success or negative in case of error. */ -int lwm2m_engine_get_float32(char *pathstr, float32_value_t *buf); +int lwm2m_engine_get_float(char *pathstr, double *buf); /** * @brief Get resource (instance) value (ObjLnk) diff --git a/samples/net/lwm2m_client/boards/qemu_x86.conf b/samples/net/lwm2m_client/boards/qemu_x86.conf new file mode 100644 index 00000000000..c099c8e81df --- /dev/null +++ b/samples/net/lwm2m_client/boards/qemu_x86.conf @@ -0,0 +1 @@ +CONFIG_FPU=y diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index b98d522c7cd..a45d7bfe03c 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -190,7 +190,7 @@ static void *temperature_get_buf(uint16_t obj_inst_id, uint16_t res_id, uint16_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 }; + static double v = 25.5; const struct device *dev = NULL; #if defined(CONFIG_FXOS8700_TEMP) @@ -198,17 +198,21 @@ static void *temperature_get_buf(uint16_t obj_inst_id, uint16_t res_id, #endif if (dev != NULL) { + struct sensor_value val; + if (sensor_sample_fetch(dev)) { LOG_ERR("temperature data update failed"); } - sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, - (struct sensor_value *) &v); - LOG_DBG("LWM2M temperature set to %d.%d", v.val1, v.val2); + sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &val); + + v = sensor_value_to_double(&val); + + LOG_DBG("LWM2M temperature set to %f", v); } /* echo the value back through the engine to update min/max values */ - lwm2m_engine_set_float32("3303/0/5700", &v); + lwm2m_engine_set_float("3303/0/5700", &v); *data_len = sizeof(v); return &v; } diff --git a/subsys/net/lib/lwm2m/ipso_accelerometer.c b/subsys/net/lib/lwm2m/ipso_accelerometer.c index bd509cdf4d0..e7326300a67 100644 --- a/subsys/net/lib/lwm2m/ipso_accelerometer.c +++ b/subsys/net/lib/lwm2m/ipso_accelerometer.c @@ -42,11 +42,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* resource state */ struct ipso_accel_data { - float32_value_t x_value; - float32_value_t y_value; - float32_value_t z_value; - float32_value_t min_range; - float32_value_t max_range; + double x_value; + double y_value; + double z_value; + double min_range; + double max_range; }; static struct ipso_accel_data accel_data[MAX_INSTANCE_COUNT]; diff --git a/subsys/net/lib/lwm2m/ipso_buzzer.c b/subsys/net/lib/lwm2m/ipso_buzzer.c index 21026bb3df7..1985a179f7a 100644 --- a/subsys/net/lib/lwm2m/ipso_buzzer.c +++ b/subsys/net/lib/lwm2m/ipso_buzzer.c @@ -43,9 +43,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* resource state */ struct ipso_buzzer_data { - float32_value_t level; - float32_value_t delay_duration; - float32_value_t min_off_time; + double level; + double delay_duration; + double min_off_time; uint64_t trigger_offset; @@ -81,14 +81,6 @@ static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][BUZZER_MAX_ID]; static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT]; -static int float2ms(float32_value_t *f, uint32_t *ms) -{ - *ms = f->val1 * MSEC_PER_SEC; - *ms += f->val2 / (LWM2M_FLOAT32_DEC_MAX / MSEC_PER_SEC); - - return 0; -} - static int get_buzzer_index(uint16_t obj_inst_id) { int i, ret = -ENOENT; @@ -116,7 +108,7 @@ static int start_buzzer(struct ipso_buzzer_data *buzzer) } /* check min off time from last trigger_offset */ - float2ms(&buzzer->min_off_time, &temp); + temp = (uint32_t)(buzzer->min_off_time * MSEC_PER_SEC); if (k_uptime_get() < buzzer->trigger_offset + temp) { return -EINVAL; } @@ -128,7 +120,7 @@ static int start_buzzer(struct ipso_buzzer_data *buzzer) buzzer->obj_inst_id, DIGITAL_INPUT_STATE_RID); lwm2m_engine_set_bool(path, true); - float2ms(&buzzer->delay_duration, &temp); + temp = (uint32_t)(buzzer->delay_duration * MSEC_PER_SEC); k_work_reschedule(&buzzer->buzzer_work, K_MSEC(temp)); return 0; @@ -210,8 +202,8 @@ static struct lwm2m_engine_obj_inst *buzzer_create(uint16_t obj_inst_id) /* Set default values */ (void)memset(&buzzer_data[avail], 0, sizeof(buzzer_data[avail])); k_work_init_delayable(&buzzer_data[avail].buzzer_work, buzzer_work_cb); - buzzer_data[avail].level.val1 = 50; /* 50% */ - buzzer_data[avail].delay_duration.val1 = 1; /* 1 seconds */ + buzzer_data[avail].level = 50; /* 50% */ + buzzer_data[avail].delay_duration = 1; /* 1 seconds */ buzzer_data[avail].obj_inst_id = obj_inst_id; (void)memset(res[avail], 0, diff --git a/subsys/net/lib/lwm2m/ipso_generic_sensor.c b/subsys/net/lib/lwm2m/ipso_generic_sensor.c index 96cd6fae30c..f5dd98fa822 100644 --- a/subsys/net/lib/lwm2m/ipso_generic_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_generic_sensor.c @@ -56,12 +56,12 @@ BUILD_ASSERT(SENSOR_TYPE_STR_MAX_SIZE >= #define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1) /* resource state variables */ -static float32_value_t sensor_value[MAX_INSTANCE_COUNT]; +static double sensor_value[MAX_INSTANCE_COUNT]; static char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE]; -static float32_value_t min_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t min_range_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_range_value[MAX_INSTANCE_COUNT]; +static double min_measured_value[MAX_INSTANCE_COUNT]; +static double max_measured_value[MAX_INSTANCE_COUNT]; +static double min_range_value[MAX_INSTANCE_COUNT]; +static double max_range_value[MAX_INSTANCE_COUNT]; static char app_type[MAX_INSTANCE_COUNT][APP_TYPE_STR_MAX_SIZE]; static char sensor_type[MAX_INSTANCE_COUNT][SENSOR_TYPE_STR_MAX_SIZE]; @@ -91,15 +91,13 @@ static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT] static void update_min_measured(uint16_t obj_inst_id, int index) { - min_measured_value[index].val1 = sensor_value[index].val1; - min_measured_value[index].val2 = sensor_value[index].val2; + min_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID); } static void update_max_measured(uint16_t obj_inst_id, int index) { - max_measured_value[index].val1 = sensor_value[index].val1; - max_measured_value[index].val2 = sensor_value[index].val2; + max_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MAX_MEASURED_VALUE_RID); } @@ -126,35 +124,15 @@ static int sensor_value_write_cb(uint16_t obj_inst_id, uint16_t res_id, size_t total_size) { int i; - bool update_min = false; - bool update_max = false; for (i = 0; i < MAX_INSTANCE_COUNT; i++) { if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { /* update min / max */ - if (sensor_value[i].val1 < min_measured_value[i].val1) { - update_min = true; - } else if (sensor_value[i].val1 == - min_measured_value[i].val1 && - sensor_value[i].val2 < - min_measured_value[i].val2) { - update_min = true; - } - - if (sensor_value[i].val1 > max_measured_value[i].val1) { - update_max = true; - } else if (sensor_value[i].val1 == - max_measured_value[i].val1 && - sensor_value[i].val2 > - max_measured_value[i].val2) { - update_max = true; - } - - if (update_min) { + if (sensor_value[i] < min_measured_value[i]) { update_min_measured(obj_inst_id, i); } - if (update_max) { + if (sensor_value[i] > max_measured_value[i]) { update_max_measured(obj_inst_id, i); } } @@ -190,17 +168,12 @@ static struct lwm2m_engine_obj_inst *generic_sensor_create(uint16_t obj_inst_id) } /* Set default values */ - sensor_value[index].val1 = 0; - sensor_value[index].val2 = 0; + sensor_value[index] = 0; units[index][0] = '\0'; - min_measured_value[index].val1 = INT32_MAX; - min_measured_value[index].val2 = 0; - max_measured_value[index].val1 = -INT32_MAX; - max_measured_value[index].val2 = 0; - min_range_value[index].val1 = 0; - min_range_value[index].val2 = 0; - max_range_value[index].val1 = 0; - max_range_value[index].val2 = 0; + min_measured_value[index] = INT32_MAX; + max_measured_value[index] = -INT32_MAX; + min_range_value[index] = 0; + max_range_value[index] = 0; app_type[index][0] = '\0'; strncpy(sensor_type[index], CONFIG_LWM2M_IPSO_GENERIC_SENSOR_TYPE, SENSOR_TYPE_STR_MAX_SIZE); diff --git a/subsys/net/lib/lwm2m/ipso_humidity_sensor.c b/subsys/net/lib/lwm2m/ipso_humidity_sensor.c index 91a81500735..5023bf7dcb8 100644 --- a/subsys/net/lib/lwm2m/ipso_humidity_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_humidity_sensor.c @@ -45,12 +45,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1) /* resource state variables */ -static float32_value_t sensor_value[MAX_INSTANCE_COUNT]; +static double sensor_value[MAX_INSTANCE_COUNT]; static char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE]; -static float32_value_t min_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t min_range_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_range_value[MAX_INSTANCE_COUNT]; +static double min_measured_value[MAX_INSTANCE_COUNT]; +static double max_measured_value[MAX_INSTANCE_COUNT]; +static double min_range_value[MAX_INSTANCE_COUNT]; +static double max_range_value[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_obj sensor; static struct lwm2m_engine_obj_field fields[] = { @@ -77,15 +77,13 @@ static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT] static void update_min_measured(uint16_t obj_inst_id, int index) { - min_measured_value[index].val1 = sensor_value[index].val1; - min_measured_value[index].val2 = sensor_value[index].val2; + min_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID); } static void update_max_measured(uint16_t obj_inst_id, int index) { - max_measured_value[index].val1 = sensor_value[index].val1; - max_measured_value[index].val2 = sensor_value[index].val2; + max_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MAX_MEASURED_VALUE_RID); } @@ -112,35 +110,15 @@ static int sensor_value_write_cb(uint16_t obj_inst_id, uint16_t res_id, size_t total_size) { int i; - bool update_min = false; - bool update_max = false; for (i = 0; i < MAX_INSTANCE_COUNT; i++) { if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { /* update min / max */ - if (sensor_value[i].val1 < min_measured_value[i].val1) { - update_min = true; - } else if (sensor_value[i].val1 == - min_measured_value[i].val1 && - sensor_value[i].val2 < - min_measured_value[i].val2) { - update_min = true; - } - - if (sensor_value[i].val1 > max_measured_value[i].val1) { - update_max = true; - } else if (sensor_value[i].val1 == - max_measured_value[i].val1 && - sensor_value[i].val2 > - max_measured_value[i].val2) { - update_max = true; - } - - if (update_min) { + if (sensor_value[i] < min_measured_value[i]) { update_min_measured(obj_inst_id, i); } - if (update_max) { + if (sensor_value[i] > max_measured_value[i]) { update_max_measured(obj_inst_id, i); } } @@ -177,17 +155,12 @@ humidity_sensor_create(uint16_t obj_inst_id) } /* Set default values */ - sensor_value[index].val1 = 0; - sensor_value[index].val2 = 0; + sensor_value[index] = 0; units[index][0] = '\0'; - min_measured_value[index].val1 = INT32_MAX; - min_measured_value[index].val2 = 0; - max_measured_value[index].val1 = -INT32_MAX; - max_measured_value[index].val2 = 0; - min_range_value[index].val1 = 0; - min_range_value[index].val2 = 0; - max_range_value[index].val1 = 0; - max_range_value[index].val2 = 0; + min_measured_value[index] = INT32_MAX; + max_measured_value[index] = -INT32_MAX; + min_range_value[index] = 0; + max_range_value[index] = 0; (void)memset(res[index], 0, sizeof(res[index][0]) * ARRAY_SIZE(res[index])); diff --git a/subsys/net/lib/lwm2m/ipso_light_control.c b/subsys/net/lib/lwm2m/ipso_light_control.c index 3a76b425a97..48d5992fa13 100644 --- a/subsys/net/lib/lwm2m/ipso_light_control.c +++ b/subsys/net/lib/lwm2m/ipso_light_control.c @@ -45,8 +45,8 @@ static bool on_off_value[MAX_INSTANCE_COUNT]; static uint8_t dimmer_value[MAX_INSTANCE_COUNT]; static int32_t on_time_value[MAX_INSTANCE_COUNT]; static uint32_t on_time_offset[MAX_INSTANCE_COUNT]; -static float32_value_t cumulative_active_value[MAX_INSTANCE_COUNT]; -static float32_value_t power_factor_value[MAX_INSTANCE_COUNT]; +static double cumulative_active_value[MAX_INSTANCE_COUNT]; +static double power_factor_value[MAX_INSTANCE_COUNT]; static char colour[MAX_INSTANCE_COUNT][LIGHT_STRING_LONG]; static char units[MAX_INSTANCE_COUNT][LIGHT_STRING_SHORT]; @@ -148,10 +148,8 @@ static struct lwm2m_engine_obj_inst *light_control_create(uint16_t obj_inst_id) dimmer_value[avail] = 0U; on_time_value[avail] = 0; on_time_offset[avail] = 0U; - cumulative_active_value[avail].val1 = 0; - cumulative_active_value[avail].val2 = 0; - power_factor_value[avail].val1 = 0; - power_factor_value[avail].val2 = 0; + cumulative_active_value[avail] = 0; + power_factor_value[avail] = 0; colour[avail][0] = '\0'; units[avail][0] = '\0'; diff --git a/subsys/net/lib/lwm2m/ipso_pressure_sensor.c b/subsys/net/lib/lwm2m/ipso_pressure_sensor.c index 72b115b0b8a..de7a7769bd5 100644 --- a/subsys/net/lib/lwm2m/ipso_pressure_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_pressure_sensor.c @@ -45,12 +45,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1) /* resource state variables */ -static float32_value_t sensor_value[MAX_INSTANCE_COUNT]; +static double sensor_value[MAX_INSTANCE_COUNT]; static char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE]; -static float32_value_t min_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t min_range_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_range_value[MAX_INSTANCE_COUNT]; +static double min_measured_value[MAX_INSTANCE_COUNT]; +static double max_measured_value[MAX_INSTANCE_COUNT]; +static double min_range_value[MAX_INSTANCE_COUNT]; +static double max_range_value[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_obj sensor; static struct lwm2m_engine_obj_field fields[] = { @@ -78,15 +78,13 @@ static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT] static void update_min_measured(uint16_t obj_inst_id, int index) { - min_measured_value[index].val1 = sensor_value[index].val1; - min_measured_value[index].val2 = sensor_value[index].val2; + min_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID); } static void update_max_measured(uint16_t obj_inst_id, int index) { - max_measured_value[index].val1 = sensor_value[index].val1; - max_measured_value[index].val2 = sensor_value[index].val2; + max_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MAX_MEASURED_VALUE_RID); } @@ -113,35 +111,15 @@ static int sensor_value_write_cb(uint16_t obj_inst_id, uint16_t res_id, size_t total_size) { int i; - bool update_min = false; - bool update_max = false; for (i = 0; i < MAX_INSTANCE_COUNT; i++) { if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { /* update min / max */ - if (sensor_value[i].val1 < min_measured_value[i].val1) { - update_min = true; - } else if (sensor_value[i].val1 == - min_measured_value[i].val1 && - sensor_value[i].val2 < - min_measured_value[i].val2) { - update_min = true; - } - - if (sensor_value[i].val1 > max_measured_value[i].val1) { - update_max = true; - } else if (sensor_value[i].val1 == - max_measured_value[i].val1 && - sensor_value[i].val2 > - max_measured_value[i].val2) { - update_max = true; - } - - if (update_min) { + if (sensor_value[i] < min_measured_value[i]) { update_min_measured(obj_inst_id, i); } - if (update_max) { + if (sensor_value[i] > max_measured_value[i]) { update_max_measured(obj_inst_id, i); } } @@ -178,17 +156,12 @@ pressure_sensor_create(uint16_t obj_inst_id) } /* Set default values */ - sensor_value[index].val1 = 0; - sensor_value[index].val2 = 0; + sensor_value[index] = 0; units[index][0] = '\0'; - min_measured_value[index].val1 = INT32_MAX; - min_measured_value[index].val2 = 0; - max_measured_value[index].val1 = -INT32_MAX; - max_measured_value[index].val2 = 0; - min_range_value[index].val1 = 0; - min_range_value[index].val2 = 0; - max_range_value[index].val1 = 0; - max_range_value[index].val2 = 0; + min_measured_value[index] = INT32_MAX; + max_measured_value[index] = -INT32_MAX; + min_range_value[index] = 0; + max_range_value[index] = 0; (void)memset(res[index], 0, sizeof(res[index][0]) * ARRAY_SIZE(res[index])); diff --git a/subsys/net/lib/lwm2m/ipso_temp_sensor.c b/subsys/net/lib/lwm2m/ipso_temp_sensor.c index 7bcb65e91bf..7fff54af1b5 100644 --- a/subsys/net/lib/lwm2m/ipso_temp_sensor.c +++ b/subsys/net/lib/lwm2m/ipso_temp_sensor.c @@ -46,12 +46,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define RESOURCE_INSTANCE_COUNT (TEMP_MAX_ID - 1) /* resource state variables */ -static float32_value_t sensor_value[MAX_INSTANCE_COUNT]; +static double sensor_value[MAX_INSTANCE_COUNT]; static char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE]; -static float32_value_t min_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_measured_value[MAX_INSTANCE_COUNT]; -static float32_value_t min_range_value[MAX_INSTANCE_COUNT]; -static float32_value_t max_range_value[MAX_INSTANCE_COUNT]; +static double min_measured_value[MAX_INSTANCE_COUNT]; +static double max_measured_value[MAX_INSTANCE_COUNT]; +static double min_range_value[MAX_INSTANCE_COUNT]; +static double max_range_value[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_obj temp_sensor; static struct lwm2m_engine_obj_field fields[] = { @@ -78,16 +78,14 @@ static struct lwm2m_engine_res_inst static void update_min_measured(uint16_t obj_inst_id, int index) { - min_measured_value[index].val1 = sensor_value[index].val1; - min_measured_value[index].val2 = sensor_value[index].val2; + min_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_TEMP_SENSOR_ID, obj_inst_id, MIN_MEASURED_VALUE_RID); } static void update_max_measured(uint16_t obj_inst_id, int index) { - max_measured_value[index].val1 = sensor_value[index].val1; - max_measured_value[index].val2 = sensor_value[index].val2; + max_measured_value[index] = sensor_value[index]; NOTIFY_OBSERVER(IPSO_OBJECT_TEMP_SENSOR_ID, obj_inst_id, MAX_MEASURED_VALUE_RID); } @@ -115,35 +113,15 @@ static int sensor_value_write_cb(uint16_t obj_inst_id, bool last_block, size_t total_size) { int i; - bool update_min = false; - bool update_max = false; for (i = 0; i < MAX_INSTANCE_COUNT; i++) { if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { /* update min / max */ - if (sensor_value[i].val1 < min_measured_value[i].val1) { - update_min = true; - } else if (sensor_value[i].val1 == - min_measured_value[i].val1 && - sensor_value[i].val2 < - min_measured_value[i].val2) { - update_min = true; - } - - if (sensor_value[i].val1 > max_measured_value[i].val1) { - update_max = true; - } else if (sensor_value[i].val1 == - max_measured_value[i].val1 && - sensor_value[i].val2 > - max_measured_value[i].val2) { - update_max = true; - } - - if (update_min) { + if (sensor_value[i] < min_measured_value[i]) { update_min_measured(obj_inst_id, i); } - if (update_max) { + if (sensor_value[i] > max_measured_value[i]) { update_max_measured(obj_inst_id, i); } } @@ -178,17 +156,12 @@ static struct lwm2m_engine_obj_inst *temp_sensor_create(uint16_t obj_inst_id) } /* Set default values */ - sensor_value[index].val1 = 0; - sensor_value[index].val2 = 0; + sensor_value[index] = 0; units[index][0] = '\0'; - min_measured_value[index].val1 = INT32_MAX; - min_measured_value[index].val2 = 0; - max_measured_value[index].val1 = -INT32_MAX; - max_measured_value[index].val2 = 0; - min_range_value[index].val1 = 0; - min_range_value[index].val2 = 0; - max_range_value[index].val1 = 0; - max_range_value[index].val2 = 0; + min_measured_value[index] = INT32_MAX; + max_measured_value[index] = -INT32_MAX; + min_range_value[index] = 0; + max_range_value[index] = 0; (void)memset(res[index], 0, sizeof(res[index][0]) * ARRAY_SIZE(res[index])); diff --git a/subsys/net/lib/lwm2m/ipso_timer.c b/subsys/net/lib/lwm2m/ipso_timer.c index d62f2707340..63430240cf9 100644 --- a/subsys/net/lib/lwm2m/ipso_timer.c +++ b/subsys/net/lib/lwm2m/ipso_timer.c @@ -46,10 +46,10 @@ enum ipso_timer_mode { /* resource state */ struct ipso_timer_data { - float32_value_t delay_duration; - float32_value_t remaining_time; - float32_value_t min_off_time; - float32_value_t cumulative_time; + double delay_duration; + double remaining_time; + double min_off_time; + double cumulative_time; uint64_t trigger_offset; uint32_t trigger_counter; @@ -85,22 +85,6 @@ 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(uint32_t ms, float32_value_t *f) -{ - f->val1 = ms / MSEC_PER_SEC; - f->val2 = (ms % MSEC_PER_SEC) * (LWM2M_FLOAT32_DEC_MAX / MSEC_PER_SEC); - - return 0; -} - -static int float2ms(float32_value_t *f, uint32_t *ms) -{ - *ms = f->val1 * MSEC_PER_SEC; - *ms += f->val2 / (LWM2M_FLOAT32_DEC_MAX / MSEC_PER_SEC); - - return 0; -} - static int get_timer_index(uint16_t obj_inst_id) { int i, ret = -ENOENT; @@ -129,7 +113,7 @@ static int start_timer(struct ipso_timer_data *timer) } /* check min off time from last trigger_offset */ - float2ms(&timer->min_off_time, &temp); + temp = timer->min_off_time * MSEC_PER_SEC; if (k_uptime_get() < timer->trigger_offset + temp) { return -EINVAL; } @@ -143,7 +127,7 @@ static int start_timer(struct ipso_timer_data *timer) timer->obj_inst_id, DIGITAL_STATE_RID); lwm2m_engine_set_bool(path, true); - float2ms(&timer->delay_duration, &temp); + temp = timer->delay_duration * MSEC_PER_SEC; k_work_reschedule(&timer->timer_work, K_MSEC(temp)); return 0; @@ -183,12 +167,11 @@ static void *remaining_time_read_cb(uint16_t obj_inst_id, } if (timer_data[i].active) { - float2ms(&timer_data[i].delay_duration, &temp); + temp = timer_data[i].delay_duration * MSEC_PER_SEC; temp -= (k_uptime_get() - timer_data[i].trigger_offset); - ms2float(temp, &timer_data[i].remaining_time); + timer_data[i].remaining_time = (double)temp / MSEC_PER_SEC; } else { - timer_data[i].remaining_time.val1 = 0; - timer_data[i].remaining_time.val2 = 0; + timer_data[i].remaining_time = 0; } *data_len = sizeof(timer_data[i].remaining_time); @@ -212,7 +195,7 @@ static void *cumulative_time_read_cb(uint16_t obj_inst_id, temp += k_uptime_get() - timer_data[i].trigger_offset; } - ms2float(temp, &timer_data[i].cumulative_time); + timer_data[i].cumulative_time = (double)temp / MSEC_PER_SEC; *data_len = sizeof(timer_data[i].cumulative_time); return &timer_data[i].cumulative_time; @@ -318,7 +301,7 @@ static struct lwm2m_engine_obj_inst *timer_create(uint16_t obj_inst_id) /* Set default values */ (void)memset(&timer_data[avail], 0, sizeof(timer_data[avail])); k_work_init_delayable(&timer_data[avail].timer_work, timer_work_cb); - timer_data[avail].delay_duration.val1 = 5; /* 5 seconds */ + timer_data[avail].delay_duration = 5; /* 5 seconds */ timer_data[avail].enabled = true; timer_data[avail].timer_mode = TIMER_MODE_ONE_SHOT; timer_data[avail].obj_inst_id = obj_inst_id; diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 80e9e29373c..3fa506c2d57 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -86,9 +86,9 @@ struct observe_node { struct notification_attrs { /* use to determine which value is set */ - float32_value_t gt; - float32_value_t lt; - float32_value_t st; + double gt; + double lt; + double st; int32_t pmin; int32_t pmax; uint8_t flags; @@ -1596,10 +1596,7 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len) break; case LWM2M_RES_TYPE_FLOAT: - ((float32_value_t *)data_ptr)->val1 = - ((float32_value_t *)value)->val1; - ((float32_value_t *)data_ptr)->val2 = - ((float32_value_t *)value)->val2; + *(double *)data_ptr = *(double *)value; break; case LWM2M_RES_TYPE_OBJLNK: @@ -1685,9 +1682,9 @@ int lwm2m_engine_set_bool(char *pathstr, bool value) return lwm2m_engine_set(pathstr, &temp, 1); } -int lwm2m_engine_set_float32(char *pathstr, float32_value_t *value) +int lwm2m_engine_set_float(char *pathstr, double *value) { - return lwm2m_engine_set(pathstr, value, sizeof(float32_value_t)); + return lwm2m_engine_set(pathstr, value, sizeof(double)); } int lwm2m_engine_set_objlnk(char *pathstr, struct lwm2m_objlnk *value) @@ -1830,10 +1827,7 @@ static int lwm2m_engine_get(char *pathstr, void *buf, uint16_t buflen) break; case LWM2M_RES_TYPE_FLOAT: - ((float32_value_t *)buf)->val1 = - ((float32_value_t *)data_ptr)->val1; - ((float32_value_t *)buf)->val2 = - ((float32_value_t *)data_ptr)->val2; + *(double *)buf = *(double *)data_ptr; break; case LWM2M_RES_TYPE_OBJLNK: @@ -1915,9 +1909,9 @@ int lwm2m_engine_get_bool(char *pathstr, bool *value) return ret; } -int lwm2m_engine_get_float32(char *pathstr, float32_value_t *buf) +int lwm2m_engine_get_float(char *pathstr, double *buf) { - return lwm2m_engine_get(pathstr, buf, sizeof(float32_value_t)); + return lwm2m_engine_get(pathstr, buf, sizeof(double)); } int lwm2m_engine_get_objlnk(char *pathstr, struct lwm2m_objlnk *buf) @@ -2325,8 +2319,8 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst, break; case LWM2M_RES_TYPE_FLOAT: - engine_put_float32fix(&msg->out, &msg->path, - (float32_value_t *)data_ptr); + engine_put_float(&msg->out, &msg->path, + (double *)data_ptr); break; case LWM2M_RES_TYPE_OBJLNK: @@ -2594,9 +2588,8 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst, break; case LWM2M_RES_TYPE_FLOAT: - engine_get_float32fix(&msg->in, - (float32_value_t *)write_buf); - len = sizeof(float32_value_t); + engine_get_float(&msg->in, (double *)write_buf); + len = sizeof(double); break; case LWM2M_RES_TYPE_OBJLNK: @@ -2725,7 +2718,7 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, /* loop through options to parse attribute */ for (i = 0; i < nr_opt; i++) { int limit = MIN(options[i].len, 5), plen = 0, vlen; - float32_value_t val = { 0 }; + struct lwm2m_attr val = { 0 }; type = 0U; /* search for '=' */ @@ -2758,7 +2751,7 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, (void)memset(nattr_ptrs[type], 0, type <= LWM2M_ATTR_PMAX ? sizeof(int32_t) : - sizeof(float32_value_t)); + sizeof(double)); continue; } @@ -2785,10 +2778,10 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, ret = -EINVAL; } - val.val1 = v; + val.int_val = v; } else { /* gt/lt/st: type float */ - ret = lwm2m_atof32(opt_buf, &val); + ret = lwm2m_atof(opt_buf, &val.float_val); } if (ret < 0) { @@ -2799,9 +2792,10 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, } if (type <= LWM2M_ATTR_PMAX) { - *(int32_t *)nattr_ptrs[type] = val.val1; + *(int32_t *)nattr_ptrs[type] = val.int_val; } else { - memcpy(nattr_ptrs[type], &val, sizeof(float32_value_t)); + memcpy(nattr_ptrs[type], &val.float_val, + sizeof(val.float_val)); } nattrs.flags |= BIT(type); @@ -2814,18 +2808,13 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, } if (nattrs.flags & (BIT(LWM2M_ATTR_LT) | BIT(LWM2M_ATTR_GT))) { - if (!((nattrs.lt.val1 < nattrs.gt.val1) || - (nattrs.lt.val2 < nattrs.gt.val2))) { + if (nattrs.lt > nattrs.gt) { LOG_DBG("lt > gt"); return -EEXIST; } if (nattrs.flags & BIT(LWM2M_ATTR_STEP)) { - int32_t st1 = nattrs.st.val1 * 2 + - nattrs.st.val2 * 2 / 1000000; - int32_t st2 = nattrs.st.val2 * 2 % 1000000; - if (!(((nattrs.lt.val1 + st1) < nattrs.gt.val1) || - ((nattrs.lt.val2 + st2) < nattrs.gt.val2))) { + if (nattrs.lt + 2 * nattrs.st > nattrs.gt) { LOG_DBG("lt + 2*st > gt"); return -EEXIST; } @@ -2862,19 +2851,19 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, attr->int_val = *(int32_t *)nattr_ptrs[type]; update_observe_node = true; + + LOG_DBG("Update %s to %d", log_strdup(LWM2M_ATTR_STR[type]), + attr->int_val); } else { - if (!memcmp(&attr->float_val, nattr_ptrs[type], - sizeof(float32_value_t))) { + if (attr->float_val == *(double *)nattr_ptrs[type]) { continue; } - memcpy(&attr->float_val, nattr_ptrs[type], - sizeof(float32_value_t)); - } + attr->float_val = *(double *)nattr_ptrs[type]; - LOG_DBG("Update %s to %d.%06d", - log_strdup(LWM2M_ATTR_STR[type]), - attr->float_val.val1, attr->float_val.val2); + LOG_DBG("Update %s to %f", log_strdup(LWM2M_ATTR_STR[type]), + attr->float_val); + } } /* add attribute to obj/obj_inst/res */ @@ -2901,14 +2890,17 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj, if (type <= LWM2M_ATTR_PMAX) { attr->int_val = *(int32_t *)nattr_ptrs[type]; update_observe_node = true; + + LOG_DBG("Add %s to %d", log_strdup(LWM2M_ATTR_STR[type]), + attr->int_val); } else { - memcpy(&attr->float_val, nattr_ptrs[type], - sizeof(float32_value_t)); + attr->float_val = *(double *)nattr_ptrs[type]; + + LOG_DBG("Add %s to %f", log_strdup(LWM2M_ATTR_STR[type]), + attr->float_val); } nattrs.flags &= ~BIT(type); - LOG_DBG("Add %s to %d.%06d", log_strdup(LWM2M_ATTR_STR[type]), - attr->float_val.val1, attr->float_val.val2); } /* check only pmin/pmax */ diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_location.c b/subsys/net/lib/lwm2m/lwm2m_obj_location.c index c682f28386e..62b1323c2d1 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_location.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_location.c @@ -37,11 +37,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define RESOURCE_INSTANCE_COUNT (LOCATION_MAX_ID) /* resource state */ -static float32_value_t latitude; -static float32_value_t longitude; -static float32_value_t altitude; -static float32_value_t radius; -static float32_value_t speed; +static double latitude; +static double longitude; +static double altitude; +static double radius; +static double speed; static int32_t timestamp; static struct lwm2m_engine_obj location; diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index 19600483435..75aeca41927 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -347,7 +347,7 @@ struct lwm2m_attr { /* values */ union { - float32_value_t float_val; + double float_val; int32_t int_val; }; @@ -515,9 +515,9 @@ struct lwm2m_writer { size_t (*put_string)(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, char *buf, size_t buflen); - size_t (*put_float32fix)(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, - float32_value_t *value); + size_t (*put_float)(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, + double *value); size_t (*put_bool)(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, bool value); @@ -538,8 +538,8 @@ struct lwm2m_reader { int64_t *value); size_t (*get_string)(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen); - size_t (*get_float32fix)(struct lwm2m_input_context *in, - float32_value_t *value); + size_t (*get_float)(struct lwm2m_input_context *in, + double *value); size_t (*get_bool)(struct lwm2m_input_context *in, bool *value); size_t (*get_opaque)(struct lwm2m_input_context *in, @@ -703,11 +703,11 @@ static inline size_t engine_put_string(struct lwm2m_output_context *out, return out->writer->put_string(out, path, buf, buflen); } -static inline size_t engine_put_float32fix(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, - float32_value_t *value) +static inline size_t engine_put_float(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, + double *value) { - return out->writer->put_float32fix(out, path, value); + return out->writer->put_float(out, path, value); } static inline size_t engine_put_bool(struct lwm2m_output_context *out, @@ -763,10 +763,10 @@ static inline size_t engine_get_string(struct lwm2m_input_context *in, return in->reader->get_string(in, buf, buflen); } -static inline size_t engine_get_float32fix(struct lwm2m_input_context *in, - float32_value_t *value) +static inline size_t engine_get_float(struct lwm2m_input_context *in, + double *value) { - return in->reader->get_float32fix(in, value); + return in->reader->get_float(in, value); } static inline size_t engine_get_bool(struct lwm2m_input_context *in, diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_json.c b/subsys/net/lib/lwm2m/lwm2m_rw_json.c index 5f017ebb0de..7fa215fff9f 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_json.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_json.c @@ -491,14 +491,14 @@ static size_t put_string(struct lwm2m_output_context *out, return len; } -static size_t put_float32fix(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, - float32_value_t *value) +static size_t put_float(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, + double *value) { size_t len; len = put_json_prefix(out, path, "\"v\""); - len += plain_text_put_float32fix(out, path, value); + len += plain_text_put_float(out, path, value); len += put_json_postfix(out); return len; } @@ -612,8 +612,8 @@ static size_t get_string(struct lwm2m_input_context *in, return fd->value_len; } -static size_t get_float32fix(struct lwm2m_input_context *in, - float32_value_t *value) +static size_t get_float(struct lwm2m_input_context *in, + double *value) { struct json_in_formatter_data *fd; @@ -652,7 +652,7 @@ static size_t get_float32fix(struct lwm2m_input_context *in, buf[i] = '\0'; - if (lwm2m_atof32(buf, value) != 0) { + if (lwm2m_atof(buf, value) != 0) { LOG_ERR("Failed to parse float value"); } @@ -729,7 +729,7 @@ const struct lwm2m_writer json_writer = { .put_s32 = put_s32, .put_s64 = put_s64, .put_string = put_string, - .put_float32fix = put_float32fix, + .put_float = put_float, .put_bool = put_bool, .put_objlnk = put_objlnk, }; @@ -738,7 +738,7 @@ const struct lwm2m_reader json_reader = { .get_s32 = get_s32, .get_s64 = get_s64, .get_string = get_string, - .get_float32fix = get_float32fix, + .get_float = get_float, .get_bool = get_bool, .get_opaque = get_opaque, .get_objlnk = get_objlnk, diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c b/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c index 8f68f8b192b..caa086c3dc5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_link_format.c @@ -9,6 +9,7 @@ #include "lwm2m_engine.h" #include "lwm2m_rw_link_format.h" +#include "lwm2m_util.h" LOG_MODULE_REGISTER(net_lwm2m_link_format, CONFIG_LWM2M_LOG_LEVEL); @@ -158,9 +159,7 @@ static int put_corelink_attributes(struct lwm2m_output_context *out, uint16_t buflen) { struct lwm2m_attr *attr = NULL; - int used, base, ret; - uint8_t digit; - int32_t fraction; + int used, ret; int len = 0; while ((attr = lwm2m_engine_get_next_attr(ref, attr)) != NULL) { @@ -171,25 +170,22 @@ static int put_corelink_attributes(struct lwm2m_output_context *out, continue; } - /* Assuming integer will have float_val.val2 set as 0. */ - used = snprintk(buf, buflen, ";%s=%s%d%s", - name, - attr->float_val.val1 == 0 && - attr->float_val.val2 < 0 ? "-" : "", - attr->float_val.val1, - attr->float_val.val2 != 0 ? "." : ""); - if (used < 0 || used >= buflen) { - return -ENOMEM; + if (attr->type <= LWM2M_ATTR_PMAX) { + used = snprintk(buf, buflen, ";%s=%d", name, attr->int_val); + } else { + uint8_t float_buf[32]; + + used = lwm2m_ftoa(&attr->float_val, float_buf, + sizeof(float_buf), 4); + if (used < 0 || used >= sizeof(float_buf)) { + return -ENOMEM; + } + + used = snprintk(buf, buflen, ";%s=%s", name, float_buf); } - base = 100000; - fraction = attr->float_val.val2 < 0 ? - -attr->float_val.val2 : attr->float_val.val2; - while (fraction && used < buflen && base > 0) { - digit = fraction / base; - buf[used++] = '0' + digit; - fraction -= digit * base; - base /= 10; + if (used < 0 || used >= buflen) { + return -ENOMEM; } len += used; diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c b/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c index 2639dddc7cb..e6d6033a7f1 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c @@ -510,30 +510,30 @@ static size_t put_string(struct lwm2m_output_context *out, return len; } -static size_t put_float32fix(struct lwm2m_output_context *out, +static size_t put_float(struct lwm2m_output_context *out, struct lwm2m_obj_path *path, - float32_value_t *value) + double *value) { struct tlv_out_formatter_data *fd; size_t len; struct oma_tlv tlv; int ret; - uint8_t b32[4]; + uint8_t b64[8]; fd = engine_get_out_user_data(out); if (!fd) { return 0; } - ret = lwm2m_f32_to_b32(value, b32, sizeof(b32)); + ret = lwm2m_float_to_b64(value, b64, sizeof(b64)); if (ret < 0) { LOG_ERR("float32 conversion error: %d", ret); return 0; } tlv_setup(&tlv, tlv_calc_type(fd->writer_flags), - tlv_calc_id(fd->writer_flags, path), sizeof(b32)); - len = oma_tlv_put(&tlv, out, b32, false); + tlv_calc_id(fd->writer_flags, path), sizeof(b64)); + len = oma_tlv_put(&tlv, out, b64, false); return len; } @@ -647,8 +647,8 @@ static size_t get_string(struct lwm2m_input_context *in, } /* convert float to fixpoint */ -static size_t get_float32fix(struct lwm2m_input_context *in, - float32_value_t *value) +static size_t get_float(struct lwm2m_input_context *in, + double *value) { struct oma_tlv tlv; size_t size = oma_tlv_get(&tlv, in, false); @@ -679,9 +679,9 @@ static size_t get_float32fix(struct lwm2m_input_context *in, } if (tlv.length == 4U) { - ret = lwm2m_b32_to_f32(buf, 4, value); + ret = lwm2m_b32_to_float(buf, 4, value); } else { - ret = lwm2m_b64_to_f32(buf, 8, value); + ret = lwm2m_b64_to_float(buf, 8, value); } if (ret < 0) { @@ -752,7 +752,7 @@ const struct lwm2m_writer oma_tlv_writer = { .put_s32 = put_s32, .put_s64 = put_s64, .put_string = put_string, - .put_float32fix = put_float32fix, + .put_float = put_float, .put_bool = put_bool, .put_opaque = put_opaque, .put_objlnk = put_objlnk, @@ -762,7 +762,7 @@ const struct lwm2m_reader oma_tlv_reader = { .get_s32 = get_s32, .get_s64 = get_s64, .get_string = get_string, - .get_float32fix = get_float32fix, + .get_float = get_float, .get_bool = get_bool, .get_opaque = get_opaque, .get_objlnk = get_objlnk, diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c index b27ce429755..9e1f1e2169c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c @@ -74,7 +74,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_util.h" /* some temporary buffer space for format conversions */ -static char pt_buffer[42]; /* can handle float64 format */ +static char pt_buffer[42]; size_t plain_text_put_format(struct lwm2m_output_context *out, const char *format, ...) @@ -122,29 +122,22 @@ static size_t put_s64(struct lwm2m_output_context *out, return plain_text_put_format(out, "%lld", value); } -size_t plain_text_put_float32fix(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, - float32_value_t *value) +size_t plain_text_put_float(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, + double *value) { - size_t len; - char buf[sizeof("000000")]; + int len = lwm2m_ftoa(value, pt_buffer, sizeof(pt_buffer), 15); - /* value of 123 -> "000123" -- ignore sign */ - len = snprintk(buf, sizeof(buf), "%06d", abs(value->val2)); - if (len != 6U) { - strcpy(buf, "0"); - } else { - /* clear ending zeroes, but leave 1 if needed */ - while (len > 1U && buf[len - 1] == '0') { - buf[--len] = '\0'; - } + if (len < 0 || len >= sizeof(pt_buffer)) { + LOG_ERR("Failed to encode float value"); + return 0; } - return plain_text_put_format(out, "%s%d.%s", - /* handle negative val2 when val1 is 0 */ - (value->val1 == 0 && value->val2 < 0) ? - "-" : "", - value->val1, buf); + if (buf_append(CPKT_BUF_WRITE(out->out_cpkt), pt_buffer, len) < 0) { + return 0; + } + + return (size_t)len; } static size_t put_string(struct lwm2m_output_context *out, @@ -253,8 +246,8 @@ static size_t get_string(struct lwm2m_input_context *in, return (size_t)in_len; } -static size_t get_float32fix(struct lwm2m_input_context *in, - float32_value_t *value) +static size_t get_float(struct lwm2m_input_context *in, + double *value) { size_t i = 0, len = 0; bool has_dot = false; @@ -290,7 +283,7 @@ static size_t get_float32fix(struct lwm2m_input_context *in, buf[i] = '\0'; - if (lwm2m_atof32(buf, value) != 0) { + if (lwm2m_atof(buf, value) != 0) { LOG_ERR("Failed to parse float value"); } @@ -380,7 +373,7 @@ const struct lwm2m_writer plain_text_writer = { .put_s32 = put_s32, .put_s64 = put_s64, .put_string = put_string, - .put_float32fix = plain_text_put_float32fix, + .put_float = plain_text_put_float, .put_bool = put_bool, .put_objlnk = put_objlnk, }; @@ -389,7 +382,7 @@ const struct lwm2m_reader plain_text_reader = { .get_s32 = get_s32, .get_s64 = get_s64, .get_string = get_string, - .get_float32fix = get_float32fix, + .get_float = get_float, .get_bool = get_bool, .get_opaque = get_opaque, .get_objlnk = get_objlnk, diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.h b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.h index 6f1ec53886c..568e77cc556 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.h +++ b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.h @@ -52,9 +52,9 @@ extern const struct lwm2m_reader plain_text_reader; size_t plain_text_put_format(struct lwm2m_output_context *out, const char *format, ...); -size_t plain_text_put_float32fix(struct lwm2m_output_context *out, - struct lwm2m_obj_path *path, - float32_value_t *value); +size_t plain_text_put_float(struct lwm2m_output_context *out, + struct lwm2m_obj_path *path, + double *value); int do_read_op_plain_text(struct lwm2m_message *msg, int content_format); diff --git a/subsys/net/lib/lwm2m/lwm2m_util.c b/subsys/net/lib/lwm2m/lwm2m_util.c index 03f1158714b..198306cc283 100644 --- a/subsys/net/lib/lwm2m/lwm2m_util.c +++ b/subsys/net/lib/lwm2m/lwm2m_util.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include "lwm2m_util.h" @@ -12,10 +13,17 @@ #define SHIFT_LEFT(v, o, m) (((v) << (o)) & (m)) #define SHIFT_RIGHT(v, o, m) (((v) >> (o)) & (m)) -/* convert from float32 to binary32 */ -int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len) +#define PRECISION64_LEN 17U +#define PRECISION64 100000000000000000ULL + +#define PRECISION32 1000000000UL + +/* convert from float to binary32 */ +int lwm2m_float_to_b32(double *in, uint8_t *b32, size_t len) { int32_t e = -1, v, f = 0; + int32_t val1 = (int32_t)*in; + int32_t val2 = (*in - (int32_t)*in) * PRECISION32; int i; if (len != 4) { @@ -23,13 +31,13 @@ int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len) } /* handle zero value special case */ - if (f32->val1 == 0 && f32->val2 == 0) { + if (val1 == 0 && val2 == 0) { memset(b32, 0, len); return 0; } /* sign handled later */ - v = abs(f32->val1); + v = abs(val1); /* add whole value to fraction */ while (v > 0) { @@ -44,18 +52,18 @@ int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len) } /* sign handled later */ - v = abs(f32->val2); + v = abs(val2); /* add decimal to fraction */ i = e; while (v > 0 && i < 23) { v *= 2; - if (!f && e < 0 && v < LWM2M_FLOAT32_DEC_MAX) { + if (!f && e < 0 && v < PRECISION32) { /* handle -e */ e--; continue; - } else if (v >= LWM2M_FLOAT32_DEC_MAX) { - v -= LWM2M_FLOAT32_DEC_MAX; + } else if (v >= PRECISION32) { + v -= PRECISION32; f |= 1 << (22 - i); } @@ -72,10 +80,10 @@ int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len) memset(b32, 0, len); /* sign: bit 31 */ - if (f32->val1 == 0) { - b32[0] = f32->val2 < 0 ? 0x80 : 0; + if (val1 == 0) { + b32[0] = val2 < 0 ? 0x80 : 0; } else { - b32[0] = f32->val1 < 0 ? 0x80 : 0; + b32[0] = val1 < 0 ? 0x80 : 0; } /* exponent: bits 30-23 */ @@ -91,11 +99,13 @@ int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len) return 0; } -/* convert from float32 to binary64 */ -int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len) +/* convert from float to binary64 */ +int lwm2m_float_to_b64(double *in, uint8_t *b64, size_t len) { int64_t v, f = 0; int32_t e = -1; + int64_t val1 = (int64_t)*in; + int64_t val2 = (*in - (int64_t)*in) * PRECISION64; int i; if (len != 8) { @@ -103,13 +113,13 @@ int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len) } /* handle zero value special case */ - if (f32->val1 == 0 && f32->val2 == 0) { + if (val1 == 0 && val2 == 0) { memset(b64, 0, len); return 0; } /* sign handled later */ - v = abs(f32->val1); + v = llabs(val1); /* add whole value to fraction */ while (v > 0) { @@ -124,18 +134,18 @@ int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len) } /* sign handled later */ - v = abs(f32->val2); + v = llabs(val2); /* add decimal to fraction */ i = e; while (v > 0 && i < 52) { v *= 2; - if (!f && e < 0 && v < LWM2M_FLOAT32_DEC_MAX) { + if (!f && e < 0 && v < PRECISION64) { /* handle -e */ e--; continue; - } else if (v >= LWM2M_FLOAT32_DEC_MAX) { - v -= LWM2M_FLOAT32_DEC_MAX; + } else if (v >= PRECISION64) { + v -= PRECISION64; f |= (int64_t)1 << (51 - i); } @@ -152,10 +162,10 @@ int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len) memset(b64, 0, len); /* sign: bit 63 */ - if (f32->val1 == 0) { - b64[0] = f32->val2 < 0 ? 0x80 : 0; + if (val1 == 0) { + b64[0] = val2 < 0 ? 0x80 : 0; } else { - b64[0] = f32->val1 < 0 ? 0x80 : 0; + b64[0] = val1 < 0 ? 0x80 : 0; } /* exponent: bits 62-52 */ @@ -175,18 +185,19 @@ int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len) return 0; } -/* convert from binary32 to float32 */ -int lwm2m_b32_to_f32(uint8_t *b32, size_t len, float32_value_t *f32) +/* convert from binary32 to float */ +int lwm2m_b32_to_float(uint8_t *b32, size_t len, double *out) { int32_t f, k, i, e; bool sign = false; + int32_t val1, val2; if (len != 4) { return -EINVAL; } - f32->val1 = 0; - f32->val2 = 0; + val1 = 0; + val2 = 0; /* calc sign: bit 31 */ sign = SHIFT_RIGHT(b32[0], 7, 0x1); @@ -211,11 +222,11 @@ int lwm2m_b32_to_f32(uint8_t *b32, size_t len, float32_value_t *f32) e = 23; } - f32->val1 = (f >> (23 - e)) * (sign ? -1 : 1); + val1 = (f >> (23 - e)) * (sign ? -1 : 1); } /* calculate the rest of the decimal */ - k = LWM2M_FLOAT32_DEC_MAX; + k = PRECISION32; /* account for -e */ while (e < -1) { @@ -226,27 +237,34 @@ int lwm2m_b32_to_f32(uint8_t *b32, size_t len, float32_value_t *f32) for (i = 22 - e; i >= 0; i--) { k /= 2; if (f & (1 << i)) { - f32->val2 += k; + val2 += k; } } + if (sign) { + *out = (double)val1 - (double)val2 / PRECISION32; + } else { + *out = (double)val1 + (double)val2 / PRECISION32; + } + return 0; } -/* convert from binary64 to float32 */ -int lwm2m_b64_to_f32(uint8_t *b64, size_t len, float32_value_t *f32) +/* convert from binary64 to float */ +int lwm2m_b64_to_float(uint8_t *b64, size_t len, double *out) { int64_t f, k; int i, e; bool sign = false; + int64_t val1, val2; if (len != 8) { return -EINVAL; } - f32->val1 = 0LL; - f32->val2 = 0LL; + val1 = 0LL; + val2 = 0LL; /* calc sign: bit 63 */ sign = SHIFT_RIGHT(b64[0], 7, 0x1); @@ -275,11 +293,11 @@ int lwm2m_b64_to_f32(uint8_t *b64, size_t len, float32_value_t *f32) e = 52; } - f32->val1 = (f >> (52 - e)) * (sign ? -1 : 1); + val1 = (f >> (52 - e)) * (sign ? -1 : 1); } /* calculate the rest of the decimal */ - k = LWM2M_FLOAT32_DEC_MAX; + k = PRECISION64; /* account for -e */ while (e < -1) { @@ -290,19 +308,26 @@ int lwm2m_b64_to_f32(uint8_t *b64, size_t len, float32_value_t *f32) for (i = 51 - e; i >= 0; i--) { k /= 2; if (f & ((int64_t)1 << i)) { - f32->val2 += k; + val2 += k; } } + if (sign) { + *out = (double)val1 - (double)val2 / PRECISION64; + } else { + *out = (double)val1 + (double)val2 / PRECISION64; + } + return 0; } -int lwm2m_atof32(const char *input, float32_value_t *out) +int lwm2m_atof(const char *input, double *out) { char *pos, *end, buf[24]; long val; - int32_t base = LWM2M_FLOAT32_DEC_MAX, sign = 1; + int64_t base = PRECISION64, sign = 1; + int64_t val1, val2; if (!input || !out) { return -EINVAL; @@ -326,18 +351,71 @@ int lwm2m_atof32(const char *input, float32_value_t *out) return -EINVAL; } - out->val1 = (int32_t) val; - out->val2 = 0; + val1 = (int64_t)val; + val2 = 0; if (!pos) { return 0; } while (*(++pos) && base > 1 && isdigit((unsigned char)*pos)) { - out->val2 = out->val2 * 10 + (*pos - '0'); + val2 = val2 * 10 + (*pos - '0'); base /= 10; } - out->val2 *= sign * base; + val2 *= sign * base; + + *out = (double)val1 + (double)val2 / PRECISION64; + return !*pos || base == 1 ? 0 : -EINVAL; } + +int lwm2m_ftoa(double *input, char *out, size_t outlen, int8_t dec_limit) +{ + size_t len; + char buf[PRECISION64_LEN + 1]; + int64_t val1 = (int64_t)*input; + int64_t val2 = (*input - (int64_t)*input) * PRECISION64; + + len = snprintk(buf, sizeof(buf), "%0*lld", PRECISION64_LEN, llabs(val2)); + if (len != PRECISION64_LEN) { + strcpy(buf, "0"); + } else { + /* Round the value to the specified decimal point. */ + if (dec_limit > 0 && dec_limit < sizeof(buf) && + buf[dec_limit] != '\0') { + bool round_up = buf[dec_limit] >= '5'; + + buf[dec_limit] = '\0'; + len = dec_limit; + + while (round_up && dec_limit > 0) { + dec_limit--; + buf[dec_limit]++; + + if (buf[dec_limit] > '9') { + buf[dec_limit] = '0'; + } else { + round_up = false; + } + } + + if (round_up) { + if (*input < 0) { + val1--; + } else { + val1++; + } + } + } + + /* clear ending zeroes, but leave 1 if needed */ + while (len > 1U && buf[len - 1] == '0') { + buf[--len] = '\0'; + } + } + + return snprintk(out, outlen, "%s%lld.%s", + /* handle negative val2 when val1 is 0 */ + (val1 == 0 && val2 < 0) ? "-" : "", val1, buf); +} diff --git a/subsys/net/lib/lwm2m/lwm2m_util.h b/subsys/net/lib/lwm2m/lwm2m_util.h index 216d83de5f2..b5b451b6c2c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_util.h +++ b/subsys/net/lib/lwm2m/lwm2m_util.h @@ -9,15 +9,17 @@ #include -/* convert float struct to binary format */ -int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len); -int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len); +/* convert float to binary format */ +int lwm2m_float_to_b32(double *in, uint8_t *b32, size_t len); +int lwm2m_float_to_b64(double *in, uint8_t *b64, size_t len); -/* convert binary format to float struct */ -int lwm2m_b32_to_f32(uint8_t *b32, size_t len, float32_value_t *f32); -int lwm2m_b64_to_f32(uint8_t *b64, size_t len, float32_value_t *f32); +/* convert binary format to float */ +int lwm2m_b32_to_float(uint8_t *b32, size_t len, double *out); +int lwm2m_b64_to_float(uint8_t *b64, size_t len, double *out); -/* convert string to float struct */ -int lwm2m_atof32(const char *input, float32_value_t *out); +/* convert string to float */ +int lwm2m_atof(const char *input, double *out); +/* convert float to string */ +int lwm2m_ftoa(double *input, char *out, size_t outlen, int8_t dec_limit); #endif /* LWM2M_UTIL_H_ */