@@ -27,6 +27,7 @@ static atomic_t coap_client_recv_active;
27
27
static int send_request (int sock , const void * buf , size_t len , int flags ,
28
28
const struct sockaddr * dest_addr , socklen_t addrlen )
29
29
{
30
+ LOG_HEXDUMP_DBG (buf , len , "Send CoAP Request:" );
30
31
if (addrlen == 0 ) {
31
32
return zsock_sendto (sock , buf , len , flags , NULL , 0 );
32
33
} else {
@@ -37,11 +38,17 @@ static int send_request(int sock, const void *buf, size_t len, int flags,
37
38
static int receive (int sock , void * buf , size_t max_len , int flags ,
38
39
struct sockaddr * src_addr , socklen_t * addrlen )
39
40
{
41
+ ssize_t err ;
42
+
40
43
if (* addrlen == 0 ) {
41
- return zsock_recvfrom (sock , buf , max_len , flags , NULL , NULL );
44
+ err = zsock_recvfrom (sock , buf , max_len , flags , NULL , NULL );
42
45
} else {
43
- return zsock_recvfrom (sock , buf , max_len , flags , src_addr , addrlen );
46
+ err = zsock_recvfrom (sock , buf , max_len , flags , src_addr , addrlen );
47
+ }
48
+ if (err > 0 ) {
49
+ LOG_HEXDUMP_DBG (buf , err , "Receive CoAP Response:" );
44
50
}
51
+ return err ;
45
52
}
46
53
47
54
static void reset_block_contexts (struct coap_client_internal_request * request )
@@ -282,6 +289,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
282
289
struct coap_client_internal_request * internal_req = get_free_request (client );
283
290
284
291
if (internal_req == NULL ) {
292
+ LOG_DBG ("No more free requests" );
285
293
return - EAGAIN ;
286
294
}
287
295
@@ -320,6 +328,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
320
328
reset_internal_request (internal_req );
321
329
322
330
if (k_mutex_lock (& client -> send_mutex , K_NO_WAIT )) {
331
+ LOG_DBG ("Could not immediately lock send_mutex" );
323
332
return - EAGAIN ;
324
333
}
325
334
@@ -380,8 +389,13 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
380
389
static void report_callback_error (struct coap_client_internal_request * internal_req , int error_code )
381
390
{
382
391
if (internal_req -> coap_request .cb ) {
383
- internal_req -> coap_request .cb (error_code , 0 , NULL , 0 , true,
384
- internal_req -> coap_request .user_data );
392
+ if (!atomic_set (& internal_req -> in_callback , 1 )) {
393
+ internal_req -> coap_request .cb (error_code , 0 , NULL , 0 , true,
394
+ internal_req -> coap_request .user_data );
395
+ atomic_clear (& internal_req -> in_callback );
396
+ } else {
397
+ LOG_DBG ("Cannot call the callback; already in it." );
398
+ }
385
399
}
386
400
}
387
401
@@ -400,7 +414,9 @@ static int resend_request(struct coap_client *client,
400
414
{
401
415
int ret = 0 ;
402
416
403
- if (internal_req -> pending .timeout != 0 && coap_pending_cycle (& internal_req -> pending )) {
417
+ if (internal_req -> request_ongoing &&
418
+ internal_req -> pending .timeout != 0 &&
419
+ coap_pending_cycle (& internal_req -> pending )) {
404
420
LOG_ERR ("Timeout in poll, retrying send" );
405
421
406
422
/* Reset send block context as it was updated in previous init from packet */
@@ -765,10 +781,16 @@ static int handle_response(struct coap_client *client, const struct coap_packet
765
781
766
782
/* Call user callback */
767
783
if (internal_req -> coap_request .cb ) {
768
- internal_req -> coap_request .cb (response_code , internal_req -> offset , payload ,
769
- payload_len , last_block ,
770
- internal_req -> coap_request .user_data );
771
-
784
+ if (!atomic_set (& internal_req -> in_callback , 1 )) {
785
+ internal_req -> coap_request .cb (response_code , internal_req -> offset , payload ,
786
+ payload_len , last_block ,
787
+ internal_req -> coap_request .user_data );
788
+ atomic_clear (& internal_req -> in_callback );
789
+ }
790
+ if (!internal_req -> request_ongoing ) {
791
+ /* User callback must have called coap_client_cancel_requests(). */
792
+ goto fail ;
793
+ }
772
794
/* Update the offset for next callback in a blockwise transfer */
773
795
if (blockwise_transfer ) {
774
796
internal_req -> offset += payload_len ;
@@ -820,8 +842,21 @@ static int handle_response(struct coap_client *client, const struct coap_packet
820
842
void coap_client_cancel_requests (struct coap_client * client )
821
843
{
822
844
for (int i = 0 ; i < ARRAY_SIZE (client -> requests ); i ++ ) {
823
- client -> requests [i ].request_ongoing = false;
845
+ if (client -> requests [i ].request_ongoing == true) {
846
+ LOG_DBG ("Cancelling request %d" , i );
847
+ /* Report the request was cancelled. This will be skipped if
848
+ * this function was called from the user's callback so we
849
+ * do not reenter it. In that case, the user knows their
850
+ * request was cancelled anyway.
851
+ */
852
+ report_callback_error (& client -> requests [i ], - ECANCELED );
853
+ client -> requests [i ].request_ongoing = false;
854
+ }
824
855
}
856
+ atomic_clear (& coap_client_recv_active );
857
+
858
+ /* Wait until after zsock_poll() can time out and return. */
859
+ k_sleep (K_MSEC (COAP_PERIODIC_TIMEOUT ));
825
860
}
826
861
827
862
void coap_client_recv (void * coap_cl , void * a , void * b )
0 commit comments