Skip to content

Commit

Permalink
net: lwm2m: add gateway callback to handle prefixed messages
Browse files Browse the repository at this point in the history
Adding a callback for handling lwm2m messages with prefixed paths defined
by the gateway object. If CONFIG_LWM2M_GATEWAY_OBJ_SUPPORT is set,
each path is checked for the prefix stored in the object instances of the
gateway object 25. If prefixes match the msg is passed to the gw_msg_cb.

Signed-off-by: Simon Walz <[email protected]>
  • Loading branch information
walzsi authored and fabiobaltieri committed Jan 10, 2024
1 parent e5974b2 commit 38aa4d5
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
12 changes: 11 additions & 1 deletion subsys/net/lib/lwm2m/lwm2m_message_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h"
#include "lwm2m_obj_access_control.h"
#include "lwm2m_obj_server.h"
#include "lwm2m_obj_gateway.h"
#include "lwm2m_rw_link_format.h"
#include "lwm2m_rw_oma_tlv.h"
#include "lwm2m_rw_plain_text.h"
Expand Down Expand Up @@ -479,7 +480,7 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx)
}
/* utility functions */

static int coap_options_to_path(struct coap_option *opt, int options_count,
int coap_options_to_path(struct coap_option *opt, int options_count,
struct lwm2m_obj_path *path)
{
uint16_t len,
Expand Down Expand Up @@ -2268,6 +2269,15 @@ static int handle_request(struct coap_packet *request, struct lwm2m_message *msg
msg->token = token;
}

if (IS_ENABLED(CONFIG_LWM2M_GATEWAY_OBJ_SUPPORT)) {
r = lwm2m_gw_handle_req(msg);
if (r == 0) {
return 0;
} else if (r != -ENOENT) {
goto error;
}
}

/* parse the URL path into components */
r = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options, ARRAY_SIZE(options));
if (r < 0) {
Expand Down
2 changes: 2 additions & 0 deletions subsys/net/lib/lwm2m/lwm2m_message_handling.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#define NUM_OUTPUT_BLOCK_CONTEXT CONFIG_LWM2M_NUM_OUTPUT_BLOCK_CONTEXT
#endif

int coap_options_to_path(struct coap_option *opt, int options_count,
struct lwm2m_obj_path *path);
/* LwM2M message functions */
struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx);
struct lwm2m_message *find_msg(struct coap_pending *pending, struct coap_reply *reply);
Expand Down
52 changes: 52 additions & 0 deletions subsys/net/lib/lwm2m/lwm2m_obj_gateway.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ static struct lwm2m_engine_obj_field fields[] = {
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][GATEWAY_MAX_ID];
static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
lwm2m_engine_gateway_msg_cb gateway_msg_cb[MAX_INSTANCE_COUNT];

static int prefix_validation_cb(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id,
uint8_t *data, uint16_t data_len, bool last_block,
Expand Down Expand Up @@ -146,6 +147,57 @@ static struct lwm2m_engine_obj_inst *lwm2m_gw_create(uint16_t obj_inst_id)
return &inst[index];
}

int lwm2m_gw_handle_req(struct lwm2m_message *msg)
{
struct coap_option options[4];
int ret;

ret = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options,
ARRAY_SIZE(options));
if (ret < 0) {
return ret;
}

for (int index = 0; index < MAX_INSTANCE_COUNT; index++) {
/* Skip uninitialized objects */
if (!inst[index].obj) {
continue;
}

char *prefix = device_table[index].prefix;
size_t prefix_len = strlen(prefix);

if (prefix_len != options[0].len) {
continue;
}
if (strncmp(options[0].value, prefix, prefix_len) != 0) {
continue;
}

if (gateway_msg_cb[index] == NULL) {
return -ENOENT;
}
/* Delete prefix from path*/
ret = coap_options_to_path(&options[1], ret - 1, &msg->path);
if (ret < 0) {
return ret;
}
return gateway_msg_cb[index](msg);
}
return -ENOENT;
}

int lwm2m_register_gw_callback(uint16_t obj_inst_id, lwm2m_engine_gateway_msg_cb cb)
{
for (int index = 0; index < MAX_INSTANCE_COUNT; index++) {
if (inst[index].obj_inst_id == obj_inst_id) {
gateway_msg_cb[index] = cb;
return 0;
}
}
return -ENOENT;
}

static int lwm2m_gw_init(void)
{
int ret = 0;
Expand Down
40 changes: 40 additions & 0 deletions subsys/net/lib/lwm2m/lwm2m_obj_gateway.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef __LWM2M_OBJ_GATEWAY__
#define __LWM2M_OBJ_GATEWAY__

#include <lwm2m_object.h>

/* LwM2M Gateway resource IDs */
/* clang-format off */
#define LWM2M_GATEWAY_DEVICE_RID 0
Expand All @@ -17,4 +19,42 @@
#define LWM2M_GATEWAY_IOT_DEVICE_OBJECTS_RID 3
/* clang-format on */

/**
* @brief A callback which handles the prefixed messages from the server.
*
* The callback gets triggered each time the prefix in front of a received lwm2m
* msg path matches the prefix set in the LWM2M_GATEWAY_PREFIX_RID buffer.
*
* It must handle the content of the coap message completely.
* In case of success the LwM2M engine will then send the formatted coap message,
* otherwise a coap response code is sent.
*
* Example of returning CoAP response:
* @code{.c}
* lwm2m_init_message(msg);
* // Write CoAP packet to msg->out.out_cpkt
* return 0;
* @endcode
*
*
* @return 0 if msg contains a valid CoAP response.
* @return negative error code otherwise.
*/
typedef int (*lwm2m_engine_gateway_msg_cb)(struct lwm2m_message *msg);
/**
* @brief Register a callback which handles the prefixed messages from the server.
*
* @return 0 on success
* @return -ENOENT if no object instance with obj_inst_id was found
*/
int lwm2m_register_gw_callback(uint16_t obj_inst_id, lwm2m_engine_gateway_msg_cb cb);
/**
* @brief Check if given message is handled by Gateway callback.
*
* @return 0 if msg was handled by Gateawy and contains a valid response. Negative error code
* otherwise.
* @return -ENOENT if this msg was not handled by Gateway object.
*/
int lwm2m_gw_handle_req(struct lwm2m_message *msg);

#endif /* __LWM2M_OBJ_GATEWAY__ */

0 comments on commit 38aa4d5

Please sign in to comment.