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_rx_enable`
|
||||
|
||||
* Replaced custom LwM2M :c:struct:`float32_value` type with a native double type.
|
||||
|
||||
==========================
|
||||
|
||||
Removed APIs in this release
|
||||
|
|
|
@ -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)
|
||||
|
|
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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]));
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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]));
|
||||
|
|
|
@ -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]));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -9,15 +9,17 @@
|
|||
|
||||
#include <net/lwm2m.h>
|
||||
|
||||
/* 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_ */
|
||||
|
|
Loading…
Reference in a new issue