net: lwm2m: lwm2m utility API update

New API's
- lwm2m_string_to_path
- lwm2m_path_to_string
- lwm2m_atou16

Signed-off-by: Juha Heiskanen <juha.heiskanen@nordicsemi.no>
This commit is contained in:
Juha Heiskanen 2022-03-07 04:42:06 -08:00 committed by Anas Nashif
commit c95dd9a9c5
3 changed files with 154 additions and 94 deletions

View file

@ -867,21 +867,6 @@ int lwm2m_delete_obj_inst(uint16_t obj_id, uint16_t obj_inst_id)
/* utility functions */ /* utility functions */
static uint16_t atou16(const uint8_t *buf, uint16_t buflen, uint16_t *len)
{
uint16_t val = 0U;
uint16_t pos = 0U;
/* we should get a value first - consume all numbers */
while (pos < buflen && isdigit(buf[pos])) {
val = val * 10U + (buf[pos] - '0');
pos++;
}
*len = pos;
return val;
}
static int coap_options_to_path(struct coap_option *opt, int options_count, static int coap_options_to_path(struct coap_option *opt, int options_count,
struct lwm2m_obj_path *path) struct lwm2m_obj_path *path)
{ {
@ -891,7 +876,7 @@ static int coap_options_to_path(struct coap_option *opt, int options_count,
path->level = options_count; path->level = options_count;
for (int i = 0; i < options_count; i++) { for (int i = 0; i < options_count; i++) {
*id[i] = atou16(opt[i].value, opt[i].len, &len); *id[i] = lwm2m_atou16(opt[i].value, opt[i].len, &len);
if (len == 0U || opt[i].len != len) { if (len == 0U || opt[i].len != len) {
path->level = i; path->level = i;
break; break;
@ -1266,71 +1251,6 @@ static int select_reader(struct lwm2m_input_context *in, uint16_t format)
/* user data setter functions */ /* user data setter functions */
static int string_to_path(const char *pathstr, struct lwm2m_obj_path *path,
char delim)
{
uint16_t value, len;
int i, tokstart = -1, toklen;
int end_index = strlen(pathstr) - 1;
(void)memset(path, 0, sizeof(*path));
for (i = 0; i <= end_index; i++) {
/* search for first numeric */
if (tokstart == -1) {
if (!isdigit((unsigned char)pathstr[i])) {
continue;
}
tokstart = i;
}
/* find delimiter char or end of string */
if (pathstr[i] == delim || i == end_index) {
toklen = i - tokstart + 1;
/* don't process delimiter char */
if (pathstr[i] == delim) {
toklen--;
}
if (toklen <= 0) {
continue;
}
value = atou16(&pathstr[tokstart], toklen, &len);
switch (path->level) {
case 0:
path->obj_id = value;
break;
case 1:
path->obj_inst_id = value;
break;
case 2:
path->res_id = value;
break;
case 3:
path->res_inst_id = value;
break;
default:
LOG_ERR("invalid level (%d)", path->level);
return -EINVAL;
}
/* increase the path level for each token found */
path->level++;
tokstart = -1;
}
}
return 0;
}
static int path_to_objs(const struct lwm2m_obj_path *path, static int path_to_objs(const struct lwm2m_obj_path *path,
struct lwm2m_engine_obj_inst **obj_inst, struct lwm2m_engine_obj_inst **obj_inst,
struct lwm2m_engine_obj_field **obj_field, struct lwm2m_engine_obj_field **obj_field,
@ -1445,7 +1365,7 @@ int lwm2m_engine_create_obj_inst(const char *pathstr)
LOG_DBG("path:%s", log_strdup(pathstr)); LOG_DBG("path:%s", log_strdup(pathstr));
/* translate path -> path_obj */ /* translate path -> path_obj */
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1475,7 +1395,7 @@ int lwm2m_engine_delete_obj_inst(const char *pathstr)
LOG_DBG("path: %s", log_strdup(pathstr)); LOG_DBG("path: %s", log_strdup(pathstr));
/* translate path -> path_obj */ /* translate path -> path_obj */
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1506,7 +1426,7 @@ int lwm2m_engine_set_res_data(const char *pathstr, void *data_ptr, uint16_t data
int ret = 0; int ret = 0;
/* translate path -> path_obj */ /* translate path -> path_obj */
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1551,7 +1471,7 @@ static int lwm2m_engine_set(const char *pathstr, void *value, uint16_t len)
LOG_DBG("path:%s, value:%p, len:%d", log_strdup(pathstr), value, len); LOG_DBG("path:%s, value:%p, len:%d", log_strdup(pathstr), value, len);
/* translate path -> path_obj */ /* translate path -> path_obj */
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1771,7 +1691,7 @@ int lwm2m_engine_get_res_data(const char *pathstr, void **data_ptr, uint16_t *da
int ret = 0; int ret = 0;
/* translate path -> path_obj */ /* translate path -> path_obj */
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1813,7 +1733,7 @@ static int lwm2m_engine_get(const char *pathstr, void *buf, uint16_t buflen)
LOG_DBG("path:%s, buf:%p, buflen:%d", log_strdup(pathstr), buf, buflen); LOG_DBG("path:%s, buf:%p, buflen:%d", log_strdup(pathstr), buf, buflen);
/* translate path -> path_obj */ /* translate path -> path_obj */
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1993,7 +1913,7 @@ int lwm2m_engine_get_resource(const char *pathstr, struct lwm2m_engine_res **res
int ret; int ret;
struct lwm2m_obj_path path; struct lwm2m_obj_path path;
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -2011,7 +1931,7 @@ int lwm2m_engine_update_observer_min_period(const char *pathstr, uint32_t period
int i, ret; int i, ret;
struct lwm2m_obj_path path; struct lwm2m_obj_path path;
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -2037,7 +1957,7 @@ int lwm2m_engine_update_observer_max_period(const char *pathstr, uint32_t period
int i, ret; int i, ret;
struct lwm2m_obj_path path; struct lwm2m_obj_path path;
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -2147,7 +2067,7 @@ int lwm2m_engine_create_res_inst(const char *pathstr)
struct lwm2m_engine_res_inst *res_inst = NULL; struct lwm2m_engine_res_inst *res_inst = NULL;
struct lwm2m_obj_path path; struct lwm2m_obj_path path;
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -2181,7 +2101,7 @@ int lwm2m_engine_delete_res_inst(const char *pathstr)
struct lwm2m_engine_res_inst *res_inst = NULL; struct lwm2m_engine_res_inst *res_inst = NULL;
struct lwm2m_obj_path path; struct lwm2m_obj_path path;
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -2216,7 +2136,7 @@ bool lwm2m_engine_path_is_observed(const char *pathstr)
int ret; int ret;
int i; int i;
ret = string_to_path(pathstr, &path, '/'); ret = lwm2m_string_to_path(pathstr, &path, '/');
if (ret < 0) { if (ret < 0) {
return false; return false;
} }
@ -5767,7 +5687,7 @@ int lwm2m_engine_send(struct lwm2m_ctx *ctx, char const *path_list[], uint8_t pa
/* Parse Path to internal used object path format */ /* Parse Path to internal used object path format */
for (int i = 0; i < path_list_size; i++) { for (int i = 0; i < path_list_size; i++) {
ret = string_to_path(path_list[i], &temp, '/'); ret = lwm2m_string_to_path(path_list[i], &temp, '/');
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }

View file

@ -9,6 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <inttypes.h> #include <inttypes.h>
#include "lwm2m_object.h"
#include "lwm2m_util.h" #include "lwm2m_util.h"
#define SHIFT_LEFT(v, o, m) (((v) << (o)) & (m)) #define SHIFT_LEFT(v, o, m) (((v) << (o)) & (m))
@ -422,3 +423,131 @@ int lwm2m_ftoa(double *input, char *out, size_t outlen, int8_t dec_limit)
/* handle negative val2 when val1 is 0 */ /* handle negative val2 when val1 is 0 */
(val1 == 0 && val2 < 0) ? "-" : "", (long long)val1, buf); (val1 == 0 && val2 < 0) ? "-" : "", (long long)val1, buf);
} }
int lwm2m_path_to_string(char *buf, size_t buf_size, struct lwm2m_obj_path *input, int level_max)
{
size_t fpl = 0; /* Length of the formed path */
int level;
int w;
if (!buf || buf_size < sizeof("/") || !input) {
return -EINVAL;
}
memset(buf, '\0', buf_size);
level = MIN(input->level, level_max);
/* Write path element at a time and leave space for the terminating NULL */
for (int idx = LWM2M_PATH_LEVEL_NONE; idx <= level; idx++) {
switch (idx) {
case LWM2M_PATH_LEVEL_NONE:
w = snprintk(&(buf[fpl]), buf_size - fpl, "/");
break;
case LWM2M_PATH_LEVEL_OBJECT:
w = snprintk(&(buf[fpl]), buf_size - fpl, "%" PRIu16 "/", input->obj_id);
break;
case LWM2M_PATH_LEVEL_OBJECT_INST:
w = snprintk(&(buf[fpl]), buf_size - fpl, "%" PRIu16 "/",
input->obj_inst_id);
break;
case LWM2M_PATH_LEVEL_RESOURCE:
w = snprintk(&(buf[fpl]), buf_size - fpl, "%" PRIu16 "", input->res_id);
break;
case LWM2M_PATH_LEVEL_RESOURCE_INST:
w = snprintk(&(buf[fpl]), buf_size - fpl, "/%" PRIu16 "",
input->res_inst_id);
break;
default:
__ASSERT_NO_MSG(false);
return -EINVAL;
}
if (w < 0 || w >= buf_size - fpl) {
return -ENOBUFS;
}
/* Next path element, overwrites terminating NULL */
fpl += w;
}
return fpl;
}
uint16_t lwm2m_atou16(const uint8_t *buf, uint16_t buflen, uint16_t *len)
{
uint16_t val = 0U;
uint16_t pos = 0U;
/* we should get a value first - consume all numbers */
while (pos < buflen && isdigit(buf[pos])) {
val = val * 10U + (buf[pos] - '0');
pos++;
}
*len = pos;
return val;
}
int lwm2m_string_to_path(const char *pathstr, struct lwm2m_obj_path *path,
char delim)
{
uint16_t value, len;
int i, tokstart = -1, toklen;
int end_index = strlen(pathstr) - 1;
(void)memset(path, 0, sizeof(*path));
for (i = 0; i <= end_index; i++) {
/* search for first numeric */
if (tokstart == -1) {
if (!isdigit((unsigned char)pathstr[i])) {
continue;
}
tokstart = i;
}
/* find delimiter char or end of string */
if (pathstr[i] == delim || i == end_index) {
toklen = i - tokstart + 1;
/* don't process delimiter char */
if (pathstr[i] == delim) {
toklen--;
}
if (toklen <= 0) {
continue;
}
value = lwm2m_atou16(&pathstr[tokstart], toklen, &len);
/* increase the path level for each token found */
path->level++;
switch (path->level) {
case LWM2M_PATH_LEVEL_OBJECT:
path->obj_id = value;
break;
case LWM2M_PATH_LEVEL_OBJECT_INST:
path->obj_inst_id = value;
break;
case LWM2M_PATH_LEVEL_RESOURCE:
path->res_id = value;
break;
case LWM2M_PATH_LEVEL_RESOURCE_INST:
path->res_inst_id = value;
break;
default:
return -EINVAL;
}
tokstart = -1;
}
}
return 0;
}

View file

@ -22,4 +22,15 @@ int lwm2m_atof(const char *input, double *out);
/* convert float to string */ /* convert float to string */
int lwm2m_ftoa(double *input, char *out, size_t outlen, int8_t dec_limit); int lwm2m_ftoa(double *input, char *out, size_t outlen, int8_t dec_limit);
uint16_t lwm2m_atou16(const uint8_t *buf, uint16_t buflen, uint16_t *len);
/* Forms a string from the path given as a structure
* Level zero seems to mean NONE, not the root path.
*
* returns used buffer space with '\0'
*/
int lwm2m_path_to_string(char *buf, size_t buf_size, struct lwm2m_obj_path *input, int level_max);
int lwm2m_string_to_path(const char *pathstr, struct lwm2m_obj_path *path, char delim);
#endif /* LWM2M_UTIL_H_ */ #endif /* LWM2M_UTIL_H_ */