net: lwm2m: Replace float32_value_t with double
Replace the custom float32_value_t LwM2M type with native double, to facilitate LwM2M API and improve floating point precission. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
3a3e3c041b
commit
875c75c4f9
|
@ -34,6 +34,8 @@ Changes in this release
|
||||||
* :c:func:`uart_tx`
|
* :c:func:`uart_tx`
|
||||||
* :c:func:`uart_rx_enable`
|
* :c:func:`uart_rx_enable`
|
||||||
|
|
||||||
|
* Replaced custom LwM2M :c:struct:`float32_value` type with a native double type.
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
Removed APIs in this release
|
Removed APIs in this release
|
||||||
|
|
|
@ -357,27 +357,6 @@ struct coap_block_context *lwm2m_firmware_get_block_context();
|
||||||
#endif
|
#endif
|
||||||
#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
|
* @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);
|
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] 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.
|
* @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)
|
* @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);
|
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[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.
|
* @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)
|
* @brief Get resource (instance) value (ObjLnk)
|
||||||
|
|
1
samples/net/lwm2m_client/boards/qemu_x86.conf
Normal file
1
samples/net/lwm2m_client/boards/qemu_x86.conf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CONFIG_FPU=y
|
|
@ -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)
|
uint16_t res_inst_id, size_t *data_len)
|
||||||
{
|
{
|
||||||
/* Last read temperature value, will use 25.5C if no sensor available */
|
/* 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;
|
const struct device *dev = NULL;
|
||||||
|
|
||||||
#if defined(CONFIG_FXOS8700_TEMP)
|
#if defined(CONFIG_FXOS8700_TEMP)
|
||||||
|
@ -198,17 +198,21 @@ static void *temperature_get_buf(uint16_t obj_inst_id, uint16_t res_id,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dev != NULL) {
|
if (dev != NULL) {
|
||||||
|
struct sensor_value val;
|
||||||
|
|
||||||
if (sensor_sample_fetch(dev)) {
|
if (sensor_sample_fetch(dev)) {
|
||||||
LOG_ERR("temperature data update failed");
|
LOG_ERR("temperature data update failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP,
|
sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &val);
|
||||||
(struct sensor_value *) &v);
|
|
||||||
LOG_DBG("LWM2M temperature set to %d.%d", v.val1, v.val2);
|
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 */
|
/* 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);
|
*data_len = sizeof(v);
|
||||||
return &v;
|
return &v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
/* resource state */
|
/* resource state */
|
||||||
struct ipso_accel_data {
|
struct ipso_accel_data {
|
||||||
float32_value_t x_value;
|
double x_value;
|
||||||
float32_value_t y_value;
|
double y_value;
|
||||||
float32_value_t z_value;
|
double z_value;
|
||||||
float32_value_t min_range;
|
double min_range;
|
||||||
float32_value_t max_range;
|
double max_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ipso_accel_data accel_data[MAX_INSTANCE_COUNT];
|
static struct ipso_accel_data accel_data[MAX_INSTANCE_COUNT];
|
||||||
|
|
|
@ -43,9 +43,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
/* resource state */
|
/* resource state */
|
||||||
struct ipso_buzzer_data {
|
struct ipso_buzzer_data {
|
||||||
float32_value_t level;
|
double level;
|
||||||
float32_value_t delay_duration;
|
double delay_duration;
|
||||||
float32_value_t min_off_time;
|
double min_off_time;
|
||||||
|
|
||||||
uint64_t trigger_offset;
|
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
|
static struct lwm2m_engine_res_inst
|
||||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
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)
|
static int get_buzzer_index(uint16_t obj_inst_id)
|
||||||
{
|
{
|
||||||
int i, ret = -ENOENT;
|
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 */
|
/* 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) {
|
if (k_uptime_get() < buzzer->trigger_offset + temp) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +120,7 @@ static int start_buzzer(struct ipso_buzzer_data *buzzer)
|
||||||
buzzer->obj_inst_id, DIGITAL_INPUT_STATE_RID);
|
buzzer->obj_inst_id, DIGITAL_INPUT_STATE_RID);
|
||||||
lwm2m_engine_set_bool(path, true);
|
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));
|
k_work_reschedule(&buzzer->buzzer_work, K_MSEC(temp));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -210,8 +202,8 @@ static struct lwm2m_engine_obj_inst *buzzer_create(uint16_t obj_inst_id)
|
||||||
/* Set default values */
|
/* Set default values */
|
||||||
(void)memset(&buzzer_data[avail], 0, sizeof(buzzer_data[avail]));
|
(void)memset(&buzzer_data[avail], 0, sizeof(buzzer_data[avail]));
|
||||||
k_work_init_delayable(&buzzer_data[avail].buzzer_work, buzzer_work_cb);
|
k_work_init_delayable(&buzzer_data[avail].buzzer_work, buzzer_work_cb);
|
||||||
buzzer_data[avail].level.val1 = 50; /* 50% */
|
buzzer_data[avail].level = 50; /* 50% */
|
||||||
buzzer_data[avail].delay_duration.val1 = 1; /* 1 seconds */
|
buzzer_data[avail].delay_duration = 1; /* 1 seconds */
|
||||||
buzzer_data[avail].obj_inst_id = obj_inst_id;
|
buzzer_data[avail].obj_inst_id = obj_inst_id;
|
||||||
|
|
||||||
(void)memset(res[avail], 0,
|
(void)memset(res[avail], 0,
|
||||||
|
|
|
@ -56,12 +56,12 @@ BUILD_ASSERT(SENSOR_TYPE_STR_MAX_SIZE >=
|
||||||
#define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1)
|
#define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1)
|
||||||
|
|
||||||
/* resource state variables */
|
/* 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 char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE];
|
||||||
static float32_value_t min_measured_value[MAX_INSTANCE_COUNT];
|
static double min_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_measured_value[MAX_INSTANCE_COUNT];
|
static double max_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t min_range_value[MAX_INSTANCE_COUNT];
|
static double min_range_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_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 app_type[MAX_INSTANCE_COUNT][APP_TYPE_STR_MAX_SIZE];
|
||||||
static char sensor_type[MAX_INSTANCE_COUNT][SENSOR_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)
|
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] = sensor_value[index];
|
||||||
min_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID);
|
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_max_measured(uint16_t obj_inst_id, int index)
|
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] = sensor_value[index];
|
||||||
max_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MAX_MEASURED_VALUE_RID);
|
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)
|
size_t total_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool update_min = false;
|
|
||||||
bool update_max = false;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
||||||
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
||||||
/* update min / max */
|
/* update min / max */
|
||||||
if (sensor_value[i].val1 < min_measured_value[i].val1) {
|
if (sensor_value[i] < min_measured_value[i]) {
|
||||||
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) {
|
|
||||||
update_min_measured(obj_inst_id, 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);
|
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 */
|
/* Set default values */
|
||||||
sensor_value[index].val1 = 0;
|
sensor_value[index] = 0;
|
||||||
sensor_value[index].val2 = 0;
|
|
||||||
units[index][0] = '\0';
|
units[index][0] = '\0';
|
||||||
min_measured_value[index].val1 = INT32_MAX;
|
min_measured_value[index] = INT32_MAX;
|
||||||
min_measured_value[index].val2 = 0;
|
max_measured_value[index] = -INT32_MAX;
|
||||||
max_measured_value[index].val1 = -INT32_MAX;
|
min_range_value[index] = 0;
|
||||||
max_measured_value[index].val2 = 0;
|
max_range_value[index] = 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;
|
|
||||||
app_type[index][0] = '\0';
|
app_type[index][0] = '\0';
|
||||||
strncpy(sensor_type[index], CONFIG_LWM2M_IPSO_GENERIC_SENSOR_TYPE,
|
strncpy(sensor_type[index], CONFIG_LWM2M_IPSO_GENERIC_SENSOR_TYPE,
|
||||||
SENSOR_TYPE_STR_MAX_SIZE);
|
SENSOR_TYPE_STR_MAX_SIZE);
|
||||||
|
|
|
@ -45,12 +45,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1)
|
#define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1)
|
||||||
|
|
||||||
/* resource state variables */
|
/* 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 char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE];
|
||||||
static float32_value_t min_measured_value[MAX_INSTANCE_COUNT];
|
static double min_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_measured_value[MAX_INSTANCE_COUNT];
|
static double max_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t min_range_value[MAX_INSTANCE_COUNT];
|
static double min_range_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_range_value[MAX_INSTANCE_COUNT];
|
static double max_range_value[MAX_INSTANCE_COUNT];
|
||||||
|
|
||||||
static struct lwm2m_engine_obj sensor;
|
static struct lwm2m_engine_obj sensor;
|
||||||
static struct lwm2m_engine_obj_field fields[] = {
|
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)
|
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] = sensor_value[index];
|
||||||
min_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID);
|
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_max_measured(uint16_t obj_inst_id, int index)
|
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] = sensor_value[index];
|
||||||
max_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MAX_MEASURED_VALUE_RID);
|
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)
|
size_t total_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool update_min = false;
|
|
||||||
bool update_max = false;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
||||||
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
||||||
/* update min / max */
|
/* update min / max */
|
||||||
if (sensor_value[i].val1 < min_measured_value[i].val1) {
|
if (sensor_value[i] < min_measured_value[i]) {
|
||||||
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) {
|
|
||||||
update_min_measured(obj_inst_id, 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);
|
update_max_measured(obj_inst_id, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,17 +155,12 @@ humidity_sensor_create(uint16_t obj_inst_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set default values */
|
/* Set default values */
|
||||||
sensor_value[index].val1 = 0;
|
sensor_value[index] = 0;
|
||||||
sensor_value[index].val2 = 0;
|
|
||||||
units[index][0] = '\0';
|
units[index][0] = '\0';
|
||||||
min_measured_value[index].val1 = INT32_MAX;
|
min_measured_value[index] = INT32_MAX;
|
||||||
min_measured_value[index].val2 = 0;
|
max_measured_value[index] = -INT32_MAX;
|
||||||
max_measured_value[index].val1 = -INT32_MAX;
|
min_range_value[index] = 0;
|
||||||
max_measured_value[index].val2 = 0;
|
max_range_value[index] = 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;
|
|
||||||
|
|
||||||
(void)memset(res[index], 0,
|
(void)memset(res[index], 0,
|
||||||
sizeof(res[index][0]) * ARRAY_SIZE(res[index]));
|
sizeof(res[index][0]) * ARRAY_SIZE(res[index]));
|
||||||
|
|
|
@ -45,8 +45,8 @@ static bool on_off_value[MAX_INSTANCE_COUNT];
|
||||||
static uint8_t dimmer_value[MAX_INSTANCE_COUNT];
|
static uint8_t dimmer_value[MAX_INSTANCE_COUNT];
|
||||||
static int32_t on_time_value[MAX_INSTANCE_COUNT];
|
static int32_t on_time_value[MAX_INSTANCE_COUNT];
|
||||||
static uint32_t on_time_offset[MAX_INSTANCE_COUNT];
|
static uint32_t on_time_offset[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t cumulative_active_value[MAX_INSTANCE_COUNT];
|
static double cumulative_active_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t power_factor_value[MAX_INSTANCE_COUNT];
|
static double power_factor_value[MAX_INSTANCE_COUNT];
|
||||||
static char colour[MAX_INSTANCE_COUNT][LIGHT_STRING_LONG];
|
static char colour[MAX_INSTANCE_COUNT][LIGHT_STRING_LONG];
|
||||||
static char units[MAX_INSTANCE_COUNT][LIGHT_STRING_SHORT];
|
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;
|
dimmer_value[avail] = 0U;
|
||||||
on_time_value[avail] = 0;
|
on_time_value[avail] = 0;
|
||||||
on_time_offset[avail] = 0U;
|
on_time_offset[avail] = 0U;
|
||||||
cumulative_active_value[avail].val1 = 0;
|
cumulative_active_value[avail] = 0;
|
||||||
cumulative_active_value[avail].val2 = 0;
|
power_factor_value[avail] = 0;
|
||||||
power_factor_value[avail].val1 = 0;
|
|
||||||
power_factor_value[avail].val2 = 0;
|
|
||||||
colour[avail][0] = '\0';
|
colour[avail][0] = '\0';
|
||||||
units[avail][0] = '\0';
|
units[avail][0] = '\0';
|
||||||
|
|
||||||
|
|
|
@ -45,12 +45,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1)
|
#define RESOURCE_INSTANCE_COUNT (NUMBER_OF_OBJ_FIELDS - 1)
|
||||||
|
|
||||||
/* resource state variables */
|
/* 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 char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE];
|
||||||
static float32_value_t min_measured_value[MAX_INSTANCE_COUNT];
|
static double min_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_measured_value[MAX_INSTANCE_COUNT];
|
static double max_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t min_range_value[MAX_INSTANCE_COUNT];
|
static double min_range_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_range_value[MAX_INSTANCE_COUNT];
|
static double max_range_value[MAX_INSTANCE_COUNT];
|
||||||
|
|
||||||
static struct lwm2m_engine_obj sensor;
|
static struct lwm2m_engine_obj sensor;
|
||||||
static struct lwm2m_engine_obj_field fields[] = {
|
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)
|
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] = sensor_value[index];
|
||||||
min_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID);
|
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MIN_MEASURED_VALUE_RID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_max_measured(uint16_t obj_inst_id, int index)
|
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] = sensor_value[index];
|
||||||
max_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_ID, obj_inst_id, MAX_MEASURED_VALUE_RID);
|
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)
|
size_t total_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool update_min = false;
|
|
||||||
bool update_max = false;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
||||||
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
||||||
/* update min / max */
|
/* update min / max */
|
||||||
if (sensor_value[i].val1 < min_measured_value[i].val1) {
|
if (sensor_value[i] < min_measured_value[i]) {
|
||||||
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) {
|
|
||||||
update_min_measured(obj_inst_id, 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);
|
update_max_measured(obj_inst_id, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,17 +156,12 @@ pressure_sensor_create(uint16_t obj_inst_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set default values */
|
/* Set default values */
|
||||||
sensor_value[index].val1 = 0;
|
sensor_value[index] = 0;
|
||||||
sensor_value[index].val2 = 0;
|
|
||||||
units[index][0] = '\0';
|
units[index][0] = '\0';
|
||||||
min_measured_value[index].val1 = INT32_MAX;
|
min_measured_value[index] = INT32_MAX;
|
||||||
min_measured_value[index].val2 = 0;
|
max_measured_value[index] = -INT32_MAX;
|
||||||
max_measured_value[index].val1 = -INT32_MAX;
|
min_range_value[index] = 0;
|
||||||
max_measured_value[index].val2 = 0;
|
max_range_value[index] = 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;
|
|
||||||
|
|
||||||
(void)memset(res[index], 0,
|
(void)memset(res[index], 0,
|
||||||
sizeof(res[index][0]) * ARRAY_SIZE(res[index]));
|
sizeof(res[index][0]) * ARRAY_SIZE(res[index]));
|
||||||
|
|
|
@ -46,12 +46,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#define RESOURCE_INSTANCE_COUNT (TEMP_MAX_ID - 1)
|
#define RESOURCE_INSTANCE_COUNT (TEMP_MAX_ID - 1)
|
||||||
|
|
||||||
/* resource state variables */
|
/* 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 char units[MAX_INSTANCE_COUNT][UNIT_STR_MAX_SIZE];
|
||||||
static float32_value_t min_measured_value[MAX_INSTANCE_COUNT];
|
static double min_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_measured_value[MAX_INSTANCE_COUNT];
|
static double max_measured_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t min_range_value[MAX_INSTANCE_COUNT];
|
static double min_range_value[MAX_INSTANCE_COUNT];
|
||||||
static float32_value_t max_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 temp_sensor;
|
||||||
static struct lwm2m_engine_obj_field fields[] = {
|
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)
|
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] = sensor_value[index];
|
||||||
min_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_TEMP_SENSOR_ID, obj_inst_id,
|
NOTIFY_OBSERVER(IPSO_OBJECT_TEMP_SENSOR_ID, obj_inst_id,
|
||||||
MIN_MEASURED_VALUE_RID);
|
MIN_MEASURED_VALUE_RID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_max_measured(uint16_t obj_inst_id, int index)
|
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] = sensor_value[index];
|
||||||
max_measured_value[index].val2 = sensor_value[index].val2;
|
|
||||||
NOTIFY_OBSERVER(IPSO_OBJECT_TEMP_SENSOR_ID, obj_inst_id,
|
NOTIFY_OBSERVER(IPSO_OBJECT_TEMP_SENSOR_ID, obj_inst_id,
|
||||||
MAX_MEASURED_VALUE_RID);
|
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)
|
bool last_block, size_t total_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool update_min = false;
|
|
||||||
bool update_max = false;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
for (i = 0; i < MAX_INSTANCE_COUNT; i++) {
|
||||||
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) {
|
||||||
/* update min / max */
|
/* update min / max */
|
||||||
if (sensor_value[i].val1 < min_measured_value[i].val1) {
|
if (sensor_value[i] < min_measured_value[i]) {
|
||||||
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) {
|
|
||||||
update_min_measured(obj_inst_id, 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);
|
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 */
|
/* Set default values */
|
||||||
sensor_value[index].val1 = 0;
|
sensor_value[index] = 0;
|
||||||
sensor_value[index].val2 = 0;
|
|
||||||
units[index][0] = '\0';
|
units[index][0] = '\0';
|
||||||
min_measured_value[index].val1 = INT32_MAX;
|
min_measured_value[index] = INT32_MAX;
|
||||||
min_measured_value[index].val2 = 0;
|
max_measured_value[index] = -INT32_MAX;
|
||||||
max_measured_value[index].val1 = -INT32_MAX;
|
min_range_value[index] = 0;
|
||||||
max_measured_value[index].val2 = 0;
|
max_range_value[index] = 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;
|
|
||||||
|
|
||||||
(void)memset(res[index], 0,
|
(void)memset(res[index], 0,
|
||||||
sizeof(res[index][0]) * ARRAY_SIZE(res[index]));
|
sizeof(res[index][0]) * ARRAY_SIZE(res[index]));
|
||||||
|
|
|
@ -46,10 +46,10 @@ enum ipso_timer_mode {
|
||||||
|
|
||||||
/* resource state */
|
/* resource state */
|
||||||
struct ipso_timer_data {
|
struct ipso_timer_data {
|
||||||
float32_value_t delay_duration;
|
double delay_duration;
|
||||||
float32_value_t remaining_time;
|
double remaining_time;
|
||||||
float32_value_t min_off_time;
|
double min_off_time;
|
||||||
float32_value_t cumulative_time;
|
double cumulative_time;
|
||||||
|
|
||||||
uint64_t trigger_offset;
|
uint64_t trigger_offset;
|
||||||
uint32_t trigger_counter;
|
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
|
static struct lwm2m_engine_res_inst
|
||||||
res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
|
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)
|
static int get_timer_index(uint16_t obj_inst_id)
|
||||||
{
|
{
|
||||||
int i, ret = -ENOENT;
|
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 */
|
/* 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) {
|
if (k_uptime_get() < timer->trigger_offset + temp) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +127,7 @@ static int start_timer(struct ipso_timer_data *timer)
|
||||||
timer->obj_inst_id, DIGITAL_STATE_RID);
|
timer->obj_inst_id, DIGITAL_STATE_RID);
|
||||||
lwm2m_engine_set_bool(path, true);
|
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));
|
k_work_reschedule(&timer->timer_work, K_MSEC(temp));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -183,12 +167,11 @@ static void *remaining_time_read_cb(uint16_t obj_inst_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer_data[i].active) {
|
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);
|
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 {
|
} else {
|
||||||
timer_data[i].remaining_time.val1 = 0;
|
timer_data[i].remaining_time = 0;
|
||||||
timer_data[i].remaining_time.val2 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*data_len = sizeof(timer_data[i].remaining_time);
|
*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;
|
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);
|
*data_len = sizeof(timer_data[i].cumulative_time);
|
||||||
return &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 */
|
/* Set default values */
|
||||||
(void)memset(&timer_data[avail], 0, sizeof(timer_data[avail]));
|
(void)memset(&timer_data[avail], 0, sizeof(timer_data[avail]));
|
||||||
k_work_init_delayable(&timer_data[avail].timer_work, timer_work_cb);
|
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].enabled = true;
|
||||||
timer_data[avail].timer_mode = TIMER_MODE_ONE_SHOT;
|
timer_data[avail].timer_mode = TIMER_MODE_ONE_SHOT;
|
||||||
timer_data[avail].obj_inst_id = obj_inst_id;
|
timer_data[avail].obj_inst_id = obj_inst_id;
|
||||||
|
|
|
@ -86,9 +86,9 @@ struct observe_node {
|
||||||
|
|
||||||
struct notification_attrs {
|
struct notification_attrs {
|
||||||
/* use to determine which value is set */
|
/* use to determine which value is set */
|
||||||
float32_value_t gt;
|
double gt;
|
||||||
float32_value_t lt;
|
double lt;
|
||||||
float32_value_t st;
|
double st;
|
||||||
int32_t pmin;
|
int32_t pmin;
|
||||||
int32_t pmax;
|
int32_t pmax;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
@ -1596,10 +1596,7 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_FLOAT:
|
case LWM2M_RES_TYPE_FLOAT:
|
||||||
((float32_value_t *)data_ptr)->val1 =
|
*(double *)data_ptr = *(double *)value;
|
||||||
((float32_value_t *)value)->val1;
|
|
||||||
((float32_value_t *)data_ptr)->val2 =
|
|
||||||
((float32_value_t *)value)->val2;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_OBJLNK:
|
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);
|
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)
|
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;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_FLOAT:
|
case LWM2M_RES_TYPE_FLOAT:
|
||||||
((float32_value_t *)buf)->val1 =
|
*(double *)buf = *(double *)data_ptr;
|
||||||
((float32_value_t *)data_ptr)->val1;
|
|
||||||
((float32_value_t *)buf)->val2 =
|
|
||||||
((float32_value_t *)data_ptr)->val2;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_OBJLNK:
|
case LWM2M_RES_TYPE_OBJLNK:
|
||||||
|
@ -1915,9 +1909,9 @@ int lwm2m_engine_get_bool(char *pathstr, bool *value)
|
||||||
return ret;
|
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)
|
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;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_FLOAT:
|
case LWM2M_RES_TYPE_FLOAT:
|
||||||
engine_put_float32fix(&msg->out, &msg->path,
|
engine_put_float(&msg->out, &msg->path,
|
||||||
(float32_value_t *)data_ptr);
|
(double *)data_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_OBJLNK:
|
case LWM2M_RES_TYPE_OBJLNK:
|
||||||
|
@ -2594,9 +2588,8 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_FLOAT:
|
case LWM2M_RES_TYPE_FLOAT:
|
||||||
engine_get_float32fix(&msg->in,
|
engine_get_float(&msg->in, (double *)write_buf);
|
||||||
(float32_value_t *)write_buf);
|
len = sizeof(double);
|
||||||
len = sizeof(float32_value_t);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_RES_TYPE_OBJLNK:
|
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 */
|
/* loop through options to parse attribute */
|
||||||
for (i = 0; i < nr_opt; i++) {
|
for (i = 0; i < nr_opt; i++) {
|
||||||
int limit = MIN(options[i].len, 5), plen = 0, vlen;
|
int limit = MIN(options[i].len, 5), plen = 0, vlen;
|
||||||
float32_value_t val = { 0 };
|
struct lwm2m_attr val = { 0 };
|
||||||
type = 0U;
|
type = 0U;
|
||||||
|
|
||||||
/* search for '=' */
|
/* search for '=' */
|
||||||
|
@ -2758,7 +2751,7 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
||||||
|
|
||||||
(void)memset(nattr_ptrs[type], 0,
|
(void)memset(nattr_ptrs[type], 0,
|
||||||
type <= LWM2M_ATTR_PMAX ? sizeof(int32_t) :
|
type <= LWM2M_ATTR_PMAX ? sizeof(int32_t) :
|
||||||
sizeof(float32_value_t));
|
sizeof(double));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2785,10 +2778,10 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
val.val1 = v;
|
val.int_val = v;
|
||||||
} else {
|
} else {
|
||||||
/* gt/lt/st: type float */
|
/* gt/lt/st: type float */
|
||||||
ret = lwm2m_atof32(opt_buf, &val);
|
ret = lwm2m_atof(opt_buf, &val.float_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -2799,9 +2792,10 @@ static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type <= LWM2M_ATTR_PMAX) {
|
if (type <= LWM2M_ATTR_PMAX) {
|
||||||
*(int32_t *)nattr_ptrs[type] = val.val1;
|
*(int32_t *)nattr_ptrs[type] = val.int_val;
|
||||||
} else {
|
} 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);
|
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.flags & (BIT(LWM2M_ATTR_LT) | BIT(LWM2M_ATTR_GT))) {
|
||||||
if (!((nattrs.lt.val1 < nattrs.gt.val1) ||
|
if (nattrs.lt > nattrs.gt) {
|
||||||
(nattrs.lt.val2 < nattrs.gt.val2))) {
|
|
||||||
LOG_DBG("lt > gt");
|
LOG_DBG("lt > gt");
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nattrs.flags & BIT(LWM2M_ATTR_STEP)) {
|
if (nattrs.flags & BIT(LWM2M_ATTR_STEP)) {
|
||||||
int32_t st1 = nattrs.st.val1 * 2 +
|
if (nattrs.lt + 2 * nattrs.st > nattrs.gt) {
|
||||||
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))) {
|
|
||||||
LOG_DBG("lt + 2*st > gt");
|
LOG_DBG("lt + 2*st > gt");
|
||||||
return -EEXIST;
|
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];
|
attr->int_val = *(int32_t *)nattr_ptrs[type];
|
||||||
update_observe_node = true;
|
update_observe_node = true;
|
||||||
|
|
||||||
|
LOG_DBG("Update %s to %d", log_strdup(LWM2M_ATTR_STR[type]),
|
||||||
|
attr->int_val);
|
||||||
} else {
|
} else {
|
||||||
if (!memcmp(&attr->float_val, nattr_ptrs[type],
|
if (attr->float_val == *(double *)nattr_ptrs[type]) {
|
||||||
sizeof(float32_value_t))) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&attr->float_val, nattr_ptrs[type],
|
attr->float_val = *(double *)nattr_ptrs[type];
|
||||||
sizeof(float32_value_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DBG("Update %s to %d.%06d",
|
LOG_DBG("Update %s to %f", log_strdup(LWM2M_ATTR_STR[type]),
|
||||||
log_strdup(LWM2M_ATTR_STR[type]),
|
attr->float_val);
|
||||||
attr->float_val.val1, attr->float_val.val2);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add attribute to obj/obj_inst/res */
|
/* 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) {
|
if (type <= LWM2M_ATTR_PMAX) {
|
||||||
attr->int_val = *(int32_t *)nattr_ptrs[type];
|
attr->int_val = *(int32_t *)nattr_ptrs[type];
|
||||||
update_observe_node = true;
|
update_observe_node = true;
|
||||||
|
|
||||||
|
LOG_DBG("Add %s to %d", log_strdup(LWM2M_ATTR_STR[type]),
|
||||||
|
attr->int_val);
|
||||||
} else {
|
} else {
|
||||||
memcpy(&attr->float_val, nattr_ptrs[type],
|
attr->float_val = *(double *)nattr_ptrs[type];
|
||||||
sizeof(float32_value_t));
|
|
||||||
|
LOG_DBG("Add %s to %f", log_strdup(LWM2M_ATTR_STR[type]),
|
||||||
|
attr->float_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
nattrs.flags &= ~BIT(type);
|
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 */
|
/* check only pmin/pmax */
|
||||||
|
|
|
@ -37,11 +37,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#define RESOURCE_INSTANCE_COUNT (LOCATION_MAX_ID)
|
#define RESOURCE_INSTANCE_COUNT (LOCATION_MAX_ID)
|
||||||
|
|
||||||
/* resource state */
|
/* resource state */
|
||||||
static float32_value_t latitude;
|
static double latitude;
|
||||||
static float32_value_t longitude;
|
static double longitude;
|
||||||
static float32_value_t altitude;
|
static double altitude;
|
||||||
static float32_value_t radius;
|
static double radius;
|
||||||
static float32_value_t speed;
|
static double speed;
|
||||||
static int32_t timestamp;
|
static int32_t timestamp;
|
||||||
|
|
||||||
static struct lwm2m_engine_obj location;
|
static struct lwm2m_engine_obj location;
|
||||||
|
|
|
@ -347,7 +347,7 @@ struct lwm2m_attr {
|
||||||
|
|
||||||
/* values */
|
/* values */
|
||||||
union {
|
union {
|
||||||
float32_value_t float_val;
|
double float_val;
|
||||||
int32_t int_val;
|
int32_t int_val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -515,9 +515,9 @@ struct lwm2m_writer {
|
||||||
size_t (*put_string)(struct lwm2m_output_context *out,
|
size_t (*put_string)(struct lwm2m_output_context *out,
|
||||||
struct lwm2m_obj_path *path,
|
struct lwm2m_obj_path *path,
|
||||||
char *buf, size_t buflen);
|
char *buf, size_t buflen);
|
||||||
size_t (*put_float32fix)(struct lwm2m_output_context *out,
|
size_t (*put_float)(struct lwm2m_output_context *out,
|
||||||
struct lwm2m_obj_path *path,
|
struct lwm2m_obj_path *path,
|
||||||
float32_value_t *value);
|
double *value);
|
||||||
size_t (*put_bool)(struct lwm2m_output_context *out,
|
size_t (*put_bool)(struct lwm2m_output_context *out,
|
||||||
struct lwm2m_obj_path *path,
|
struct lwm2m_obj_path *path,
|
||||||
bool value);
|
bool value);
|
||||||
|
@ -538,8 +538,8 @@ struct lwm2m_reader {
|
||||||
int64_t *value);
|
int64_t *value);
|
||||||
size_t (*get_string)(struct lwm2m_input_context *in,
|
size_t (*get_string)(struct lwm2m_input_context *in,
|
||||||
uint8_t *buf, size_t buflen);
|
uint8_t *buf, size_t buflen);
|
||||||
size_t (*get_float32fix)(struct lwm2m_input_context *in,
|
size_t (*get_float)(struct lwm2m_input_context *in,
|
||||||
float32_value_t *value);
|
double *value);
|
||||||
size_t (*get_bool)(struct lwm2m_input_context *in,
|
size_t (*get_bool)(struct lwm2m_input_context *in,
|
||||||
bool *value);
|
bool *value);
|
||||||
size_t (*get_opaque)(struct lwm2m_input_context *in,
|
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);
|
return out->writer->put_string(out, path, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t engine_put_float32fix(struct lwm2m_output_context *out,
|
static inline size_t engine_put_float(struct lwm2m_output_context *out,
|
||||||
struct lwm2m_obj_path *path,
|
struct lwm2m_obj_path *path,
|
||||||
float32_value_t *value)
|
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,
|
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);
|
return in->reader->get_string(in, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t engine_get_float32fix(struct lwm2m_input_context *in,
|
static inline size_t engine_get_float(struct lwm2m_input_context *in,
|
||||||
float32_value_t *value)
|
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,
|
static inline size_t engine_get_bool(struct lwm2m_input_context *in,
|
||||||
|
|
|
@ -491,14 +491,14 @@ static size_t put_string(struct lwm2m_output_context *out,
|
||||||
return len;
|
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,
|
struct lwm2m_obj_path *path,
|
||||||
float32_value_t *value)
|
double *value)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
len = put_json_prefix(out, path, "\"v\"");
|
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);
|
len += put_json_postfix(out);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -612,8 +612,8 @@ static size_t get_string(struct lwm2m_input_context *in,
|
||||||
return fd->value_len;
|
return fd->value_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_float32fix(struct lwm2m_input_context *in,
|
static size_t get_float(struct lwm2m_input_context *in,
|
||||||
float32_value_t *value)
|
double *value)
|
||||||
{
|
{
|
||||||
struct json_in_formatter_data *fd;
|
struct json_in_formatter_data *fd;
|
||||||
|
|
||||||
|
@ -652,7 +652,7 @@ static size_t get_float32fix(struct lwm2m_input_context *in,
|
||||||
|
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
||||||
if (lwm2m_atof32(buf, value) != 0) {
|
if (lwm2m_atof(buf, value) != 0) {
|
||||||
LOG_ERR("Failed to parse float value");
|
LOG_ERR("Failed to parse float value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +729,7 @@ const struct lwm2m_writer json_writer = {
|
||||||
.put_s32 = put_s32,
|
.put_s32 = put_s32,
|
||||||
.put_s64 = put_s64,
|
.put_s64 = put_s64,
|
||||||
.put_string = put_string,
|
.put_string = put_string,
|
||||||
.put_float32fix = put_float32fix,
|
.put_float = put_float,
|
||||||
.put_bool = put_bool,
|
.put_bool = put_bool,
|
||||||
.put_objlnk = put_objlnk,
|
.put_objlnk = put_objlnk,
|
||||||
};
|
};
|
||||||
|
@ -738,7 +738,7 @@ const struct lwm2m_reader json_reader = {
|
||||||
.get_s32 = get_s32,
|
.get_s32 = get_s32,
|
||||||
.get_s64 = get_s64,
|
.get_s64 = get_s64,
|
||||||
.get_string = get_string,
|
.get_string = get_string,
|
||||||
.get_float32fix = get_float32fix,
|
.get_float = get_float,
|
||||||
.get_bool = get_bool,
|
.get_bool = get_bool,
|
||||||
.get_opaque = get_opaque,
|
.get_opaque = get_opaque,
|
||||||
.get_objlnk = get_objlnk,
|
.get_objlnk = get_objlnk,
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "lwm2m_engine.h"
|
#include "lwm2m_engine.h"
|
||||||
#include "lwm2m_rw_link_format.h"
|
#include "lwm2m_rw_link_format.h"
|
||||||
|
#include "lwm2m_util.h"
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(net_lwm2m_link_format, CONFIG_LWM2M_LOG_LEVEL);
|
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)
|
uint16_t buflen)
|
||||||
{
|
{
|
||||||
struct lwm2m_attr *attr = NULL;
|
struct lwm2m_attr *attr = NULL;
|
||||||
int used, base, ret;
|
int used, ret;
|
||||||
uint8_t digit;
|
|
||||||
int32_t fraction;
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
while ((attr = lwm2m_engine_get_next_attr(ref, attr)) != NULL) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assuming integer will have float_val.val2 set as 0. */
|
if (attr->type <= LWM2M_ATTR_PMAX) {
|
||||||
used = snprintk(buf, buflen, ";%s=%s%d%s",
|
used = snprintk(buf, buflen, ";%s=%d", name, attr->int_val);
|
||||||
name,
|
} else {
|
||||||
attr->float_val.val1 == 0 &&
|
uint8_t float_buf[32];
|
||||||
attr->float_val.val2 < 0 ? "-" : "",
|
|
||||||
attr->float_val.val1,
|
used = lwm2m_ftoa(&attr->float_val, float_buf,
|
||||||
attr->float_val.val2 != 0 ? "." : "");
|
sizeof(float_buf), 4);
|
||||||
if (used < 0 || used >= buflen) {
|
if (used < 0 || used >= sizeof(float_buf)) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
used = snprintk(buf, buflen, ";%s=%s", name, float_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
base = 100000;
|
if (used < 0 || used >= buflen) {
|
||||||
fraction = attr->float_val.val2 < 0 ?
|
return -ENOMEM;
|
||||||
-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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len += used;
|
len += used;
|
||||||
|
|
|
@ -510,30 +510,30 @@ static size_t put_string(struct lwm2m_output_context *out,
|
||||||
return len;
|
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,
|
struct lwm2m_obj_path *path,
|
||||||
float32_value_t *value)
|
double *value)
|
||||||
{
|
{
|
||||||
struct tlv_out_formatter_data *fd;
|
struct tlv_out_formatter_data *fd;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct oma_tlv tlv;
|
struct oma_tlv tlv;
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t b32[4];
|
uint8_t b64[8];
|
||||||
|
|
||||||
fd = engine_get_out_user_data(out);
|
fd = engine_get_out_user_data(out);
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lwm2m_f32_to_b32(value, b32, sizeof(b32));
|
ret = lwm2m_float_to_b64(value, b64, sizeof(b64));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_ERR("float32 conversion error: %d", ret);
|
LOG_ERR("float32 conversion error: %d", ret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
|
tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
|
||||||
tlv_calc_id(fd->writer_flags, path), sizeof(b32));
|
tlv_calc_id(fd->writer_flags, path), sizeof(b64));
|
||||||
len = oma_tlv_put(&tlv, out, b32, false);
|
len = oma_tlv_put(&tlv, out, b64, false);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,8 +647,8 @@ static size_t get_string(struct lwm2m_input_context *in,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert float to fixpoint */
|
/* convert float to fixpoint */
|
||||||
static size_t get_float32fix(struct lwm2m_input_context *in,
|
static size_t get_float(struct lwm2m_input_context *in,
|
||||||
float32_value_t *value)
|
double *value)
|
||||||
{
|
{
|
||||||
struct oma_tlv tlv;
|
struct oma_tlv tlv;
|
||||||
size_t size = oma_tlv_get(&tlv, in, false);
|
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) {
|
if (tlv.length == 4U) {
|
||||||
ret = lwm2m_b32_to_f32(buf, 4, value);
|
ret = lwm2m_b32_to_float(buf, 4, value);
|
||||||
} else {
|
} else {
|
||||||
ret = lwm2m_b64_to_f32(buf, 8, value);
|
ret = lwm2m_b64_to_float(buf, 8, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -752,7 +752,7 @@ const struct lwm2m_writer oma_tlv_writer = {
|
||||||
.put_s32 = put_s32,
|
.put_s32 = put_s32,
|
||||||
.put_s64 = put_s64,
|
.put_s64 = put_s64,
|
||||||
.put_string = put_string,
|
.put_string = put_string,
|
||||||
.put_float32fix = put_float32fix,
|
.put_float = put_float,
|
||||||
.put_bool = put_bool,
|
.put_bool = put_bool,
|
||||||
.put_opaque = put_opaque,
|
.put_opaque = put_opaque,
|
||||||
.put_objlnk = put_objlnk,
|
.put_objlnk = put_objlnk,
|
||||||
|
@ -762,7 +762,7 @@ const struct lwm2m_reader oma_tlv_reader = {
|
||||||
.get_s32 = get_s32,
|
.get_s32 = get_s32,
|
||||||
.get_s64 = get_s64,
|
.get_s64 = get_s64,
|
||||||
.get_string = get_string,
|
.get_string = get_string,
|
||||||
.get_float32fix = get_float32fix,
|
.get_float = get_float,
|
||||||
.get_bool = get_bool,
|
.get_bool = get_bool,
|
||||||
.get_opaque = get_opaque,
|
.get_opaque = get_opaque,
|
||||||
.get_objlnk = get_objlnk,
|
.get_objlnk = get_objlnk,
|
||||||
|
|
|
@ -74,7 +74,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#include "lwm2m_util.h"
|
#include "lwm2m_util.h"
|
||||||
|
|
||||||
/* some temporary buffer space for format conversions */
|
/* 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,
|
size_t plain_text_put_format(struct lwm2m_output_context *out,
|
||||||
const char *format, ...)
|
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);
|
return plain_text_put_format(out, "%lld", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t plain_text_put_float32fix(struct lwm2m_output_context *out,
|
size_t plain_text_put_float(struct lwm2m_output_context *out,
|
||||||
struct lwm2m_obj_path *path,
|
struct lwm2m_obj_path *path,
|
||||||
float32_value_t *value)
|
double *value)
|
||||||
{
|
{
|
||||||
size_t len;
|
int len = lwm2m_ftoa(value, pt_buffer, sizeof(pt_buffer), 15);
|
||||||
char buf[sizeof("000000")];
|
|
||||||
|
|
||||||
/* value of 123 -> "000123" -- ignore sign */
|
if (len < 0 || len >= sizeof(pt_buffer)) {
|
||||||
len = snprintk(buf, sizeof(buf), "%06d", abs(value->val2));
|
LOG_ERR("Failed to encode float value");
|
||||||
if (len != 6U) {
|
return 0;
|
||||||
strcpy(buf, "0");
|
|
||||||
} else {
|
|
||||||
/* clear ending zeroes, but leave 1 if needed */
|
|
||||||
while (len > 1U && buf[len - 1] == '0') {
|
|
||||||
buf[--len] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return plain_text_put_format(out, "%s%d.%s",
|
if (buf_append(CPKT_BUF_WRITE(out->out_cpkt), pt_buffer, len) < 0) {
|
||||||
/* handle negative val2 when val1 is 0 */
|
return 0;
|
||||||
(value->val1 == 0 && value->val2 < 0) ?
|
}
|
||||||
"-" : "",
|
|
||||||
value->val1, buf);
|
return (size_t)len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t put_string(struct lwm2m_output_context *out,
|
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;
|
return (size_t)in_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_float32fix(struct lwm2m_input_context *in,
|
static size_t get_float(struct lwm2m_input_context *in,
|
||||||
float32_value_t *value)
|
double *value)
|
||||||
{
|
{
|
||||||
size_t i = 0, len = 0;
|
size_t i = 0, len = 0;
|
||||||
bool has_dot = false;
|
bool has_dot = false;
|
||||||
|
@ -290,7 +283,7 @@ static size_t get_float32fix(struct lwm2m_input_context *in,
|
||||||
|
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
||||||
if (lwm2m_atof32(buf, value) != 0) {
|
if (lwm2m_atof(buf, value) != 0) {
|
||||||
LOG_ERR("Failed to parse float value");
|
LOG_ERR("Failed to parse float value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +373,7 @@ const struct lwm2m_writer plain_text_writer = {
|
||||||
.put_s32 = put_s32,
|
.put_s32 = put_s32,
|
||||||
.put_s64 = put_s64,
|
.put_s64 = put_s64,
|
||||||
.put_string = put_string,
|
.put_string = put_string,
|
||||||
.put_float32fix = plain_text_put_float32fix,
|
.put_float = plain_text_put_float,
|
||||||
.put_bool = put_bool,
|
.put_bool = put_bool,
|
||||||
.put_objlnk = put_objlnk,
|
.put_objlnk = put_objlnk,
|
||||||
};
|
};
|
||||||
|
@ -389,7 +382,7 @@ const struct lwm2m_reader plain_text_reader = {
|
||||||
.get_s32 = get_s32,
|
.get_s32 = get_s32,
|
||||||
.get_s64 = get_s64,
|
.get_s64 = get_s64,
|
||||||
.get_string = get_string,
|
.get_string = get_string,
|
||||||
.get_float32fix = get_float32fix,
|
.get_float = get_float,
|
||||||
.get_bool = get_bool,
|
.get_bool = get_bool,
|
||||||
.get_opaque = get_opaque,
|
.get_opaque = get_opaque,
|
||||||
.get_objlnk = get_objlnk,
|
.get_objlnk = get_objlnk,
|
||||||
|
|
|
@ -52,9 +52,9 @@ extern const struct lwm2m_reader plain_text_reader;
|
||||||
size_t plain_text_put_format(struct lwm2m_output_context *out,
|
size_t plain_text_put_format(struct lwm2m_output_context *out,
|
||||||
const char *format, ...);
|
const char *format, ...);
|
||||||
|
|
||||||
size_t plain_text_put_float32fix(struct lwm2m_output_context *out,
|
size_t plain_text_put_float(struct lwm2m_output_context *out,
|
||||||
struct lwm2m_obj_path *path,
|
struct lwm2m_obj_path *path,
|
||||||
float32_value_t *value);
|
double *value);
|
||||||
|
|
||||||
|
|
||||||
int do_read_op_plain_text(struct lwm2m_message *msg, int content_format);
|
int do_read_op_plain_text(struct lwm2m_message *msg, int content_format);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "lwm2m_util.h"
|
#include "lwm2m_util.h"
|
||||||
|
@ -12,10 +13,17 @@
|
||||||
#define SHIFT_LEFT(v, o, m) (((v) << (o)) & (m))
|
#define SHIFT_LEFT(v, o, m) (((v) << (o)) & (m))
|
||||||
#define SHIFT_RIGHT(v, o, m) (((v) >> (o)) & (m))
|
#define SHIFT_RIGHT(v, o, m) (((v) >> (o)) & (m))
|
||||||
|
|
||||||
/* convert from float32 to binary32 */
|
#define PRECISION64_LEN 17U
|
||||||
int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len)
|
#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 e = -1, v, f = 0;
|
||||||
|
int32_t val1 = (int32_t)*in;
|
||||||
|
int32_t val2 = (*in - (int32_t)*in) * PRECISION32;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (len != 4) {
|
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 */
|
/* handle zero value special case */
|
||||||
if (f32->val1 == 0 && f32->val2 == 0) {
|
if (val1 == 0 && val2 == 0) {
|
||||||
memset(b32, 0, len);
|
memset(b32, 0, len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sign handled later */
|
/* sign handled later */
|
||||||
v = abs(f32->val1);
|
v = abs(val1);
|
||||||
|
|
||||||
/* add whole value to fraction */
|
/* add whole value to fraction */
|
||||||
while (v > 0) {
|
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 */
|
/* sign handled later */
|
||||||
v = abs(f32->val2);
|
v = abs(val2);
|
||||||
|
|
||||||
/* add decimal to fraction */
|
/* add decimal to fraction */
|
||||||
i = e;
|
i = e;
|
||||||
while (v > 0 && i < 23) {
|
while (v > 0 && i < 23) {
|
||||||
v *= 2;
|
v *= 2;
|
||||||
if (!f && e < 0 && v < LWM2M_FLOAT32_DEC_MAX) {
|
if (!f && e < 0 && v < PRECISION32) {
|
||||||
/* handle -e */
|
/* handle -e */
|
||||||
e--;
|
e--;
|
||||||
continue;
|
continue;
|
||||||
} else if (v >= LWM2M_FLOAT32_DEC_MAX) {
|
} else if (v >= PRECISION32) {
|
||||||
v -= LWM2M_FLOAT32_DEC_MAX;
|
v -= PRECISION32;
|
||||||
f |= 1 << (22 - i);
|
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);
|
memset(b32, 0, len);
|
||||||
|
|
||||||
/* sign: bit 31 */
|
/* sign: bit 31 */
|
||||||
if (f32->val1 == 0) {
|
if (val1 == 0) {
|
||||||
b32[0] = f32->val2 < 0 ? 0x80 : 0;
|
b32[0] = val2 < 0 ? 0x80 : 0;
|
||||||
} else {
|
} else {
|
||||||
b32[0] = f32->val1 < 0 ? 0x80 : 0;
|
b32[0] = val1 < 0 ? 0x80 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exponent: bits 30-23 */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert from float32 to binary64 */
|
/* convert from float to binary64 */
|
||||||
int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len)
|
int lwm2m_float_to_b64(double *in, uint8_t *b64, size_t len)
|
||||||
{
|
{
|
||||||
int64_t v, f = 0;
|
int64_t v, f = 0;
|
||||||
int32_t e = -1;
|
int32_t e = -1;
|
||||||
|
int64_t val1 = (int64_t)*in;
|
||||||
|
int64_t val2 = (*in - (int64_t)*in) * PRECISION64;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (len != 8) {
|
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 */
|
/* handle zero value special case */
|
||||||
if (f32->val1 == 0 && f32->val2 == 0) {
|
if (val1 == 0 && val2 == 0) {
|
||||||
memset(b64, 0, len);
|
memset(b64, 0, len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sign handled later */
|
/* sign handled later */
|
||||||
v = abs(f32->val1);
|
v = llabs(val1);
|
||||||
|
|
||||||
/* add whole value to fraction */
|
/* add whole value to fraction */
|
||||||
while (v > 0) {
|
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 */
|
/* sign handled later */
|
||||||
v = abs(f32->val2);
|
v = llabs(val2);
|
||||||
|
|
||||||
/* add decimal to fraction */
|
/* add decimal to fraction */
|
||||||
i = e;
|
i = e;
|
||||||
while (v > 0 && i < 52) {
|
while (v > 0 && i < 52) {
|
||||||
v *= 2;
|
v *= 2;
|
||||||
if (!f && e < 0 && v < LWM2M_FLOAT32_DEC_MAX) {
|
if (!f && e < 0 && v < PRECISION64) {
|
||||||
/* handle -e */
|
/* handle -e */
|
||||||
e--;
|
e--;
|
||||||
continue;
|
continue;
|
||||||
} else if (v >= LWM2M_FLOAT32_DEC_MAX) {
|
} else if (v >= PRECISION64) {
|
||||||
v -= LWM2M_FLOAT32_DEC_MAX;
|
v -= PRECISION64;
|
||||||
f |= (int64_t)1 << (51 - i);
|
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);
|
memset(b64, 0, len);
|
||||||
|
|
||||||
/* sign: bit 63 */
|
/* sign: bit 63 */
|
||||||
if (f32->val1 == 0) {
|
if (val1 == 0) {
|
||||||
b64[0] = f32->val2 < 0 ? 0x80 : 0;
|
b64[0] = val2 < 0 ? 0x80 : 0;
|
||||||
} else {
|
} else {
|
||||||
b64[0] = f32->val1 < 0 ? 0x80 : 0;
|
b64[0] = val1 < 0 ? 0x80 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exponent: bits 62-52 */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert from binary32 to float32 */
|
/* convert from binary32 to float */
|
||||||
int lwm2m_b32_to_f32(uint8_t *b32, size_t len, float32_value_t *f32)
|
int lwm2m_b32_to_float(uint8_t *b32, size_t len, double *out)
|
||||||
{
|
{
|
||||||
int32_t f, k, i, e;
|
int32_t f, k, i, e;
|
||||||
bool sign = false;
|
bool sign = false;
|
||||||
|
int32_t val1, val2;
|
||||||
|
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32->val1 = 0;
|
val1 = 0;
|
||||||
f32->val2 = 0;
|
val2 = 0;
|
||||||
|
|
||||||
/* calc sign: bit 31 */
|
/* calc sign: bit 31 */
|
||||||
sign = SHIFT_RIGHT(b32[0], 7, 0x1);
|
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;
|
e = 23;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32->val1 = (f >> (23 - e)) * (sign ? -1 : 1);
|
val1 = (f >> (23 - e)) * (sign ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the rest of the decimal */
|
/* calculate the rest of the decimal */
|
||||||
k = LWM2M_FLOAT32_DEC_MAX;
|
k = PRECISION32;
|
||||||
|
|
||||||
/* account for -e */
|
/* account for -e */
|
||||||
while (e < -1) {
|
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--) {
|
for (i = 22 - e; i >= 0; i--) {
|
||||||
k /= 2;
|
k /= 2;
|
||||||
if (f & (1 << i)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert from binary64 to float32 */
|
/* convert from binary64 to float */
|
||||||
int lwm2m_b64_to_f32(uint8_t *b64, size_t len, float32_value_t *f32)
|
int lwm2m_b64_to_float(uint8_t *b64, size_t len, double *out)
|
||||||
{
|
{
|
||||||
int64_t f, k;
|
int64_t f, k;
|
||||||
int i, e;
|
int i, e;
|
||||||
bool sign = false;
|
bool sign = false;
|
||||||
|
int64_t val1, val2;
|
||||||
|
|
||||||
if (len != 8) {
|
if (len != 8) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32->val1 = 0LL;
|
val1 = 0LL;
|
||||||
f32->val2 = 0LL;
|
val2 = 0LL;
|
||||||
|
|
||||||
/* calc sign: bit 63 */
|
/* calc sign: bit 63 */
|
||||||
sign = SHIFT_RIGHT(b64[0], 7, 0x1);
|
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;
|
e = 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32->val1 = (f >> (52 - e)) * (sign ? -1 : 1);
|
val1 = (f >> (52 - e)) * (sign ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the rest of the decimal */
|
/* calculate the rest of the decimal */
|
||||||
k = LWM2M_FLOAT32_DEC_MAX;
|
k = PRECISION64;
|
||||||
|
|
||||||
/* account for -e */
|
/* account for -e */
|
||||||
while (e < -1) {
|
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--) {
|
for (i = 51 - e; i >= 0; i--) {
|
||||||
k /= 2;
|
k /= 2;
|
||||||
if (f & ((int64_t)1 << i)) {
|
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;
|
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];
|
char *pos, *end, buf[24];
|
||||||
long val;
|
long val;
|
||||||
int32_t base = LWM2M_FLOAT32_DEC_MAX, sign = 1;
|
int64_t base = PRECISION64, sign = 1;
|
||||||
|
int64_t val1, val2;
|
||||||
|
|
||||||
if (!input || !out) {
|
if (!input || !out) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -326,18 +351,71 @@ int lwm2m_atof32(const char *input, float32_value_t *out)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->val1 = (int32_t) val;
|
val1 = (int64_t)val;
|
||||||
out->val2 = 0;
|
val2 = 0;
|
||||||
|
|
||||||
if (!pos) {
|
if (!pos) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*(++pos) && base > 1 && isdigit((unsigned char)*pos)) {
|
while (*(++pos) && base > 1 && isdigit((unsigned char)*pos)) {
|
||||||
out->val2 = out->val2 * 10 + (*pos - '0');
|
val2 = val2 * 10 + (*pos - '0');
|
||||||
base /= 10;
|
base /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->val2 *= sign * base;
|
val2 *= sign * base;
|
||||||
|
|
||||||
|
*out = (double)val1 + (double)val2 / PRECISION64;
|
||||||
|
|
||||||
return !*pos || base == 1 ? 0 : -EINVAL;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -9,15 +9,17 @@
|
||||||
|
|
||||||
#include <net/lwm2m.h>
|
#include <net/lwm2m.h>
|
||||||
|
|
||||||
/* convert float struct to binary format */
|
/* convert float to binary format */
|
||||||
int lwm2m_f32_to_b32(float32_value_t *f32, uint8_t *b32, size_t len);
|
int lwm2m_float_to_b32(double *in, uint8_t *b32, size_t len);
|
||||||
int lwm2m_f32_to_b64(float32_value_t *f32, uint8_t *b64, size_t len);
|
int lwm2m_float_to_b64(double *in, uint8_t *b64, size_t len);
|
||||||
|
|
||||||
/* convert binary format to float struct */
|
/* convert binary format to float */
|
||||||
int lwm2m_b32_to_f32(uint8_t *b32, size_t len, float32_value_t *f32);
|
int lwm2m_b32_to_float(uint8_t *b32, size_t len, double *out);
|
||||||
int lwm2m_b64_to_f32(uint8_t *b64, size_t len, float32_value_t *f32);
|
int lwm2m_b64_to_float(uint8_t *b64, size_t len, double *out);
|
||||||
|
|
||||||
/* convert string to float struct */
|
/* convert string to float */
|
||||||
int lwm2m_atof32(const char *input, float32_value_t *out);
|
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_ */
|
#endif /* LWM2M_UTIL_H_ */
|
||||||
|
|
Loading…
Reference in a new issue