diff --git a/sys/net/application_layer/nanocoap/sock.c b/sys/net/application_layer/nanocoap/sock.c index c722a553b007b77609ba5505a6b58bb1a16cb2b7..e77e9e94d31c90223bd59b44c87cd565cdbfb003 100644 --- a/sys/net/application_layer/nanocoap/sock.c +++ b/sys/net/application_layer/nanocoap/sock.c @@ -46,19 +46,14 @@ ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local, sock_udp_ep_t *r /* TODO: timeout random between between ACK_TIMEOUT and (ACK_TIMEOUT * * ACK_RANDOM_FACTOR) */ - uint32_t timeout = COAP_ACK_TIMEOUT * (1000000U); - int tries = 0; - while (tries++ < COAP_MAX_RETRANSMIT) { - if (!tries) { - DEBUG("nanocoap: maximum retries reached.\n"); - res = -ETIMEDOUT; - goto out; - } + uint32_t timeout = COAP_ACK_TIMEOUT * US_PER_SEC; + unsigned tries_left = COAP_MAX_RETRANSMIT + 1; /* add 1 for initial transmit */ + while (tries_left) { res = sock_udp_send(&sock, buf, pdu_len, NULL); if (res <= 0) { - DEBUG("nanocoap: error sending coap request\n"); - goto out; + DEBUG("nanocoap: error sending coap request, %d\n", (int)res); + break; } res = sock_udp_recv(&sock, buf, len, timeout, NULL); @@ -67,9 +62,13 @@ ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local, sock_udp_ep_t *r DEBUG("nanocoap: timeout\n"); timeout *= 2; + tries_left--; + if (!tries_left) { + DEBUG("nanocoap: maximum retries reached\n"); + } continue; } - DEBUG("nanocoap: error receiving coap request\n"); + DEBUG("nanocoap: error receiving coap response, %d\n", (int)res); break; } else { @@ -81,7 +80,6 @@ ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local, sock_udp_ep_t *r } } -out: sock_udp_close(&sock); return res; diff --git a/tests/nanocoap_cli/nanocli_server.c b/tests/nanocoap_cli/nanocli_server.c index 53bea14f4810c04841535a0279bcad540b7036f4..3b33264093dd70793bdcfb272d76f20b25ae7e8a 100644 --- a/tests/nanocoap_cli/nanocli_server.c +++ b/tests/nanocoap_cli/nanocli_server.c @@ -27,38 +27,104 @@ #define ENABLE_DEBUG (0) #include "debug.h" -static void _start_server(uint16_t port) +/* + * Customized implementation of nanocoap_server() to ignore a count of + * requests. Allows testing confirmable messaging. + */ +static int _nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize, + int ignore_count) +{ + sock_udp_t sock; + sock_udp_ep_t remote; + + if (!local->port) { + local->port = COAP_PORT; + } + + ssize_t res = sock_udp_create(&sock, local, NULL, 0); + if (res == -1) { + return -1; + } + + int recv_count = 0; + while (1) { + res = sock_udp_recv(&sock, buf, bufsize, -1, &remote); + if (++recv_count <= ignore_count) { + DEBUG("ignoring request\n"); + continue; + } + if (res == -1) { + DEBUG("nanocoap: error receiving coap request, \n"); + return -1; + } + else { + coap_pkt_t pkt; + if (coap_parse(&pkt, (uint8_t *)buf, res) < 0) { + DEBUG("nanocoap: error parsing packet\n"); + continue; + } + if ((res = coap_handle_req(&pkt, buf, bufsize)) > 0) { + res = sock_udp_send(&sock, buf, res, &remote); + } + } + } + + return 0; +} + +static void _start_server(uint16_t port, int ignore_count) { uint8_t buf[128]; sock_udp_ep_t local = { .port=port, .family=AF_INET6 }; - nanocoap_server(&local, buf, sizeof(buf)); + _nanocoap_server(&local, buf, sizeof(buf), ignore_count); } int nanotest_server_cmd(int argc, char **argv) { - uint16_t port = COAP_PORT; - if (argc >= 2) { - if (strncmp("start", argv[1], 5) != 0) { - goto end; - } + if (argc < 2) { + goto error; + } + + if (strncmp("start", argv[1], 5) != 0) { + goto error; + } + int arg_pos = 2; + int ignore_count = 0; + if ((argc >= (arg_pos+1)) && (strcmp(argv[arg_pos], "-i") == 0)) { + /* need count of requests to ignore*/ if (argc == 3) { - port = atoi(argv[2]); - if (port == 0) { - puts("nanocli: unable to parse port"); - return 1; - } + goto error; } + arg_pos++; - puts("starting server\n"); - _start_server(port); + ignore_count = atoi(argv[arg_pos]); + if (ignore_count <= 0) { + puts("nanocli: unable to parse ignore_count"); + goto error; + } + arg_pos++; + } - /* server executes run loop; never reaches this point*/ - return 0; + uint16_t port = COAP_PORT; + if (argc == (arg_pos+1)) { + port = atoi(argv[arg_pos]); + if (port == 0) { + puts("nanocli: unable to parse port"); + goto error; + } } - end: - printf("usage: %s start [port]\n", argv[0]); - printf(" Port defaults to %u\n", COAP_PORT); + printf("starting server on port %u\n", port); + _start_server(port, ignore_count); + + /* server executes run loop; never reaches this point*/ + return 0; + + error: + printf("usage: %s start [-i ignore_count] [port]\n", argv[0]); + printf("Options\n"); + printf(" -i ignore a number of requests\n"); + printf(" port defaults to %u\n", COAP_PORT); return 1; }