net: lwm2m: dont release reply for duplicate block transfer

During normal use, a CoAP packet can be resent due to network congestion
and other causes.  During block transfer the LwM2M client checks to make
sure the block received is the one we expect and if not generates a
"duplicate" warning.  When this happened, we were releasing the reply
handler and when the correct block was received the client would
generate a "No handler" error.

To avoid releasing the reply handler too early, let's set the coap_reply
"user_data" field to an error condition (1).  Then, once the reply
processing is complete we can check the user_data field to be sure that
it's ok to release the reply handler.

Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
This commit is contained in:
Michael Scott 2018-03-23 10:49:44 -07:00 committed by Anas Nashif
commit 4c58ffb5ab
3 changed files with 16 additions and 0 deletions

View file

@ -1018,6 +1018,7 @@ int lwm2m_init_message(struct lwm2m_message *msg)
goto cleanup;
}
coap_reply_clear(msg->reply);
coap_reply_init(msg->reply, &msg->cpkt);
msg->reply->reply = msg->reply_cb;
}
@ -3446,6 +3447,14 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, struct net_pkt *pkt,
}
if (reply || pending) {
/* skip release if reply->user_data has error condition */
if (reply && reply->user_data != COAP_REPLY_STATUS_NONE) {
/* reset reply->user_data for next time */
reply->user_data = (void *)COAP_REPLY_STATUS_NONE;
SYS_LOG_DBG("reply %p NOT removed", reply);
goto cleanup;
}
/* free up msg resources */
if (msg) {
lwm2m_reset_message(msg, true);

View file

@ -40,6 +40,10 @@
/* length of time in milliseconds to wait for buffer allocations */
#define BUF_ALLOC_TIMEOUT K_SECONDS(1)
/* coap reply status */
#define COAP_REPLY_STATUS_NONE 0
#define COAP_REPLY_STATUS_ERROR 1
struct lwm2m_message;
/* Establish a message timeout callback */

View file

@ -308,6 +308,9 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
/* restore main firmware block context */
memcpy(&firmware_block_ctx, &received_block_ctx,
sizeof(firmware_block_ctx));
/* set reply->user_data to error to avoid releasing */
reply->user_data = (void *)COAP_REPLY_STATUS_ERROR;
return 0;
}