net: lwm2m: Add ObjLnk resource type support
Implement LWM2M ObjLnk resource type and plaintext, TLV and JSON readers/writers. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
9a034c611d
commit
bd7d6926c4
7 changed files with 187 additions and 6 deletions
|
@ -216,7 +216,7 @@ Example LwM2M object and resources: Device
|
||||||
- R
|
- R
|
||||||
- Multiple
|
- Multiple
|
||||||
- Optional
|
- Optional
|
||||||
- ObjLink
|
- ObjLnk
|
||||||
|
|
||||||
The server could query the ``Manufacturer`` resource for ``Device`` object
|
The server could query the ``Manufacturer`` resource for ``Device`` object
|
||||||
instance 0 (the default and only instance) by sending a ``READ 3/0/0``
|
instance 0 (the default and only instance) by sending a ``READ 3/0/0``
|
||||||
|
|
|
@ -341,6 +341,19 @@ typedef struct float64_value {
|
||||||
int64_t val2;
|
int64_t val2;
|
||||||
} float64_value_t;
|
} float64_value_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum value for ObjLnk resource fields
|
||||||
|
*/
|
||||||
|
#define LWM2M_OBJLNK_MAX_ID USHRT_MAX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LWM2M ObjLnk resource type structure
|
||||||
|
*/
|
||||||
|
struct lwm2m_objlnk {
|
||||||
|
uint16_t obj_id;
|
||||||
|
uint16_t obj_inst;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an LwM2M object instance.
|
* @brief Create an LwM2M object instance.
|
||||||
*
|
*
|
||||||
|
@ -485,6 +498,16 @@ int lwm2m_engine_set_float32(char *pathstr, float32_value_t *value);
|
||||||
*/
|
*/
|
||||||
int lwm2m_engine_set_float64(char *pathstr, float64_value_t *value);
|
int lwm2m_engine_set_float64(char *pathstr, float64_value_t *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set resource (instance) value (ObjLnk)
|
||||||
|
*
|
||||||
|
* @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
|
||||||
|
* @param[in] value pointer to the lwm2m_objlnk structure
|
||||||
|
*
|
||||||
|
* @return 0 for success or negative in case of error.
|
||||||
|
*/
|
||||||
|
int lwm2m_engine_set_objlnk(char *pathstr, struct lwm2m_objlnk *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get resource (instance) value (opaque buffer)
|
* @brief Get resource (instance) value (opaque buffer)
|
||||||
*
|
*
|
||||||
|
@ -617,6 +640,17 @@ int lwm2m_engine_get_float32(char *pathstr, float32_value_t *buf);
|
||||||
*/
|
*/
|
||||||
int lwm2m_engine_get_float64(char *pathstr, float64_value_t *buf);
|
int lwm2m_engine_get_float64(char *pathstr, float64_value_t *buf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get resource (instance) value (ObjLnk)
|
||||||
|
*
|
||||||
|
* @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
|
||||||
|
* @param[out] buf lwm2m_objlnk buffer to copy data into
|
||||||
|
*
|
||||||
|
* @return 0 for success or negative in case of error.
|
||||||
|
*/
|
||||||
|
int lwm2m_engine_get_objlnk(char *pathstr, struct lwm2m_objlnk *buf);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set resource (instance) read callback
|
* @brief Set resource (instance) read callback
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,11 +12,6 @@
|
||||||
* Joel Hoglund <joel@sics.se>
|
* Joel Hoglund <joel@sics.se>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
* - Handle Resource ObjLink type
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LOG_MODULE_NAME net_lwm2m_engine
|
#define LOG_MODULE_NAME net_lwm2m_engine
|
||||||
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL
|
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL
|
||||||
|
|
||||||
|
@ -1501,6 +1496,11 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len)
|
||||||
((float64_value_t *)value)->val2;
|
((float64_value_t *)value)->val2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LWM2M_RES_TYPE_OBJLNK:
|
||||||
|
*((struct lwm2m_objlnk *)data_ptr) =
|
||||||
|
*(struct lwm2m_objlnk *)value;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERR("unknown obj data_type %d", obj_field->data_type);
|
LOG_ERR("unknown obj data_type %d", obj_field->data_type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1587,6 +1587,11 @@ int lwm2m_engine_set_float64(char *pathstr, float64_value_t *value)
|
||||||
return lwm2m_engine_set(pathstr, value, sizeof(float64_value_t));
|
return lwm2m_engine_set(pathstr, value, sizeof(float64_value_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lwm2m_engine_set_objlnk(char *pathstr, struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
return lwm2m_engine_set(pathstr, value, sizeof(struct lwm2m_objlnk));
|
||||||
|
}
|
||||||
|
|
||||||
/* user data getter functions */
|
/* user data getter functions */
|
||||||
|
|
||||||
int lwm2m_engine_get_res_data(char *pathstr, void **data_ptr, uint16_t *data_len,
|
int lwm2m_engine_get_res_data(char *pathstr, void **data_ptr, uint16_t *data_len,
|
||||||
|
@ -1739,6 +1744,11 @@ static int lwm2m_engine_get(char *pathstr, void *buf, uint16_t buflen)
|
||||||
((float64_value_t *)data_ptr)->val2;
|
((float64_value_t *)data_ptr)->val2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LWM2M_RES_TYPE_OBJLNK:
|
||||||
|
*(struct lwm2m_objlnk *)buf =
|
||||||
|
*(struct lwm2m_objlnk *)data_ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERR("unknown obj data_type %d",
|
LOG_ERR("unknown obj data_type %d",
|
||||||
obj_field->data_type);
|
obj_field->data_type);
|
||||||
|
@ -1823,6 +1833,11 @@ int lwm2m_engine_get_float64(char *pathstr, float64_value_t *buf)
|
||||||
return lwm2m_engine_get(pathstr, buf, sizeof(float64_value_t));
|
return lwm2m_engine_get(pathstr, buf, sizeof(float64_value_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lwm2m_engine_get_objlnk(char *pathstr, struct lwm2m_objlnk *buf)
|
||||||
|
{
|
||||||
|
return lwm2m_engine_get(pathstr, buf, sizeof(struct lwm2m_objlnk));
|
||||||
|
}
|
||||||
|
|
||||||
int lwm2m_engine_get_resource(char *pathstr, struct lwm2m_engine_res **res)
|
int lwm2m_engine_get_resource(char *pathstr, struct lwm2m_engine_res **res)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2159,6 +2174,11 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||||
(float64_value_t *)data_ptr);
|
(float64_value_t *)data_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LWM2M_RES_TYPE_OBJLNK:
|
||||||
|
engine_put_objlnk(&msg->out, &msg->path,
|
||||||
|
(struct lwm2m_objlnk *)data_ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERR("unknown obj data_type %d",
|
LOG_ERR("unknown obj data_type %d",
|
||||||
obj_field->data_type);
|
obj_field->data_type);
|
||||||
|
@ -2386,6 +2406,12 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||||
len = sizeof(float64_value_t);
|
len = sizeof(float64_value_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LWM2M_RES_TYPE_OBJLNK:
|
||||||
|
engine_get_objlnk(&msg->in,
|
||||||
|
(struct lwm2m_objlnk *)data_ptr);
|
||||||
|
len = sizeof(struct lwm2m_objlnk);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERR("unknown obj data_type %d",
|
LOG_ERR("unknown obj data_type %d",
|
||||||
obj_field->data_type);
|
obj_field->data_type);
|
||||||
|
|
|
@ -124,6 +124,7 @@
|
||||||
#define LWM2M_RES_TYPE_TIME 12
|
#define LWM2M_RES_TYPE_TIME 12
|
||||||
#define LWM2M_RES_TYPE_FLOAT32 13
|
#define LWM2M_RES_TYPE_FLOAT32 13
|
||||||
#define LWM2M_RES_TYPE_FLOAT64 14
|
#define LWM2M_RES_TYPE_FLOAT64 14
|
||||||
|
#define LWM2M_RES_TYPE_OBJLNK 15
|
||||||
|
|
||||||
/* remember that we have already output a value - can be between two block's */
|
/* remember that we have already output a value - can be between two block's */
|
||||||
#define WRITER_OUTPUT_VALUE 1
|
#define WRITER_OUTPUT_VALUE 1
|
||||||
|
@ -470,6 +471,9 @@ struct lwm2m_writer {
|
||||||
size_t (*put_opaque)(struct lwm2m_output_context *out,
|
size_t (*put_opaque)(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_objlnk)(struct lwm2m_output_context *out,
|
||||||
|
struct lwm2m_obj_path *path,
|
||||||
|
struct lwm2m_objlnk *value);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lwm2m_reader {
|
struct lwm2m_reader {
|
||||||
|
@ -487,6 +491,8 @@ struct lwm2m_reader {
|
||||||
bool *value);
|
bool *value);
|
||||||
size_t (*get_opaque)(struct lwm2m_input_context *in,
|
size_t (*get_opaque)(struct lwm2m_input_context *in,
|
||||||
uint8_t *buf, size_t buflen, bool *last_block);
|
uint8_t *buf, size_t buflen, bool *last_block);
|
||||||
|
size_t (*get_objlnk)(struct lwm2m_input_context *in,
|
||||||
|
struct lwm2m_objlnk *value);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* output user_data management functions */
|
/* output user_data management functions */
|
||||||
|
@ -674,6 +680,13 @@ static inline size_t engine_put_opaque(struct lwm2m_output_context *out,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t engine_put_objlnk(struct lwm2m_output_context *out,
|
||||||
|
struct lwm2m_obj_path *path,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
return out->writer->put_objlnk(out, path, value);
|
||||||
|
}
|
||||||
|
|
||||||
static inline size_t engine_get_s32(struct lwm2m_input_context *in,
|
static inline size_t engine_get_s32(struct lwm2m_input_context *in,
|
||||||
int32_t *value)
|
int32_t *value)
|
||||||
{
|
{
|
||||||
|
@ -721,4 +734,10 @@ static inline size_t engine_get_opaque(struct lwm2m_input_context *in,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t engine_get_objlnk(struct lwm2m_input_context *in,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
return in->reader->get_objlnk(in, value);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LWM2M_OBJECT_H_ */
|
#endif /* LWM2M_OBJECT_H_ */
|
||||||
|
|
|
@ -526,6 +526,20 @@ static size_t put_bool(struct lwm2m_output_context *out,
|
||||||
return (size_t)len;
|
return (size_t)len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t put_objlnk(struct lwm2m_output_context *out,
|
||||||
|
struct lwm2m_obj_path *path,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = put_json_prefix(out, path, "\"ov\"");
|
||||||
|
len += plain_text_put_format(out, "\"%u:%u\"", value->obj_id,
|
||||||
|
value->obj_inst);
|
||||||
|
len += put_json_postfix(out);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t read_number(struct lwm2m_input_context *in,
|
static size_t read_number(struct lwm2m_input_context *in,
|
||||||
int64_t *value1, int64_t *value2,
|
int64_t *value1, int64_t *value2,
|
||||||
bool accept_sign, bool accept_dot)
|
bool accept_sign, bool accept_dot)
|
||||||
|
@ -676,6 +690,37 @@ static size_t get_opaque(struct lwm2m_input_context *in,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t get_objlnk(struct lwm2m_input_context *in,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
int64_t tmp;
|
||||||
|
size_t len;
|
||||||
|
uint16_t value_offset;
|
||||||
|
struct json_in_formatter_data *fd;
|
||||||
|
|
||||||
|
fd = engine_get_in_user_data(in);
|
||||||
|
if (!fd) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the original value offset. */
|
||||||
|
value_offset = fd->value_offset;
|
||||||
|
|
||||||
|
len = read_number(in, &tmp, NULL, false, false);
|
||||||
|
value->obj_id = (uint16_t)tmp;
|
||||||
|
|
||||||
|
len++; /* +1 for ':' delimeter. */
|
||||||
|
fd->value_offset += len;
|
||||||
|
|
||||||
|
len += read_number(in, &tmp, NULL, false, false);
|
||||||
|
value->obj_inst = (uint16_t)tmp;
|
||||||
|
|
||||||
|
/* Restore the original value offset. */
|
||||||
|
fd->value_offset = value_offset;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
const struct lwm2m_writer json_writer = {
|
const struct lwm2m_writer json_writer = {
|
||||||
.put_begin = put_begin,
|
.put_begin = put_begin,
|
||||||
.put_end = put_end,
|
.put_end = put_end,
|
||||||
|
@ -689,6 +734,7 @@ const struct lwm2m_writer json_writer = {
|
||||||
.put_float32fix = put_float32fix,
|
.put_float32fix = put_float32fix,
|
||||||
.put_float64fix = put_float64fix,
|
.put_float64fix = put_float64fix,
|
||||||
.put_bool = put_bool,
|
.put_bool = put_bool,
|
||||||
|
.put_objlnk = put_objlnk,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct lwm2m_reader json_reader = {
|
const struct lwm2m_reader json_reader = {
|
||||||
|
@ -699,6 +745,7 @@ const struct lwm2m_reader json_reader = {
|
||||||
.get_float64fix = get_float64fix,
|
.get_float64fix = get_float64fix,
|
||||||
.get_bool = get_bool,
|
.get_bool = get_bool,
|
||||||
.get_opaque = get_opaque,
|
.get_opaque = get_opaque,
|
||||||
|
.get_objlnk = get_objlnk,
|
||||||
};
|
};
|
||||||
|
|
||||||
int do_read_op_json(struct lwm2m_message *msg, int content_format)
|
int do_read_op_json(struct lwm2m_message *msg, int content_format)
|
||||||
|
|
|
@ -566,6 +566,15 @@ static size_t put_opaque(struct lwm2m_output_context *out,
|
||||||
return put_string(out, path, buf, buflen);
|
return put_string(out, path, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t put_objlnk(struct lwm2m_output_context *out,
|
||||||
|
struct lwm2m_obj_path *path,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
int32_t value_s32 = (value->obj_id << 16) | value->obj_inst;
|
||||||
|
|
||||||
|
return put_s32(out, path, value_s32);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t get_number(struct lwm2m_input_context *in, int64_t *value,
|
static size_t get_number(struct lwm2m_input_context *in, int64_t *value,
|
||||||
uint8_t max_len)
|
uint8_t max_len)
|
||||||
{
|
{
|
||||||
|
@ -758,6 +767,20 @@ static size_t get_opaque(struct lwm2m_input_context *in,
|
||||||
return lwm2m_engine_get_opaque_more(in, value, buflen, last_block);
|
return lwm2m_engine_get_opaque_more(in, value, buflen, last_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t get_objlnk(struct lwm2m_input_context *in,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
int32_t value_s32;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = get_s32(in, &value_s32);
|
||||||
|
|
||||||
|
value->obj_id = (value_s32 >> 16) & 0xFFFF;
|
||||||
|
value->obj_inst = value_s32 && 0xFFFF;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
const struct lwm2m_writer oma_tlv_writer = {
|
const struct lwm2m_writer oma_tlv_writer = {
|
||||||
.put_begin_oi = put_begin_oi,
|
.put_begin_oi = put_begin_oi,
|
||||||
.put_end_oi = put_end_oi,
|
.put_end_oi = put_end_oi,
|
||||||
|
@ -772,6 +795,7 @@ const struct lwm2m_writer oma_tlv_writer = {
|
||||||
.put_float64fix = put_float64fix,
|
.put_float64fix = put_float64fix,
|
||||||
.put_bool = put_bool,
|
.put_bool = put_bool,
|
||||||
.put_opaque = put_opaque,
|
.put_opaque = put_opaque,
|
||||||
|
.put_objlnk = put_objlnk,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct lwm2m_reader oma_tlv_reader = {
|
const struct lwm2m_reader oma_tlv_reader = {
|
||||||
|
@ -782,6 +806,7 @@ const struct lwm2m_reader oma_tlv_reader = {
|
||||||
.get_float64fix = get_float64fix,
|
.get_float64fix = get_float64fix,
|
||||||
.get_bool = get_bool,
|
.get_bool = get_bool,
|
||||||
.get_opaque = get_opaque,
|
.get_opaque = get_opaque,
|
||||||
|
.get_objlnk = get_objlnk,
|
||||||
};
|
};
|
||||||
|
|
||||||
int do_read_op_tlv(struct lwm2m_message *msg, int content_format)
|
int do_read_op_tlv(struct lwm2m_message *msg, int content_format)
|
||||||
|
|
|
@ -194,6 +194,14 @@ static size_t put_bool(struct lwm2m_output_context *out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t put_objlnk(struct lwm2m_output_context *out,
|
||||||
|
struct lwm2m_obj_path *path,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
return plain_text_put_format(out, "%u:%u", value->obj_id,
|
||||||
|
value->obj_inst);
|
||||||
|
}
|
||||||
|
|
||||||
static int get_length_left(struct lwm2m_input_context *in)
|
static int get_length_left(struct lwm2m_input_context *in)
|
||||||
{
|
{
|
||||||
return in->in_cpkt->offset - in->offset;
|
return in->in_cpkt->offset - in->offset;
|
||||||
|
@ -330,6 +338,26 @@ static size_t get_opaque(struct lwm2m_input_context *in,
|
||||||
return lwm2m_engine_get_opaque_more(in, value, buflen, last_block);
|
return lwm2m_engine_get_opaque_more(in, value, buflen, last_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t get_objlnk(struct lwm2m_input_context *in,
|
||||||
|
struct lwm2m_objlnk *value)
|
||||||
|
{
|
||||||
|
int64_t tmp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = plain_text_read_number(in, &tmp, NULL, false, false);
|
||||||
|
value->obj_id = (uint16_t)tmp;
|
||||||
|
|
||||||
|
/* Skip ':' delimeter. */
|
||||||
|
in->offset++;
|
||||||
|
len++;
|
||||||
|
|
||||||
|
len += plain_text_read_number(in, &tmp, NULL, false, false);
|
||||||
|
value->obj_inst = (uint16_t)tmp;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
const struct lwm2m_writer plain_text_writer = {
|
const struct lwm2m_writer plain_text_writer = {
|
||||||
.put_s8 = put_s8,
|
.put_s8 = put_s8,
|
||||||
.put_s16 = put_s16,
|
.put_s16 = put_s16,
|
||||||
|
@ -339,6 +367,7 @@ const struct lwm2m_writer plain_text_writer = {
|
||||||
.put_float32fix = plain_text_put_float32fix,
|
.put_float32fix = plain_text_put_float32fix,
|
||||||
.put_float64fix = plain_text_put_float64fix,
|
.put_float64fix = plain_text_put_float64fix,
|
||||||
.put_bool = put_bool,
|
.put_bool = put_bool,
|
||||||
|
.put_objlnk = put_objlnk,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct lwm2m_reader plain_text_reader = {
|
const struct lwm2m_reader plain_text_reader = {
|
||||||
|
@ -349,6 +378,7 @@ const struct lwm2m_reader plain_text_reader = {
|
||||||
.get_float64fix = get_float64fix,
|
.get_float64fix = get_float64fix,
|
||||||
.get_bool = get_bool,
|
.get_bool = get_bool,
|
||||||
.get_opaque = get_opaque,
|
.get_opaque = get_opaque,
|
||||||
|
.get_objlnk = get_objlnk,
|
||||||
};
|
};
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue