@@ -26,6 +26,13 @@ static int num_clients;
2626static K_SEM_DEFINE (coap_client_recv_sem , 0 , 1 ) ;
2727static atomic_t coap_client_recv_active ;
2828
29+ static bool timeout_expired (struct coap_client_internal_request * internal_req );
30+ static void cancel_requests_with (struct coap_client * client , int error );
31+ static int recv_response (struct coap_client * client , struct coap_packet * response , bool * truncated );
32+ static int handle_response (struct coap_client * client , const struct coap_packet * response ,
33+ bool response_truncated );
34+
35+
2936static int send_request (int sock , const void * buf , size_t len , int flags ,
3037 const struct sockaddr * dest_addr , socklen_t addrlen )
3138{
@@ -127,27 +134,26 @@ static bool has_ongoing_exchange(struct coap_client *client)
127134 return false;
128135}
129136
130- static struct coap_client_internal_request * get_free_request (struct coap_client * client )
137+ static bool has_timeout_expired (struct coap_client * client )
131138{
132139 for (int i = 0 ; i < CONFIG_COAP_CLIENT_MAX_REQUESTS ; i ++ ) {
133- if (client -> requests [i ].request_ongoing == false &&
134- exchange_lifetime_exceeded (& client -> requests [i ])) {
135- return & client -> requests [i ];
140+ if (timeout_expired (& client -> requests [i ])) {
141+ return true;
136142 }
137143 }
138-
139- return NULL ;
144+ return false;
140145}
141146
142- static bool has_ongoing_requests ( void )
147+ static struct coap_client_internal_request * get_free_request ( struct coap_client * client )
143148{
144- for (int i = 0 ; i < num_clients ; i ++ ) {
145- if (has_ongoing_request (clients [i ])) {
146- return true;
149+ for (int i = 0 ; i < CONFIG_COAP_CLIENT_MAX_REQUESTS ; i ++ ) {
150+ if (client -> requests [i ].request_ongoing == false &&
151+ exchange_lifetime_exceeded (& client -> requests [i ])) {
152+ return & client -> requests [i ];
147153 }
148154 }
149155
150- return false ;
156+ return NULL ;
151157}
152158
153159static bool has_ongoing_exchanges (void )
@@ -498,86 +504,91 @@ static int resend_request(struct coap_client *client,
498504 return ret ;
499505}
500506
501- static int coap_client_resend_handler (void )
507+ static void coap_client_resend_handler (struct coap_client * client )
502508{
503509 int ret = 0 ;
504510
505- for (int i = 0 ; i < num_clients ; i ++ ) {
506- k_mutex_lock (& clients [i ]-> lock , K_FOREVER );
511+ k_mutex_lock (& client -> lock , K_FOREVER );
507512
508- for (int j = 0 ; j < CONFIG_COAP_CLIENT_MAX_REQUESTS ; j ++ ) {
509- if (timeout_expired (& clients [i ]-> requests [j ])) {
510- ret = resend_request (clients [i ], & clients [i ]-> requests [j ]);
513+ for (int i = 0 ; i < CONFIG_COAP_CLIENT_MAX_REQUESTS ; i ++ ) {
514+ if (timeout_expired (& client -> requests [i ])) {
515+ ret = resend_request (client , & client -> requests [i ]);
516+ if (ret < 0 ) {
517+ report_callback_error (& client -> requests [i ], ret );
518+ reset_internal_request (& client -> requests [i ]);
511519 }
512520 }
513-
514- k_mutex_unlock (& clients [i ]-> lock );
515521 }
516522
517- return ret ;
523+ k_mutex_unlock ( & client -> lock ) ;
518524}
519525
520526static int handle_poll (void )
521527{
522528 int ret = 0 ;
523529
524- while (1 ) {
525- struct zsock_pollfd fds [CONFIG_COAP_CLIENT_MAX_INSTANCES ] = {0 };
526- int nfds = 0 ;
527-
528- /* Use periodic timeouts */
529- for (int i = 0 ; i < num_clients ; i ++ ) {
530- fds [i ].fd = clients [i ]-> fd ;
531- fds [i ].events = ZSOCK_POLLIN ;
532- fds [i ].revents = 0 ;
533- nfds ++ ;
534- }
530+ struct zsock_pollfd fds [CONFIG_COAP_CLIENT_MAX_INSTANCES ] = {0 };
531+ int nfds = 0 ;
535532
536- ret = zsock_poll (fds , nfds , COAP_PERIODIC_TIMEOUT );
533+ /* Use periodic timeouts */
534+ for (int i = 0 ; i < num_clients ; i ++ ) {
535+ fds [i ].fd = clients [i ]-> fd ;
536+ fds [i ].events = (has_ongoing_exchange (clients [i ]) ? ZSOCK_POLLIN : 0 ) |
537+ (has_timeout_expired (clients [i ]) ? ZSOCK_POLLOUT : 0 );
538+ fds [i ].revents = 0 ;
539+ nfds ++ ;
540+ }
537541
538- if (ret < 0 ) {
539- LOG_ERR ("Error in poll:%d" , errno );
540- errno = 0 ;
541- return ret ;
542- } else if (ret == 0 ) {
543- /* Resend all the expired pending messages */
544- ret = coap_client_resend_handler ();
542+ ret = zsock_poll (fds , nfds , COAP_PERIODIC_TIMEOUT );
545543
546- if (ret < 0 ) {
547- LOG_ERR ("Error resending request: %d" , ret );
548- }
544+ if (ret < 0 ) {
545+ ret = - errno ;
546+ LOG_ERR ("Error in poll:%d" , ret );
547+ return ret ;
548+ } else if (ret == 0 ) {
549+ return 0 ;
550+ }
549551
550- if (!has_ongoing_requests ()) {
551- return ret ;
552- }
552+ for (int i = 0 ; i < nfds ; i ++ ) {
553+ if (fds [i ].revents & ZSOCK_POLLOUT ) {
554+ coap_client_resend_handler (clients [i ]);
555+ }
556+ if (fds [i ].revents & ZSOCK_POLLIN ) {
557+ struct coap_packet response ;
558+ bool response_truncated = false;
553559
554- } else {
555- for (int i = 0 ; i < nfds ; i ++ ) {
560+ k_mutex_lock (& clients [i ]-> lock , K_FOREVER );
556561
557- if (fds [i ].revents & ZSOCK_POLLERR ) {
558- LOG_ERR ("Error in poll for socket %d" , fds [i ].fd );
559- clients [i ]-> socket_error = - EIO ;
560- }
561- if (fds [i ].revents & ZSOCK_POLLHUP ) {
562- LOG_ERR ("Error in poll: POLLHUP for socket %d" , fds [i ].fd );
563- clients [i ]-> socket_error = - ENOTCONN ;
564- }
565- if (fds [i ].revents & ZSOCK_POLLNVAL ) {
566- LOG_ERR ("Error in poll: POLLNVAL - fd %d not open" ,
567- fds [i ].fd );
568- clients [i ]-> socket_error = - EINVAL ;
569- }
570- if (fds [i ].revents & ZSOCK_POLLIN ) {
571- clients [i ]-> response_ready = true;
572- }
562+ ret = recv_response (clients [i ], & response , & response_truncated );
563+ if (ret < 0 ) {
564+ LOG_ERR ("Error receiving response" );
565+ cancel_requests_with (clients [i ], - EIO );
566+ k_mutex_unlock (& clients [i ]-> lock );
567+ continue ;
568+ }
573569
570+ ret = handle_response (clients [i ], & response , response_truncated );
571+ if (ret < 0 ) {
572+ LOG_ERR ("Error handling response" );
574573 }
575574
576- return 0 ;
575+ k_mutex_unlock (& clients [i ]-> lock );
576+ }
577+ if (fds [i ].revents & ZSOCK_POLLERR ) {
578+ LOG_ERR ("Error in poll for socket %d" , fds [i ].fd );
579+ cancel_requests_with (clients [i ], - EIO );
580+ }
581+ if (fds [i ].revents & ZSOCK_POLLHUP ) {
582+ LOG_ERR ("Error in poll: POLLHUP for socket %d" , fds [i ].fd );
583+ cancel_requests_with (clients [i ], - EIO );
584+ }
585+ if (fds [i ].revents & ZSOCK_POLLNVAL ) {
586+ LOG_ERR ("Error in poll: POLLNVAL - fd %d not open" , fds [i ].fd );
587+ cancel_requests_with (clients [i ], - EIO );
577588 }
578589 }
579590
580- return ret ;
591+ return 0 ;
581592}
582593
583594static bool token_compare (struct coap_client_internal_request * internal_req ,
@@ -895,14 +906,13 @@ static int handle_response(struct coap_client *client, const struct coap_packet
895906 }
896907 }
897908fail :
898- client -> response_ready = false;
899909 if (ret < 0 || !internal_req -> is_observe ) {
900910 internal_req -> request_ongoing = false;
901911 }
902912 return ret ;
903913}
904914
905- void coap_client_cancel_requests (struct coap_client * client )
915+ static void cancel_requests_with (struct coap_client * client , int error )
906916{
907917 k_mutex_lock (& client -> lock , K_FOREVER );
908918
@@ -914,33 +924,20 @@ void coap_client_cancel_requests(struct coap_client *client)
914924 * do not reenter it. In that case, the user knows their
915925 * request was cancelled anyway.
916926 */
917- report_callback_error (& client -> requests [i ], - ECANCELED );
918- client -> requests [i ].request_ongoing = false;
919- client -> requests [i ].is_observe = false;
927+ report_callback_error (& client -> requests [i ], error );
928+ reset_internal_request (& client -> requests [i ]);
920929 }
921930 }
922931 atomic_clear (& coap_client_recv_active );
923932 k_mutex_unlock (& client -> lock );
924933
925- /* Wait until after zsock_poll() can time out and return. */
926- k_sleep (K_MSEC (COAP_PERIODIC_TIMEOUT ));
927934}
928935
929- static void signal_socket_error (struct coap_client * cli )
936+ void coap_client_cancel_requests (struct coap_client * client )
930937{
931- for (int i = 0 ; i < CONFIG_COAP_CLIENT_MAX_REQUESTS ; i ++ ) {
932- struct coap_client_internal_request * req = & cli -> requests [i ];
933-
934- if (!req -> request_ongoing ) {
935- continue ;
936- }
937-
938- req -> request_ongoing = false;
939- if (req -> coap_request .cb ) {
940- req -> coap_request .cb (cli -> socket_error , 0 , NULL , 0 ,
941- true, req -> coap_request .user_data );
942- }
943- }
938+ cancel_requests_with (client , - ECANCELED );
939+ /* Wait until after zsock_poll() can time out and return. */
940+ k_sleep (K_MSEC (COAP_PERIODIC_TIMEOUT ));
944941}
945942
946943void coap_client_recv (void * coap_cl , void * a , void * b )
@@ -957,41 +954,6 @@ void coap_client_recv(void *coap_cl, void *a, void *b)
957954 goto idle ;
958955 }
959956
960- for (int i = 0 ; i < num_clients ; i ++ ) {
961- if (clients [i ]-> response_ready ) {
962- struct coap_packet response ;
963- bool response_truncated = false;
964-
965- k_mutex_lock (& clients [i ]-> lock , K_FOREVER );
966-
967- ret = recv_response (clients [i ], & response , & response_truncated );
968- if (ret < 0 ) {
969- LOG_ERR ("Error receiving response" );
970- clients [i ]-> response_ready = false;
971- k_mutex_unlock (& clients [i ]-> lock );
972- if (ret == - EOPNOTSUPP ) {
973- LOG_ERR ("Socket misconfigured." );
974- goto idle ;
975- }
976- continue ;
977- }
978-
979- ret = handle_response (clients [i ], & response , response_truncated );
980- if (ret < 0 ) {
981- LOG_ERR ("Error handling response" );
982- }
983-
984- clients [i ]-> response_ready = false;
985- k_mutex_unlock (& clients [i ]-> lock );
986- }
987-
988- if (clients [i ]-> socket_error ) {
989- signal_socket_error (clients [i ]);
990- clients [i ]-> socket_error = 0 ;
991- }
992-
993- }
994-
995957 /* There are more messages coming */
996958 if (has_ongoing_exchanges ()) {
997959 continue ;
0 commit comments