Skip to content

Commit f6281ed

Browse files
author
Tero Heinonen
authored
CoAP transaction delete improvements (ARMmbed#91)
Some improvements/fixes for the CoAP transaction delete: - Calculate transaction lifetime from CoAP retransmission maximum times - When transaction times out, callback must be called to inform that transaction was failed
1 parent a4bb497 commit f6281ed

File tree

4 files changed

+93
-19
lines changed

4 files changed

+93
-19
lines changed

source/coap_message_handler.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,28 @@ static coap_transaction_t *transaction_find_by_address(uint8_t *address_ptr, uin
9797
return this;
9898
}
9999

100+
/* retransmission valid time is calculated to be max. time that CoAP message sending can take: */
101+
/* Number of retransmisisons, each retransmission is 2 * previous retransmisison time */
102+
/* + random factor (max. 1.5) */
103+
static uint32_t transaction_valid_time_calculate(void)
104+
{
105+
int i;
106+
uint32_t time_valid = 0;
107+
108+
for (i = 0; i <= COAP_RESENDING_COUNT; i++) {
109+
time_valid += (COAP_RESENDING_INTERVAL << i) * 1.5;
110+
}
111+
112+
return time_valid + coap_service_get_internal_timer_ticks();
113+
}
114+
100115
static coap_transaction_t *transaction_create(void)
101116
{
102117
coap_transaction_t *this = ns_dyn_mem_alloc(sizeof(coap_transaction_t));
103118
if (this) {
104119
memset(this, 0, sizeof(coap_transaction_t));
105120
this->client_request = true;// default to client initiated method
106-
this->create_time = coap_service_get_internal_timer_ticks();
121+
this->valid_until = transaction_valid_time_calculate();
107122
ns_list_add_to_start(&request_list, this);
108123
}
109124

@@ -199,6 +214,9 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint
199214
/* Set default buffer size for CoAP duplicate message detection */
200215
sn_coap_protocol_set_duplicate_buffer_size(handle->coap, DUPLICATE_MESSAGE_BUFFER_SIZE);
201216

217+
/* Set default CoAP retransmission paramters */
218+
sn_coap_protocol_set_retransmission_parameters(handle->coap, COAP_RESENDING_COUNT, COAP_RESENDING_INTERVAL);
219+
202220
return handle;
203221
}
204222

@@ -518,8 +536,13 @@ int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_ti
518536

519537
// Remove outdated transactions from queue
520538
ns_list_foreach_safe(coap_transaction_t, transaction, &request_list) {
521-
if ((transaction->create_time + TRANSACTION_LIFETIME) < current_time) {
522-
transaction_delete(transaction);
539+
if (transaction->valid_until < current_time) {
540+
tr_debug("transaction %d timed out", transaction->msg_id);
541+
ns_list_remove(&request_list, transaction);
542+
if (transaction->resp_cb) {
543+
transaction->resp_cb(transaction->service_id, transaction->remote_address, transaction->remote_port, NULL);
544+
}
545+
transaction_free(transaction);
523546
}
524547
}
525548

source/include/coap_message_handler.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
/* Default value for CoAP duplicate message buffer (0 = disabled) */
2727
#define DUPLICATE_MESSAGE_BUFFER_SIZE 0
2828

29+
/* Default values for CoAP resendings */
30+
#define COAP_RESENDING_COUNT 3
31+
#define COAP_RESENDING_INTERVAL 10
32+
2933
/**
3034
* \brief Service message response receive callback.
3135
*
@@ -51,7 +55,7 @@ typedef struct coap_transaction {
5155
uint8_t remote_address[16];
5256
uint8_t local_address[16];
5357
uint8_t token[8];
54-
uint32_t create_time;
58+
uint32_t valid_until;
5559
uint8_t *data_ptr;
5660
coap_message_handler_response_recv *resp_cb;
5761
uint16_t remote_port;

test/coap-service/unittest/coap_message_handler/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ TEST_SRC_FILES = \
3737

3838
include ../MakefileWorker.mk
3939

40-
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT
40+
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -I ../../../../source/
4141

test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
#include "sn_coap_builder_stub.h"
2323
#include "sn_coap_parser_stub.h"
2424
#include "socket_api.h"
25+
#include "coap_message_handler.c"
2526

2627
int retCounter = 0;
2728
int retValue = 0;
29+
int transaction_cb = 0;
2830

29-
static void *own_alloc(uint16_t size)
31+
static void *test_own_alloc(uint16_t size)
3032
{
3133
if( retCounter > 0 ){
3234
retCounter--;
@@ -35,7 +37,7 @@ static void *own_alloc(uint16_t size)
3537
return NULL;
3638
}
3739

38-
static void own_free(void *ptr)
40+
static void test_own_free(void *ptr)
3941
{
4042
if (ptr) {
4143
free(ptr);
@@ -56,24 +58,30 @@ int16_t process_cb(int8_t a, sn_coap_hdr_s *b, coap_transaction_t *c)
5658
return retValue;
5759
}
5860

61+
static int transaction_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr)
62+
{
63+
transaction_cb = 1;
64+
return 1;
65+
}
66+
5967
bool test_coap_message_handler_init()
6068
{
6169
if( NULL != coap_message_handler_init(NULL, NULL, NULL) )
6270
return false;
63-
if( NULL != coap_message_handler_init(&own_alloc, NULL, NULL) )
71+
if( NULL != coap_message_handler_init(&test_own_alloc, NULL, NULL) )
6472
return false;
65-
if( NULL != coap_message_handler_init(&own_alloc, &own_free, NULL) )
73+
if( NULL != coap_message_handler_init(&test_own_alloc, &test_own_free, NULL) )
6674
return false;
67-
if( NULL != coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function) )
75+
if( NULL != coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function) )
6876
return false;
6977
retCounter = 1;
7078
sn_coap_protocol_stub.expectedCoap = NULL;
71-
if( NULL != coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function) )
79+
if( NULL != coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function) )
7280
return false;
7381
retCounter = 1;
7482
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
7583
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
76-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
84+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
7785
if( NULL == handle )
7886
return false;
7987
free(sn_coap_protocol_stub.expectedCoap);
@@ -89,7 +97,7 @@ bool test_coap_message_handler_destroy()
8997
retCounter = 1;
9098
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
9199
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
92-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
100+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
93101

94102
if( 0 != coap_message_handler_destroy(handle) )
95103
return false;
@@ -105,7 +113,7 @@ bool test_coap_message_handler_find_transaction()
105113
retCounter = 1;
106114
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
107115
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
108-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
116+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
109117

110118
uint8_t buf[16];
111119
memset(&buf, 1, 16);
@@ -139,7 +147,7 @@ bool test_coap_message_handler_coap_msg_process()
139147
retCounter = 1;
140148
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
141149
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
142-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
150+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
143151

144152
sn_coap_protocol_stub.expectedHeader = NULL;
145153
/* Coap parse returns null */
@@ -213,7 +221,7 @@ bool test_coap_message_handler_request_send()
213221
retCounter = 1;
214222
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
215223
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
216-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
224+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
217225

218226
uint8_t buf[16];
219227
memset(&buf, 1, 16);
@@ -255,7 +263,7 @@ bool test_coap_message_handler_request_delete()
255263
retCounter = 1;
256264
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
257265
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
258-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
266+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
259267

260268
uint8_t buf[16];
261269
memset(&buf, 1, 16);
@@ -291,7 +299,7 @@ bool test_coap_message_handler_response_send()
291299
retCounter = 1;
292300
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
293301
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
294-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
302+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
295303
sn_coap_hdr_s *header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
296304
memset(header, 0, sizeof(sn_coap_hdr_s));
297305

@@ -340,15 +348,54 @@ bool test_coap_message_handler_response_send()
340348

341349
bool test_coap_message_handler_exec()
342350
{
351+
/* Null as a parameter */
343352
if( -1 != coap_message_handler_exec(NULL, 0))
344353
return false;
354+
345355
retCounter = 1;
346356
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
347357
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
348-
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
358+
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
359+
360+
if( 0 != coap_message_handler_exec(handle, 0))
361+
return false;
362+
363+
nsdynmemlib_stub.returnCounter = 1;
364+
coap_transaction_t *transact_ptr = transaction_create();
365+
366+
/* Transaction not timed out*/
349367
if( 0 != coap_message_handler_exec(handle, 0))
350368
return false;
351369

370+
if (transaction_cb != 0)
371+
return false;
372+
373+
/* Timed out, no CB */
374+
if( 0 != coap_message_handler_exec(handle, 300))
375+
return false;
376+
377+
if (transaction_cb != 0)
378+
return false;
379+
380+
nsdynmemlib_stub.returnCounter = 1;
381+
transact_ptr = transaction_create();
382+
transact_ptr->resp_cb = transaction_recv_cb;
383+
384+
/* Transaction not timed out */
385+
if( 0 != coap_message_handler_exec(handle, 0))
386+
return false;
387+
388+
if (transaction_cb != 0)
389+
return false;
390+
391+
/* Transaction timed out */
392+
if( 0 != coap_message_handler_exec(handle, 300))
393+
return false;
394+
395+
if (transaction_cb == 0)
396+
return false;
397+
398+
/* Teardown */
352399
free(sn_coap_protocol_stub.expectedCoap);
353400
sn_coap_protocol_stub.expectedCoap = NULL;
354401
coap_message_handler_destroy(handle);

0 commit comments

Comments
 (0)