net: lwm2m: refactor engine to use lwm2m_message structure
Sending an lwm2m message is too difficult. It requires pending / reply and other structures to be configured and set by various portions of the library. There is also no way to know if a pending message ever encounters a timeout. Let's fix this by simplifying the internal LwM2M engine APIs for handling lwm2m messages: 1. A user calls lwm2m_get_message(lwm2m_ctx) which returns the first available lwm2m message from an array of messages (total # of messages is set via CONFIG_LWM2M_ENGINE_MAX_MESSAGES). 2. Next the user sets all of the fields in the message that are required (type, code message id, token, etc) 3. Then the user calls lwm2m_init_message(msg). This initializes the underlying zoap_packet, pending and reply structures. 4. Once initialized, the user creates their payload in msg->zpkt. 5. When the user is ready to send, the call lwm2m_send_message(msg). 6. And if for some reason an error occurs at any point, they can free up the entire set of structures with: lwm2m_release_message(msg). Included in the refactoring is a timeout_cb field which can be set in the LwM2M messages. If a pending structure ever expires the engine will call the timeout_cb passing in the msg structure before it's automatically released. Signed-off-by: Michael Scott <michael.scott@linaro.org>
This commit is contained in:
parent
42f3eccb38
commit
897dbffe7c
|
@ -29,6 +29,12 @@ config LWM2M_ENGINE_STACK_SIZE
|
|||
Set the stack size for the LWM2M library engine (used for handling
|
||||
OBSERVE and NOTIFY events)
|
||||
|
||||
config LWM2M_ENGINE_MAX_MESSAGES
|
||||
int "LWM2M engine max. message object"
|
||||
default 10
|
||||
help
|
||||
Set the maximum message objects for the LWM2M library client
|
||||
|
||||
config LWM2M_ENGINE_MAX_PENDING
|
||||
int "LWM2M engine max. pending objects"
|
||||
default 5
|
||||
|
|
|
@ -111,6 +111,9 @@ static struct lwm2m_engine_obj *get_engine_obj(int obj_id);
|
|||
static struct lwm2m_engine_obj_inst *get_engine_obj_inst(int obj_id,
|
||||
int obj_inst_id);
|
||||
|
||||
/* Shared set of in-flight LwM2M messages */
|
||||
static struct lwm2m_message messages[CONFIG_LWM2M_ENGINE_MAX_MESSAGES];
|
||||
|
||||
/* for debugging: to print IP addresses */
|
||||
char *lwm2m_sprint_ip_addr(const struct sockaddr *addr)
|
||||
{
|
||||
|
@ -189,7 +192,7 @@ int lwm2m_notify_observer_path(struct lwm2m_obj_path *path)
|
|||
path->res_id);
|
||||
}
|
||||
|
||||
static int engine_add_observer(struct net_app_ctx *app_ctx,
|
||||
static int engine_add_observer(struct lwm2m_message *msg,
|
||||
const u8_t *token, u8_t tkl,
|
||||
struct lwm2m_obj_path *path,
|
||||
u16_t format)
|
||||
|
@ -199,6 +202,11 @@ static int engine_add_observer(struct net_app_ctx *app_ctx,
|
|||
struct sockaddr *addr;
|
||||
int i;
|
||||
|
||||
if (!msg || !msg->ctx) {
|
||||
SYS_LOG_ERR("valid lwm2m message is required");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!token || (tkl == 0 || tkl > MAX_TOKEN_LEN)) {
|
||||
SYS_LOG_ERR("token(%p) and token length(%u) must be valid.",
|
||||
token, tkl);
|
||||
|
@ -206,7 +214,7 @@ static int engine_add_observer(struct net_app_ctx *app_ctx,
|
|||
}
|
||||
|
||||
/* remote addr */
|
||||
addr = &app_ctx->default_ctx->remote;
|
||||
addr = &msg->ctx->net_app_ctx.default_ctx->remote;
|
||||
|
||||
/* check if object exists */
|
||||
if (!get_engine_obj(path->obj_id)) {
|
||||
|
@ -243,7 +251,7 @@ static int engine_add_observer(struct net_app_ctx *app_ctx,
|
|||
|
||||
/* make sure this observer doesn't exist already */
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&engine_observer_list, obs, node) {
|
||||
if (&obs->ctx->net_app_ctx == app_ctx &&
|
||||
if (obs->ctx == msg->ctx &&
|
||||
memcmp(&obs->path, path, sizeof(*path)) == 0) {
|
||||
/* quietly update the token information */
|
||||
memcpy(obs->token, token, tkl);
|
||||
|
@ -272,8 +280,7 @@ static int engine_add_observer(struct net_app_ctx *app_ctx,
|
|||
|
||||
/* copy the values and add it to the list */
|
||||
observe_node_data[i].used = true;
|
||||
observe_node_data[i].ctx = CONTAINER_OF(app_ctx,
|
||||
struct lwm2m_ctx, net_app_ctx);
|
||||
observe_node_data[i].ctx = msg->ctx;
|
||||
memcpy(&observe_node_data[i].path, path, sizeof(*path));
|
||||
memcpy(observe_node_data[i].token, token, tkl);
|
||||
observe_node_data[i].tkl = tkl;
|
||||
|
@ -588,104 +595,192 @@ static void zoap_options_to_path(struct zoap_option *opt, int options_count,
|
|||
}
|
||||
}
|
||||
|
||||
int lwm2m_init_message(struct net_app_ctx *app_ctx, struct zoap_packet *zpkt,
|
||||
struct net_pkt **pkt, u8_t type, u8_t code, u16_t mid,
|
||||
const u8_t *token, u8_t tkl)
|
||||
struct lwm2m_message *find_msg_from_pending(struct zoap_pending *pending)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!pending) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < CONFIG_LWM2M_ENGINE_MAX_MESSAGES; i++) {
|
||||
if (messages[i].ctx && messages[i].pending == pending) {
|
||||
return &messages[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < CONFIG_LWM2M_ENGINE_MAX_MESSAGES; i++) {
|
||||
if (!messages[i].ctx) {
|
||||
messages[i].ctx = client_ctx;
|
||||
return &messages[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lwm2m_release_message(struct lwm2m_message *msg)
|
||||
{
|
||||
if (!msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->pending) {
|
||||
zoap_pending_clear(msg->pending);
|
||||
}
|
||||
|
||||
if (msg->reply) {
|
||||
/* make sure we want to clear the reply */
|
||||
zoap_reply_clear(msg->reply);
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
}
|
||||
|
||||
int lwm2m_init_message(struct lwm2m_message *msg)
|
||||
{
|
||||
struct net_pkt *pkt;
|
||||
struct net_app_ctx *app_ctx;
|
||||
struct net_buf *frag;
|
||||
int r;
|
||||
|
||||
*pkt = net_app_get_net_pkt(app_ctx, AF_UNSPEC, BUF_ALLOC_TIMEOUT);
|
||||
if (!*pkt) {
|
||||
if (!msg || !msg->ctx) {
|
||||
SYS_LOG_ERR("LwM2M message is invalid.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
app_ctx = &msg->ctx->net_app_ctx;
|
||||
pkt = net_app_get_net_pkt(app_ctx, AF_UNSPEC, BUF_ALLOC_TIMEOUT);
|
||||
if (!pkt) {
|
||||
SYS_LOG_ERR("Unable to get TX packet, not enough memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_app_get_net_buf(app_ctx, *pkt,
|
||||
BUF_ALLOC_TIMEOUT);
|
||||
frag = net_app_get_net_buf(app_ctx, pkt, BUF_ALLOC_TIMEOUT);
|
||||
if (!frag) {
|
||||
SYS_LOG_ERR("Unable to get DATA buffer, not enough memory.");
|
||||
net_pkt_unref(*pkt);
|
||||
*pkt = NULL;
|
||||
return -ENOMEM;
|
||||
r = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r = zoap_packet_init(zpkt, *pkt);
|
||||
r = zoap_packet_init(&msg->zpkt, pkt);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("zoap packet init error (err:%d)", r);
|
||||
return r;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* FIXME: Could be that zoap_packet_init() sets some defaults */
|
||||
zoap_header_set_version(zpkt, 1);
|
||||
zoap_header_set_type(zpkt, type);
|
||||
zoap_header_set_code(zpkt, code);
|
||||
zoap_header_set_version(&msg->zpkt, 1);
|
||||
zoap_header_set_type(&msg->zpkt, msg->type);
|
||||
zoap_header_set_code(&msg->zpkt, msg->code);
|
||||
|
||||
if (mid > 0) {
|
||||
zoap_header_set_id(zpkt, mid);
|
||||
if (msg->mid > 0) {
|
||||
zoap_header_set_id(&msg->zpkt, msg->mid);
|
||||
} else {
|
||||
zoap_header_set_id(zpkt, zoap_next_id());
|
||||
zoap_header_set_id(&msg->zpkt, zoap_next_id());
|
||||
}
|
||||
|
||||
/*
|
||||
* tkl == 0 is for a new TOKEN
|
||||
* tkl == LWM2M_MSG_TOKEN_LEN_SKIP means dont set
|
||||
*/
|
||||
if (tkl == 0) {
|
||||
zoap_header_set_token(zpkt, zoap_next_token(),
|
||||
if (msg->tkl == 0) {
|
||||
zoap_header_set_token(&msg->zpkt, zoap_next_token(),
|
||||
MAX_TOKEN_LEN);
|
||||
} else if (token && tkl != LWM2M_MSG_TOKEN_LEN_SKIP) {
|
||||
zoap_header_set_token(zpkt, token, tkl);
|
||||
} else if (msg->token && msg->tkl != LWM2M_MSG_TOKEN_LEN_SKIP) {
|
||||
zoap_header_set_token(&msg->zpkt, msg->token, msg->tkl);
|
||||
}
|
||||
|
||||
/* only TYPE_CON messages need pending tracking / reply handling */
|
||||
if (msg->type != ZOAP_TYPE_CON) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg->pending = zoap_pending_next_unused(
|
||||
msg->ctx->pendings,
|
||||
CONFIG_LWM2M_ENGINE_MAX_PENDING);
|
||||
if (!msg->pending) {
|
||||
SYS_LOG_ERR("Unable to find a free pending to track "
|
||||
"retransmissions.");
|
||||
r = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r = zoap_pending_init(msg->pending, &msg->zpkt,
|
||||
&app_ctx->default_ctx->remote);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("Unable to initialize a pending "
|
||||
"retransmission (err:%d).", r);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* clear out pkt to avoid double unref */
|
||||
pkt = NULL;
|
||||
|
||||
if (msg->reply_cb) {
|
||||
msg->reply = zoap_reply_next_unused(
|
||||
msg->ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!msg->reply) {
|
||||
SYS_LOG_ERR("No resources for "
|
||||
"waiting for replies.");
|
||||
r = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_reply_init(msg->reply, &msg->zpkt);
|
||||
msg->reply->reply = msg->reply_cb;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct zoap_pending *lwm2m_init_message_pending(struct lwm2m_ctx *client_ctx,
|
||||
struct zoap_packet *zpkt)
|
||||
{
|
||||
struct zoap_pending *pending = NULL;
|
||||
int ret;
|
||||
|
||||
pending = zoap_pending_next_unused(client_ctx->pendings,
|
||||
CONFIG_LWM2M_ENGINE_MAX_PENDING);
|
||||
if (!pending) {
|
||||
SYS_LOG_ERR("Unable to find a free pending to track "
|
||||
"retransmissions.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = zoap_pending_init(pending, zpkt,
|
||||
&client_ctx->net_app_ctx.default_ctx->remote);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Unable to initialize a pending "
|
||||
"retransmission (err:%d).", ret);
|
||||
pending->pkt = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
void lwm2m_init_message_cleanup(struct net_pkt *pkt,
|
||||
struct zoap_pending *pending,
|
||||
struct zoap_reply *reply)
|
||||
{
|
||||
if (pending) {
|
||||
zoap_pending_clear(pending);
|
||||
/* don't unref attached pkt twice */
|
||||
if (!pending->pkt) {
|
||||
pkt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (reply) {
|
||||
zoap_reply_clear(reply);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
lwm2m_release_message(msg);
|
||||
if (pkt) {
|
||||
net_pkt_unref(pkt);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int lwm2m_send_message(struct lwm2m_message *msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!msg || !msg->ctx) {
|
||||
SYS_LOG_ERR("LwM2M message is invalid.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg->send_attempts++;
|
||||
ret = net_app_send_pkt(&msg->ctx->net_app_ctx, msg->zpkt.pkt,
|
||||
&msg->ctx->net_app_ctx.default_ctx->remote,
|
||||
NET_SOCKADDR_MAX_SIZE, K_NO_WAIT, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (msg->type == ZOAP_TYPE_CON) {
|
||||
if (msg->send_attempts > 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
zoap_pending_cycle(msg->pending);
|
||||
k_delayed_work_submit(&msg->ctx->retransmit_work,
|
||||
msg->pending->timeout);
|
||||
} else {
|
||||
/* if we're not expecting an ACK, free up the msg data */
|
||||
lwm2m_release_message(msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16_t lwm2m_get_rd_data(u8_t *client_data, u16_t size)
|
||||
|
@ -2015,9 +2110,8 @@ static int get_observe_option(const struct zoap_packet *zpkt)
|
|||
return zoap_option_value_to_int(&option);
|
||||
}
|
||||
|
||||
static int handle_request(struct net_app_ctx *app_ctx,
|
||||
struct zoap_packet *request,
|
||||
struct zoap_packet *response)
|
||||
static int handle_request(struct zoap_packet *request,
|
||||
struct lwm2m_message *msg)
|
||||
{
|
||||
int r;
|
||||
u8_t code;
|
||||
|
@ -2040,9 +2134,9 @@ static int handle_request(struct net_app_ctx *app_ctx,
|
|||
context.path = &path;
|
||||
engine_clear_context(&context);
|
||||
|
||||
/* set ZoAP request / response */
|
||||
/* set ZoAP request / message */
|
||||
in.in_zpkt = request;
|
||||
out.out_zpkt = response;
|
||||
out.out_zpkt = &msg->zpkt;
|
||||
|
||||
/* set default reader/writer */
|
||||
in.reader = &plain_text_reader;
|
||||
|
@ -2159,8 +2253,7 @@ static int handle_request(struct net_app_ctx *app_ctx,
|
|||
r);
|
||||
}
|
||||
|
||||
r = engine_add_observer(app_ctx,
|
||||
token, tkl, &path,
|
||||
r = engine_add_observer(msg, token, tkl, &path,
|
||||
accept);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("add OBSERVE error: %d", r);
|
||||
|
@ -2248,25 +2341,16 @@ static int handle_request(struct net_app_ctx *app_ctx,
|
|||
return r;
|
||||
}
|
||||
|
||||
int lwm2m_udp_sendto(struct net_app_ctx *app_ctx, struct net_pkt *pkt)
|
||||
{
|
||||
return net_app_send_pkt(app_ctx, pkt, &app_ctx->default_ctx->remote,
|
||||
NET_SOCKADDR_MAX_SIZE, K_NO_WAIT, NULL);
|
||||
}
|
||||
|
||||
void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, struct net_pkt *pkt,
|
||||
bool handle_separate_response,
|
||||
int (*udp_request_handler)(struct net_app_ctx *app_ctx,
|
||||
struct zoap_packet *,
|
||||
struct zoap_packet *))
|
||||
udp_request_handler_cb_t udp_request_handler)
|
||||
{
|
||||
struct lwm2m_message *msg = NULL;
|
||||
struct net_udp_hdr hdr, *udp_hdr;
|
||||
struct zoap_pending *pending;
|
||||
struct zoap_reply *reply;
|
||||
struct zoap_packet response;
|
||||
struct sockaddr from_addr;
|
||||
struct zoap_packet response2;
|
||||
struct net_pkt *pkt2;
|
||||
int header_len, r;
|
||||
const u8_t *token;
|
||||
u8_t tkl;
|
||||
|
@ -2312,8 +2396,17 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, struct net_pkt *pkt,
|
|||
token = zoap_header_get_token(&response, &tkl);
|
||||
pending = zoap_pending_received(&response, client_ctx->pendings,
|
||||
CONFIG_LWM2M_ENGINE_MAX_PENDING);
|
||||
/*
|
||||
* Clear pending pointer because zoap_pending_received() calls
|
||||
* zoap_pending_clear, and later when we call lwm2m_release_message()
|
||||
* it will try and call zoap_pending_clear() again if msg->pending
|
||||
* is != NULL.
|
||||
*/
|
||||
if (pending) {
|
||||
/* TODO: If necessary cancel retransmissions */
|
||||
msg = find_msg_from_pending(pending);
|
||||
if (msg) {
|
||||
msg->pending = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SYS_LOG_DBG("checking for reply from [%s]",
|
||||
|
@ -2321,47 +2414,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, struct net_pkt *pkt,
|
|||
reply = zoap_response_received(&response, &from_addr,
|
||||
client_ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!reply) {
|
||||
/*
|
||||
* If no normal response handler is found, then this is
|
||||
* a new request coming from the server. Let's look
|
||||
* at registered objects to find a handler.
|
||||
*/
|
||||
if (udp_request_handler &&
|
||||
zoap_header_get_type(&response) == ZOAP_TYPE_CON) {
|
||||
/* Create a response packet if we reach this point */
|
||||
r = lwm2m_init_message(&client_ctx->net_app_ctx,
|
||||
&response2, &pkt2,
|
||||
ZOAP_TYPE_ACK,
|
||||
zoap_header_get_code(&response),
|
||||
zoap_header_get_id(&response),
|
||||
NULL, LWM2M_MSG_TOKEN_LEN_SKIP);
|
||||
if (r < 0) {
|
||||
if (pkt2) {
|
||||
net_pkt_unref(pkt2);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* The "response" here is actually a new request
|
||||
*/
|
||||
r = udp_request_handler(&client_ctx->net_app_ctx,
|
||||
&response, &response2);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("Request handler error: %d", r);
|
||||
} else {
|
||||
r = lwm2m_udp_sendto(&client_ctx->net_app_ctx,
|
||||
pkt2);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("Err sending response: %d",
|
||||
r);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SYS_LOG_ERR("No handler for response");
|
||||
}
|
||||
} else {
|
||||
if (reply) {
|
||||
/*
|
||||
* Separate response is composed of 2 messages, empty ACK with
|
||||
* no token and an additional message with a matching token id
|
||||
|
@ -2375,12 +2428,61 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, struct net_pkt *pkt,
|
|||
if (handle_separate_response && !tkl &&
|
||||
zoap_header_get_type(&response) == ZOAP_TYPE_ACK) {
|
||||
SYS_LOG_DBG("separated response, not removing reply");
|
||||
} else {
|
||||
SYS_LOG_DBG("reply %p handled and removed", reply);
|
||||
zoap_reply_clear(reply);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (reply || pending) {
|
||||
/* free up msg resources */
|
||||
if (msg) {
|
||||
lwm2m_release_message(msg);
|
||||
}
|
||||
|
||||
SYS_LOG_DBG("reply %p handled and removed", reply);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no normal response handler is found, then this is
|
||||
* a new request coming from the server. Let's look
|
||||
* at registered objects to find a handler.
|
||||
*/
|
||||
if (udp_request_handler &&
|
||||
zoap_header_get_type(&response) == ZOAP_TYPE_CON) {
|
||||
msg = lwm2m_get_message(client_ctx);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("Unable to get a lwm2m message!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create a response message if we reach this point */
|
||||
msg->type = ZOAP_TYPE_ACK;
|
||||
msg->code = zoap_header_get_code(&response);
|
||||
msg->mid = zoap_header_get_id(&response);
|
||||
/* skip token generation by default */
|
||||
msg->tkl = LWM2M_MSG_TOKEN_LEN_SKIP;
|
||||
|
||||
r = lwm2m_init_message(msg);
|
||||
if (r < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* process the response to this request */
|
||||
r = udp_request_handler(&response, msg);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("Request handler error: %d", r);
|
||||
} else {
|
||||
r = lwm2m_send_message(msg);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("Err sending response: %d",
|
||||
r);
|
||||
lwm2m_release_message(msg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SYS_LOG_ERR("No handler for response");
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pkt) {
|
||||
net_pkt_unref(pkt);
|
||||
|
@ -2400,6 +2502,7 @@ static void udp_receive(struct net_app_ctx *app_ctx, struct net_pkt *pkt,
|
|||
static void retransmit_request(struct k_work *work)
|
||||
{
|
||||
struct lwm2m_ctx *client_ctx;
|
||||
struct lwm2m_message *msg;
|
||||
struct zoap_pending *pending;
|
||||
int r;
|
||||
|
||||
|
@ -2410,17 +2513,28 @@ static void retransmit_request(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
r = lwm2m_udp_sendto(&client_ctx->net_app_ctx,
|
||||
pending->pkt);
|
||||
if (r < 0) {
|
||||
msg = find_msg_from_pending(pending);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("pending has no valid LwM2M message!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!zoap_pending_cycle(pending)) {
|
||||
zoap_pending_clear(pending);
|
||||
/* pending request has expired */
|
||||
if (msg->message_timeout_cb) {
|
||||
msg->message_timeout_cb(msg);
|
||||
}
|
||||
|
||||
lwm2m_release_message(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
r = lwm2m_send_message(msg);
|
||||
if (r < 0) {
|
||||
SYS_LOG_ERR("Error sending lwm2m message: %d", r);
|
||||
/* don't error here, retry until timeout */
|
||||
}
|
||||
|
||||
k_delayed_work_submit(&client_ctx->retransmit_work, pending->timeout);
|
||||
}
|
||||
|
||||
|
@ -2458,10 +2572,7 @@ static int notify_message_reply_cb(const struct zoap_packet *response,
|
|||
static int generate_notify_message(struct observe_node *obs,
|
||||
bool manual_trigger)
|
||||
{
|
||||
struct net_pkt *pkt = NULL;
|
||||
struct zoap_pending *pending = NULL;
|
||||
struct zoap_reply *reply = NULL;
|
||||
struct zoap_packet request;
|
||||
struct lwm2m_message *msg;
|
||||
struct lwm2m_engine_obj_inst *obj_inst;
|
||||
struct lwm2m_output_context out;
|
||||
struct lwm2m_engine_context context;
|
||||
|
@ -2481,7 +2592,6 @@ static int generate_notify_message(struct observe_node *obs,
|
|||
memcpy(&path, &obs->path, sizeof(struct lwm2m_obj_path));
|
||||
context.path = &path;
|
||||
context.operation = LWM2M_OP_READ;
|
||||
out.out_zpkt = &request;
|
||||
|
||||
SYS_LOG_DBG("[%s] NOTIFY MSG START: %u/%u/%u(%u) token:'%s' [%s] %lld",
|
||||
manual_trigger ? "MANUAL" : "AUTO",
|
||||
|
@ -2503,11 +2613,23 @@ static int generate_notify_message(struct observe_node *obs,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = lwm2m_init_message(&obs->ctx->net_app_ctx, out.out_zpkt, &pkt,
|
||||
ZOAP_TYPE_CON, ZOAP_RESPONSE_CODE_CONTENT,
|
||||
0, obs->token, obs->tkl);
|
||||
msg = lwm2m_get_message(obs->ctx);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("Unable to get a lwm2m message!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
out.out_zpkt = &msg->zpkt;
|
||||
msg->type = ZOAP_TYPE_CON;
|
||||
msg->code = ZOAP_RESPONSE_CODE_CONTENT;
|
||||
msg->mid = 0;
|
||||
msg->token = obs->token;
|
||||
msg->tkl = obs->tkl;
|
||||
msg->reply_cb = notify_message_reply_cb;
|
||||
|
||||
ret = lwm2m_init_message(msg);
|
||||
if (ret) {
|
||||
goto cleanup;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* each notification should increment the obs counter */
|
||||
|
@ -2542,36 +2664,17 @@ static int generate_notify_message(struct observe_node *obs,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
pending = lwm2m_init_message_pending(obs->ctx, out.out_zpkt);
|
||||
if (!pending) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = zoap_reply_next_unused(obs->ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!reply) {
|
||||
SYS_LOG_ERR("No resources for waiting for replies.");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_reply_init(reply, &request);
|
||||
reply->reply = notify_message_reply_cb;
|
||||
|
||||
ret = lwm2m_udp_sendto(&obs->ctx->net_app_ctx, pkt);
|
||||
ret = lwm2m_send_message(msg);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Error sending LWM2M packet (err:%d).", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
SYS_LOG_DBG("NOTIFY MSG: SENT");
|
||||
|
||||
zoap_pending_cycle(pending);
|
||||
k_delayed_work_submit(&obs->ctx->retransmit_work, pending->timeout);
|
||||
return ret;
|
||||
SYS_LOG_DBG("NOTIFY MSG: SENT");
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
lwm2m_init_message_cleanup(pkt, pending, reply);
|
||||
lwm2m_release_message(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,40 @@
|
|||
/* Use this value to skip token generation */
|
||||
#define LWM2M_MSG_TOKEN_LEN_SKIP 0xFF
|
||||
|
||||
struct lwm2m_message;
|
||||
|
||||
/* Establish a message timeout callback */
|
||||
typedef void (*lwm2m_message_timeout_cb_t)(struct lwm2m_message *msg);
|
||||
|
||||
/* Internal LwM2M message structure to track in-flight messages. */
|
||||
struct lwm2m_message {
|
||||
/** LwM2M context related to this message */
|
||||
struct lwm2m_ctx *ctx;
|
||||
|
||||
/** ZoAP packet data related to this message */
|
||||
struct zoap_packet zpkt;
|
||||
|
||||
/** Message transmission handling for TYPE_CON */
|
||||
struct zoap_pending *pending;
|
||||
struct zoap_reply *reply;
|
||||
|
||||
/** Message configuration */
|
||||
const u8_t *token;
|
||||
zoap_reply_t reply_cb;
|
||||
lwm2m_message_timeout_cb_t message_timeout_cb;
|
||||
u16_t mid;
|
||||
u8_t type;
|
||||
u8_t code;
|
||||
u8_t tkl;
|
||||
|
||||
/** Counter for message re-send / abort handling */
|
||||
u8_t send_attempts;
|
||||
};
|
||||
|
||||
/* Establish a request handler callback type */
|
||||
typedef int (*udp_request_handler_cb_t)(struct zoap_packet *request,
|
||||
struct lwm2m_message *msg);
|
||||
|
||||
char *lwm2m_sprint_ip_addr(const struct sockaddr *addr);
|
||||
|
||||
int lwm2m_notify_observer(u16_t obj_id, u16_t obj_inst_id, u16_t res_id);
|
||||
|
@ -51,14 +85,12 @@ int lwm2m_get_or_create_engine_obj(struct lwm2m_engine_context *context,
|
|||
struct lwm2m_engine_obj_inst **obj_inst,
|
||||
u8_t *created);
|
||||
|
||||
int lwm2m_init_message(struct net_app_ctx *app_ctx, struct zoap_packet *zpkt,
|
||||
struct net_pkt **pkt, u8_t type, u8_t code, u16_t mid,
|
||||
const u8_t *token, u8_t tkl);
|
||||
struct zoap_pending *lwm2m_init_message_pending(struct lwm2m_ctx *client_ctx,
|
||||
struct zoap_packet *zpkt);
|
||||
void lwm2m_init_message_cleanup(struct net_pkt *pkt,
|
||||
struct zoap_pending *pending,
|
||||
struct zoap_reply *reply);
|
||||
/* LwM2M message functions */
|
||||
struct lwm2m_message *find_msg_from_pending(struct zoap_pending *pending);
|
||||
struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx);
|
||||
void lwm2m_release_message(struct lwm2m_message *msg);
|
||||
int lwm2m_init_message(struct lwm2m_message *msg);
|
||||
int lwm2m_send_message(struct lwm2m_message *msg);
|
||||
|
||||
u16_t lwm2m_get_rd_data(u8_t *client_data, u16_t size);
|
||||
|
||||
|
@ -67,11 +99,8 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
|||
struct lwm2m_engine_obj_field *obj_field,
|
||||
struct lwm2m_engine_context *context);
|
||||
|
||||
int lwm2m_udp_sendto(struct net_app_ctx *app_ctx, struct net_pkt *pkt);
|
||||
void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, struct net_pkt *pkt,
|
||||
bool handle_separate_response,
|
||||
int (*udp_request_handler)(struct net_app_ctx *app_ctx,
|
||||
struct zoap_packet *request,
|
||||
struct zoap_packet *response));
|
||||
udp_request_handler_cb_t udp_request_handler);
|
||||
|
||||
#endif /* LWM2M_ENGINE_H */
|
||||
|
|
|
@ -46,97 +46,64 @@ firmware_udp_receive(struct net_app_ctx *app_ctx, struct net_pkt *pkt,
|
|||
lwm2m_udp_receive(&firmware_ctx, pkt, true, NULL);
|
||||
}
|
||||
|
||||
static void retransmit_request(struct k_work *work)
|
||||
static void do_transmit_timeout_cb(struct lwm2m_message *msg)
|
||||
{
|
||||
struct zoap_pending *pending;
|
||||
int r;
|
||||
|
||||
pending = zoap_pending_next_to_expire(firmware_ctx.pendings,
|
||||
CONFIG_LWM2M_ENGINE_MAX_PENDING);
|
||||
if (!pending) {
|
||||
return;
|
||||
}
|
||||
|
||||
r = lwm2m_udp_sendto(&firmware_ctx.net_app_ctx, pending->pkt);
|
||||
if (r < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!zoap_pending_cycle(pending)) {
|
||||
zoap_pending_clear(pending);
|
||||
return;
|
||||
}
|
||||
|
||||
k_delayed_work_submit(&firmware_ctx.retransmit_work, pending->timeout);
|
||||
/* TODO: Handle timeout */
|
||||
}
|
||||
|
||||
static int transfer_request(struct zoap_block_context *ctx,
|
||||
const u8_t *token, u8_t tkl,
|
||||
zoap_reply_t reply_cb)
|
||||
{
|
||||
struct zoap_packet request;
|
||||
struct net_pkt *pkt = NULL;
|
||||
struct zoap_pending *pending = NULL;
|
||||
struct zoap_reply *reply = NULL;
|
||||
struct lwm2m_message *msg;
|
||||
int ret;
|
||||
|
||||
ret = lwm2m_init_message(&firmware_ctx.net_app_ctx, &request, &pkt,
|
||||
ZOAP_TYPE_CON, ZOAP_METHOD_GET,
|
||||
0, token, tkl);
|
||||
msg = lwm2m_get_message(&firmware_ctx);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("Unable to get a lwm2m message!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
msg->type = ZOAP_TYPE_CON;
|
||||
msg->code = ZOAP_METHOD_GET;
|
||||
msg->mid = 0;
|
||||
msg->token = token;
|
||||
msg->tkl = tkl;
|
||||
msg->reply_cb = reply_cb;
|
||||
msg->message_timeout_cb = do_transmit_timeout_cb;
|
||||
|
||||
ret = lwm2m_init_message(msg);
|
||||
if (ret) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* hard code URI path here -- should be pulled from package_uri */
|
||||
ret = zoap_add_option(&request, ZOAP_OPTION_URI_PATH,
|
||||
ret = zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_PATH,
|
||||
"large-create", sizeof("large-create") - 1);
|
||||
ret = zoap_add_option(&request, ZOAP_OPTION_URI_PATH,
|
||||
ret = zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_PATH,
|
||||
"1", sizeof("1") - 1);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Error adding URI_QUERY 'large'");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = zoap_add_block2_option(&request, ctx);
|
||||
ret = zoap_add_block2_option(&msg->zpkt, ctx);
|
||||
if (ret) {
|
||||
SYS_LOG_ERR("Unable to add block2 option.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pending = lwm2m_init_message_pending(&firmware_ctx, &request);
|
||||
if (!pending) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* set the reply handler */
|
||||
if (reply_cb) {
|
||||
reply = zoap_reply_next_unused(firmware_ctx.replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!reply) {
|
||||
SYS_LOG_ERR("No resources for waiting for replies.");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_reply_init(reply, &request);
|
||||
reply->reply = reply_cb;
|
||||
}
|
||||
|
||||
/* send request */
|
||||
ret = lwm2m_udp_sendto(&firmware_ctx.net_app_ctx, pkt);
|
||||
ret = lwm2m_send_message(msg);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Error sending LWM2M packet (err:%d).",
|
||||
ret);
|
||||
SYS_LOG_ERR("Error sending LWM2M packet (err:%d).", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_pending_cycle(pending);
|
||||
k_delayed_work_submit(&firmware_ctx.retransmit_work, pending->timeout);
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
lwm2m_init_message_cleanup(pkt, pending, reply);
|
||||
lwm2m_release_message(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -299,8 +266,6 @@ int lwm2m_firmware_start_transfer(char *package_uri)
|
|||
firmware_ctx.net_init_timeout = NETWORK_INIT_TIMEOUT;
|
||||
firmware_ctx.net_timeout = NETWORK_CONNECT_TIMEOUT;
|
||||
k_work_init(&firmware_work, firmware_transfer);
|
||||
k_delayed_work_init(&firmware_ctx.retransmit_work,
|
||||
retransmit_request);
|
||||
|
||||
/* start file transfer work */
|
||||
strncpy(firmware_uri, package_uri, PACKAGE_URI_LEN - 1);
|
||||
|
|
|
@ -398,72 +398,57 @@ static int sm_do_init(int index)
|
|||
|
||||
static int sm_do_bootstrap(int index)
|
||||
{
|
||||
struct zoap_packet request;
|
||||
struct net_pkt *pkt = NULL;
|
||||
struct zoap_pending *pending = NULL;
|
||||
struct zoap_reply *reply = NULL;
|
||||
struct lwm2m_message *msg;
|
||||
struct net_app_ctx *app_ctx = NULL;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (clients[index].use_bootstrap &&
|
||||
clients[index].bootstrapped == 0 &&
|
||||
clients[index].has_bs_server_info) {
|
||||
app_ctx = &clients[index].ctx->net_app_ctx;
|
||||
ret = lwm2m_init_message(app_ctx,
|
||||
&request, &pkt, ZOAP_TYPE_CON,
|
||||
ZOAP_METHOD_POST, 0, NULL, 0);
|
||||
msg = lwm2m_get_message(clients[index].ctx);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("Unable to get a lwm2m message!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
msg->type = ZOAP_TYPE_CON;
|
||||
msg->code = ZOAP_METHOD_POST;
|
||||
msg->mid = 0;
|
||||
msg->reply_cb = do_bootstrap_reply_cb;
|
||||
|
||||
ret = lwm2m_init_message(msg);
|
||||
if (ret) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_PATH,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_PATH,
|
||||
"bs", strlen("bs"));
|
||||
|
||||
snprintf(query_buffer, sizeof(query_buffer) - 1,
|
||||
"ep=%s", clients[index].ep_name);
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_QUERY,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_QUERY,
|
||||
query_buffer, strlen(query_buffer));
|
||||
|
||||
pending = lwm2m_init_message_pending(clients[index].ctx,
|
||||
&request);
|
||||
if (!pending) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = zoap_reply_next_unused(clients[index].ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!reply) {
|
||||
SYS_LOG_ERR("No resources for waiting for replies.");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_reply_init(reply, &request);
|
||||
reply->reply = do_bootstrap_reply_cb;
|
||||
|
||||
/* log the bootstrap attempt */
|
||||
SYS_LOG_DBG("Register ID with bootstrap server [%s] as '%s'",
|
||||
lwm2m_sprint_ip_addr(
|
||||
&app_ctx->default_ctx->remote),
|
||||
query_buffer);
|
||||
|
||||
ret = lwm2m_udp_sendto(app_ctx, pkt);
|
||||
ret = lwm2m_send_message(msg);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Error sending LWM2M packet (err:%d).",
|
||||
ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_pending_cycle(pending);
|
||||
k_delayed_work_submit(&clients[index].ctx->retransmit_work,
|
||||
pending->timeout);
|
||||
set_sm_state(index, ENGINE_BOOTSTRAP_SENT);
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
lwm2m_init_message_cleanup(pkt, pending, reply);
|
||||
lwm2m_release_message(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -512,54 +497,62 @@ static int sm_bootstrap_done(int index)
|
|||
}
|
||||
|
||||
static int sm_send_registration(int index, bool send_obj_support_data,
|
||||
zoap_reply_t reply_cb)
|
||||
zoap_reply_t reply_cb,
|
||||
lwm2m_message_timeout_cb_t timeout_cb)
|
||||
{
|
||||
struct net_app_ctx *app_ctx = NULL;
|
||||
struct zoap_packet request;
|
||||
struct net_pkt *pkt = NULL;
|
||||
struct zoap_pending *pending = NULL;
|
||||
struct zoap_reply *reply = NULL;
|
||||
struct lwm2m_message *msg;
|
||||
u8_t *payload;
|
||||
u16_t client_data_len, len;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
app_ctx = &clients[index].ctx->net_app_ctx;
|
||||
msg = lwm2m_get_message(clients[index].ctx);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("Unable to get a lwm2m message!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* remember the last reg time */
|
||||
clients[index].last_update = k_uptime_get();
|
||||
ret = lwm2m_init_message(app_ctx,
|
||||
&request, &pkt, ZOAP_TYPE_CON,
|
||||
ZOAP_METHOD_POST, 0, NULL, 0);
|
||||
|
||||
msg->type = ZOAP_TYPE_CON;
|
||||
msg->code = ZOAP_METHOD_POST;
|
||||
msg->mid = 0;
|
||||
msg->reply_cb = reply_cb;
|
||||
msg->message_timeout_cb = timeout_cb;
|
||||
|
||||
ret = lwm2m_init_message(msg);
|
||||
if (ret) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_PATH,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_PATH,
|
||||
LWM2M_RD_CLIENT_URI,
|
||||
strlen(LWM2M_RD_CLIENT_URI));
|
||||
|
||||
if (!sm_is_registered(index)) {
|
||||
/* include client endpoint in URI QUERY on 1st registration */
|
||||
zoap_add_option_int(&request, ZOAP_OPTION_CONTENT_FORMAT,
|
||||
zoap_add_option_int(&msg->zpkt, ZOAP_OPTION_CONTENT_FORMAT,
|
||||
LWM2M_FORMAT_APP_LINK_FORMAT);
|
||||
snprintf(query_buffer, sizeof(query_buffer) - 1,
|
||||
"lwm2m=%s", LWM2M_PROTOCOL_VERSION);
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_QUERY,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_QUERY,
|
||||
query_buffer, strlen(query_buffer));
|
||||
snprintf(query_buffer, sizeof(query_buffer) - 1,
|
||||
"ep=%s", clients[index].ep_name);
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_QUERY,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_QUERY,
|
||||
query_buffer, strlen(query_buffer));
|
||||
} else {
|
||||
/* include server endpoint in URI PATH otherwise */
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_PATH,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_PATH,
|
||||
clients[index].server_ep,
|
||||
strlen(clients[index].server_ep));
|
||||
}
|
||||
|
||||
snprintf(query_buffer, sizeof(query_buffer) - 1,
|
||||
"lt=%d", clients[index].lifetime);
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_QUERY,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_QUERY,
|
||||
query_buffer, strlen(query_buffer));
|
||||
/* TODO: add supported binding query string */
|
||||
|
||||
|
@ -567,54 +560,34 @@ static int sm_send_registration(int index, bool send_obj_support_data,
|
|||
/* generate the rd data */
|
||||
client_data_len = lwm2m_get_rd_data(client_data,
|
||||
sizeof(client_data));
|
||||
payload = zoap_packet_get_payload(&request, &len);
|
||||
payload = zoap_packet_get_payload(&msg->zpkt, &len);
|
||||
if (!payload) {
|
||||
ret = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(payload, client_data, client_data_len);
|
||||
ret = zoap_packet_set_used(&request, client_data_len);
|
||||
ret = zoap_packet_set_used(&msg->zpkt, client_data_len);
|
||||
if (ret) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
pending = lwm2m_init_message_pending(clients[index].ctx, &request);
|
||||
if (!pending) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = zoap_reply_next_unused(clients[index].ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!reply) {
|
||||
SYS_LOG_ERR("No resources for waiting for replies.");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_reply_init(reply, &request);
|
||||
reply->reply = reply_cb;
|
||||
|
||||
/* log the registration attempt */
|
||||
SYS_LOG_DBG("registration sent [%s]",
|
||||
lwm2m_sprint_ip_addr(&app_ctx->default_ctx->remote));
|
||||
|
||||
ret = lwm2m_udp_sendto(app_ctx, pkt);
|
||||
ret = lwm2m_send_message(msg);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Error sending LWM2M packet (err:%d).",
|
||||
ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_pending_cycle(pending);
|
||||
k_delayed_work_submit(&clients[index].ctx->retransmit_work,
|
||||
pending->timeout);
|
||||
return ret;
|
||||
/* log the registration attempt */
|
||||
SYS_LOG_DBG("registration sent [%s]",
|
||||
lwm2m_sprint_ip_addr(&app_ctx->default_ctx->remote));
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
lwm2m_init_message_cleanup(pkt, pending, reply);
|
||||
lwm2m_release_message(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -626,7 +599,7 @@ static int sm_do_registration(int index)
|
|||
!sm_is_registered(index) &&
|
||||
clients[index].has_registration_info) {
|
||||
ret = sm_send_registration(index, true,
|
||||
do_registration_reply_cb);
|
||||
do_registration_reply_cb, NULL);
|
||||
if (!ret) {
|
||||
set_sm_state(index, ENGINE_REGISTRATION_SENT);
|
||||
} else {
|
||||
|
@ -650,7 +623,7 @@ static int sm_registration_done(int index)
|
|||
forced_update = clients[index].trigger_update;
|
||||
clients[index].trigger_update = 0;
|
||||
ret = sm_send_registration(index, forced_update,
|
||||
do_update_reply_cb);
|
||||
do_update_reply_cb, NULL);
|
||||
if (!ret) {
|
||||
set_sm_state(index, ENGINE_UPDATE_SENT);
|
||||
} else {
|
||||
|
@ -664,59 +637,44 @@ static int sm_registration_done(int index)
|
|||
static int sm_do_deregister(int index)
|
||||
{
|
||||
struct net_app_ctx *app_ctx = NULL;
|
||||
struct zoap_packet request;
|
||||
struct net_pkt *pkt = NULL;
|
||||
struct zoap_pending *pending = NULL;
|
||||
struct zoap_reply *reply = NULL;
|
||||
struct lwm2m_message *msg;
|
||||
int ret;
|
||||
|
||||
app_ctx = &clients[index].ctx->net_app_ctx;
|
||||
msg = lwm2m_get_message(clients[index].ctx);
|
||||
if (!msg) {
|
||||
SYS_LOG_ERR("Unable to get a lwm2m message!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = lwm2m_init_message(app_ctx,
|
||||
&request, &pkt, ZOAP_TYPE_CON,
|
||||
ZOAP_METHOD_DELETE, 0, NULL, 0);
|
||||
msg->type = ZOAP_TYPE_CON;
|
||||
msg->code = ZOAP_METHOD_DELETE;
|
||||
msg->mid = 0;
|
||||
msg->reply_cb = do_deregister_reply_cb;
|
||||
|
||||
ret = lwm2m_init_message(msg);
|
||||
if (ret) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_add_option(&request, ZOAP_OPTION_URI_PATH,
|
||||
zoap_add_option(&msg->zpkt, ZOAP_OPTION_URI_PATH,
|
||||
clients[index].server_ep,
|
||||
strlen(clients[index].server_ep));
|
||||
|
||||
pending = lwm2m_init_message_pending(clients[index].ctx, &request);
|
||||
if (!pending) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reply = zoap_reply_next_unused(clients[index].ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
if (!reply) {
|
||||
SYS_LOG_ERR("No resources for waiting for replies.");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_reply_init(reply, &request);
|
||||
reply->reply = do_deregister_reply_cb;
|
||||
|
||||
SYS_LOG_INF("Deregister from '%s'", clients[index].server_ep);
|
||||
|
||||
ret = lwm2m_udp_sendto(app_ctx, pkt);
|
||||
ret = lwm2m_send_message(msg);
|
||||
if (ret < 0) {
|
||||
SYS_LOG_ERR("Error sending LWM2M packet (err:%d).",
|
||||
ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zoap_pending_cycle(pending);
|
||||
k_delayed_work_submit(&clients[index].ctx->retransmit_work,
|
||||
pending->timeout);
|
||||
set_sm_state(index, ENGINE_DEREGISTER_SENT);
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
lwm2m_init_message_cleanup(pkt, pending, reply);
|
||||
lwm2m_release_message(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue