coap_client_misc.c
Go to the documentation of this file.
1 /**
2  * @file coap_client_misc.c
3  * @brief Helper functions for CoAP client
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL COAP_TRACE_LEVEL
33 
34 //Dependencies
35 #include <stdlib.h>
36 #include "core/net.h"
37 #include "coap/coap_client.h"
40 #include "coap/coap_client_misc.h"
41 #include "coap/coap_common.h"
42 #include "coap/coap_debug.h"
43 #include "debug.h"
44 #include "error.h"
45 
46 //Check TCP/IP stack configuration
47 #if (COAP_CLIENT_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Process CoAP client events
52  * @param[in] context Pointer to the CoAP client context
53  * @param[in] timeout Maximum time to wait before returning
54  * @return Error code
55  **/
56 
58 {
59  error_t error;
60  uint_t i;
61  systime_t d;
62  systime_t startTime;
63  systime_t currentTime;
64 
65  //Flush receive buffer
66  context->response.length = 0;
67 
68  //Save current time
69  currentTime = osGetSystemTime();
70  startTime = currentTime;
71 
72 #if (NET_RTOS_SUPPORT == ENABLED)
73  //Process events
74  do
75  {
76 #endif
77  //Maximum time to wait for an incoming datagram
78  if(timeCompare(startTime + timeout, currentTime) > 0)
79  d = startTime + timeout - currentTime;
80  else
81  d = 0;
82 
83  //Limit the delay
85 
86  //Wait for incoming traffic
87  coapClientWaitForDatagram(context, d);
88 
89  //Get current time
90  currentTime = osGetSystemTime();
91 
92  //Receive datagram, if any
93  error = coapClientReceiveDatagram(context, context->response.buffer,
94  COAP_MAX_MSG_SIZE, &context->response.length);
95 
96  //Any datagram received?
97  if(error == NO_ERROR)
98  {
99  //Parse the received datagram
100  error = coapParseMessage(&context->response);
101 
102  //Check status code
103  if(error == NO_ERROR)
104  {
105  //Rewind to the beginning of the buffer
106  context->response.pos = 0;
107  //Terminate the payload with a NULL character
108  context->response.buffer[context->response.length] = '\0';
109 
110  //Debug message
111  TRACE_INFO("CoAP message received (%" PRIuSIZE " bytes)...\r\n",
112  context->response.length);
113 
114  //Dump the contents of the message for debugging purpose
115  coapDumpMessage(context->response.buffer,
116  context->response.length);
117 
118  //Try to match the response with an outstanding request
119  for(i = 0; i < COAP_CLIENT_NSTART; i++)
120  {
121  //Apply request/response matching rules
122  error = coapClientMatchResponse(&context->request[i],
123  &context->response);
124 
125  //Test if the response matches the current request
126  if(error != ERROR_UNEXPECTED_MESSAGE)
127  break;
128  }
129 
130  //Check status code
131  if(error == NO_ERROR)
132  {
133  //Process the received CoAP message
134  error = coapClientProcessResponse(&context->request[i],
135  &context->response);
136  }
137  else if(error == ERROR_UNEXPECTED_MESSAGE)
138  {
139  //Reject the received CoAP message
140  error = coapClientRejectResponse(context, &context->response);
141  }
142  else
143  {
144  //Just for sanity
145  }
146  }
147  else
148  {
149  //Debug message
150  TRACE_DEBUG("Invalid CoAP message received!\r\n");
151  //Silently discard the received datagram
152  error = NO_ERROR;
153  }
154  }
155  else if(error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
156  {
157  //No datagram has been received
158  error = NO_ERROR;
159  }
160  else
161  {
162  //Just for sanity
163  }
164 
165  //Check status code
166  if(error == NO_ERROR)
167  {
168  //Process request-specific events
169  for(i = 0; i < COAP_CLIENT_NSTART; i++)
170  {
171  //Manage retransmission for the current request
172  error = coapClientProcessRequestEvents(&context->request[i]);
173  //Any error to report?
174  if(error)
175  break;
176  }
177  }
178 
179 #if (NET_RTOS_SUPPORT == ENABLED)
180  //Check whether the timeout has elapsed
181  } while(error == NO_ERROR && context->response.length == 0 && d > 0);
182 #endif
183 
184  //Return status code
185  return error;
186 }
187 
188 
189 /**
190  * @brief Process request-specific events
191  * @param[in] request CoAP request handle
192  * @return Error code
193  **/
194 
196 {
197  error_t error;
198  systime_t time;
199  CoapClientContext *context;
200  CoapMessageHeader *header;
201 
202  //Initialize status code
203  error = NO_ERROR;
204 
205  //Get current time
206  time = osGetSystemTime();
207 
208  //Point to the CoAP client context
209  context = request->context;
210  //Point to the CoAP message header
211  header = (CoapMessageHeader *) request->message.buffer;
212 
213  //Check current state
214  if(request->state == COAP_REQ_STATE_TRANSMIT)
215  {
216  //Debug message
217  TRACE_INFO("Sending CoAP message (%" PRIuSIZE " bytes)...\r\n",
218  request->message.length);
219 
220  //Dump the contents of the message for debugging purpose
221  coapDumpMessage(request->message.buffer, request->message.length);
222 
223  //Send CoAP request
224  error = coapClientSendDatagram(context, request->message.buffer,
225  request->message.length);
226 
227  //Save the time at which the message was sent
228  request->retransmitStartTime = osGetSystemTime();
229 
230  //Check retransmission counter
231  if(request->retransmitCount == 0)
232  {
233  //Save request start time
234  request->startTime = request->retransmitStartTime;
235 
236  //The initial timeout is set to a random duration
237  request->retransmitTimeout = netGetRandRange(COAP_CLIENT_ACK_TIMEOUT_MIN,
239  }
240  else
241  {
242  //The timeout is doubled
243  request->retransmitTimeout *= 2;
244  }
245 
246  //Increment retransmission counter
247  request->retransmitCount++;
248 
249  //Wait for a response to be received
251  }
252  else if(request->state == COAP_REQ_STATE_RECEIVE)
253  {
254  //Check whether the timeout has elapsed
255  if(timeCompare(time, request->startTime + request->timeout) >= 0)
256  {
257  //Report a timeout error
259  }
260  else if(timeCompare(time, request->retransmitStartTime +
261  request->retransmitTimeout) >= 0)
262  {
263  //The reliable transmission of a message is initiated by marking the
264  //message as Confirmable in the CoAP header
265  if(header->type == COAP_TYPE_CON)
266  {
267  //The sender retransmits the Confirmable message at exponentially
268  //increasing intervals, until it receives an acknowledgment or
269  //runs out of attempts (refer to RFC 7252, section 4.2)
270  if(request->retransmitCount < COAP_CLIENT_MAX_RETRANSMIT)
271  {
272  //When the timeout is triggered and the retransmission counter is
273  //less than MAX_RETRANSMIT, the message is retransmitted
274  error = coapClientChangeRequestState(request,
276  }
277  else
278  {
279  //If the retransmission counter reaches MAX_RETRANSMIT on a
280  //timeout, then the attempt to transmit the message is canceled
281  //and the application process informed of failure
282  error = coapClientChangeRequestState(request,
284  }
285  }
286  }
287  else
288  {
289  //Just for sanity
290  }
291  }
292  else if(request->state == COAP_REQ_STATE_SEPARATE)
293  {
294  //Check whether the timeout has elapsed
295  if(timeCompare(time, request->startTime + request->timeout) >= 0)
296  {
297  //Report a timeout error
299  }
300  }
301  else if(request->state == COAP_REQ_STATE_OBSERVE)
302  {
303  //Check whether the timeout has elapsed
304  if(timeCompare(time, request->retransmitStartTime +
305  request->retransmitTimeout) >= 0)
306  {
307  //Point to the CoAP message header
308  header = (CoapMessageHeader *) request->message.buffer;
309 
310  //The message ID is a 16-bit unsigned integer that is generated by
311  //the sender of a Confirmable or Non-confirmable message
312  coapClientGenerateMessageId(context, header);
313 
314  //Reset retransmission counter
315  request->retransmitCount = 0;
316 
317  //To re-register its interest in a resource, a client may issue a
318  //new GET request with the same token as the original
320  }
321  }
322  else
323  {
324  //Just for sanity
325  }
326 
327  //Return status code
328  return error;
329 }
330 
331 
332 /**
333  * @brief Update CoAP request state
334  * @param[in] request CoAP request handle
335  * @param[in] newState New state to switch to
336  * @return Error code
337  **/
338 
340  CoapRequestState newState)
341 {
342  error_t error;
343  CoapRequestStatus status;
344  CoapClientContext *context;
345 
346  //Initialize status code
347  error = NO_ERROR;
348 
349  //Point to the CoAP client context
350  context = request->context;
351 
352  //Switch to the new state
353  request->state = newState;
354 
355  //Check whether a request is ready to be transmitted
356  if(newState == COAP_REQ_STATE_TRANSMIT)
357  {
358  //Notify the CoAP client
359  osSetEvent(&context->event);
360  }
361 
362  //The CoAP client operates in asynchronous mode when a callback function
363  //has been defined
364  if(request->callback != NULL)
365  {
366  //Check whether the request has terminated
367  if(newState == COAP_REQ_STATE_OBSERVE ||
368  newState == COAP_REQ_STATE_DONE ||
369  newState == COAP_REQ_STATE_RESET ||
370  newState == COAP_REQ_STATE_TIMEOUT ||
371  newState == COAP_REQ_STATE_CANCELED)
372  {
373  //Get the status of the request
374  if(newState == COAP_REQ_STATE_RESET)
375  {
376  //A Reset message has been received
377  status = COAP_REQUEST_STATUS_RESET;
378  }
379  else if(newState == COAP_REQ_STATE_TIMEOUT)
380  {
381  //A timeout error has occurred
383  }
384  else if(newState == COAP_REQ_STATE_CANCELED)
385  {
386  //The request has been canceled
388  }
389  else
390  {
391  //The request has successfully completed
393  }
394 
395  //Release exclusive access to the CoAP client context
396  osReleaseMutex(&context->mutex);
397  //Invoke callback function
398  error = request->callback(context, request, status, request->param);
399  //Acquire exclusive access to the CoAP client context
400  osAcquireMutex(&context->mutex);
401  }
402 
403  //Asynchronous requests are automatically released
404  if(newState == COAP_REQ_STATE_DONE ||
405  newState == COAP_REQ_STATE_RESET ||
406  newState == COAP_REQ_STATE_TIMEOUT ||
407  newState == COAP_REQ_STATE_CANCELED)
408  {
409  if(request->state != COAP_REQ_STATE_TRANSMIT)
410  {
411  //Release the resources associated with a CoAP request
412  request->state = COAP_REQ_STATE_UNUSED;
413  }
414  }
415  }
416 
417  //Return status code
418  return error;
419 }
420 
421 
422 /**
423  * @brief Check whether a response matches the specified request
424  * @param[in] request CoAP request handle
425  * @param[in] response Pointer to the response message
426  * @return Error code
427  **/
428 
430  const CoapMessage *response)
431 {
432  error_t error;
433  const CoapMessageHeader *reqHeader;
434  const CoapMessageHeader *respHeader;
435 
436  //Get CoAP request and response headers
437  reqHeader = (CoapMessageHeader *) request->message.buffer;
438  respHeader = (CoapMessageHeader *) response->buffer;
439 
440  //Initialize status code
441  error = ERROR_UNEXPECTED_MESSAGE;
442 
443  //Check request state
444  if(request->state == COAP_REQ_STATE_RECEIVE)
445  {
446  //Confirmable request?
447  if(reqHeader->type == COAP_TYPE_CON)
448  {
449  //Check the type of the response
450  if(respHeader->type == COAP_TYPE_CON ||
451  respHeader->type == COAP_TYPE_NON)
452  {
453  //Tokens are used to match a response with a request
454  if(coapCompareToken(respHeader, reqHeader))
455  {
456  //A matching response has been received
457  error = NO_ERROR;
458  }
459  }
460  else if(respHeader->type == COAP_TYPE_ACK)
461  {
462  //The message ID of the Acknowledgment must match the message ID
463  //of the Confirmable message
464  if(respHeader->mid == reqHeader->mid)
465  {
466  //Empty ACK received?
467  if(respHeader->code == COAP_CODE_EMPTY)
468  {
469  //When a Confirmable message carrying a request is acknowledged
470  //with an Empty message, a separate response is sent in a
471  //separate message exchange
472  error = NO_ERROR;
473  }
474  else
475  {
476  //In a piggybacked response, the message ID of the Confirmable
477  //request and the Acknowledgment must match, and the tokens of
478  //the response and original request must match
479  if(coapCompareToken(respHeader, reqHeader))
480  {
481  //A matching response has been received
482  error = NO_ERROR;
483  }
484  }
485  }
486  }
487  else if(respHeader->code == COAP_TYPE_RST)
488  {
489  //The message ID of the Reset must match the message ID of
490  //the Confirmable message
491  if(respHeader->mid == reqHeader->mid)
492  {
493  //A Reset message indicates that the request was received by the
494  //server, but some context is missing to properly process it
495  error = NO_ERROR;
496  }
497  }
498  else
499  {
500  //Just for sanity
501  }
502  }
503  //Non-Confirmable request?
504  else
505  {
506  //If a request is sent in a Non-confirmable message, then the response
507  //is sent using a new Non-confirmable message, although the server may
508  //instead send a Confirmable message (refer to RFC 7252, section 2.2)
509  if(respHeader->type == COAP_TYPE_CON ||
510  respHeader->type == COAP_TYPE_NON)
511  {
512  //Tokens are used to match a response with a request
513  if(coapCompareToken(respHeader, reqHeader))
514  {
515  //A matching response has been received
516  error = NO_ERROR;
517  }
518  }
519  else if(respHeader->type == COAP_TYPE_RST)
520  {
521  //The message ID of the Reset must match the message ID of
522  //the Non-confirmable message
523  if(respHeader->mid == reqHeader->mid)
524  {
525  //A matching response has been received
526  error = NO_ERROR;
527  }
528  }
529  else
530  {
531  //Just for sanity
532  }
533  }
534  }
535  else if(request->state == COAP_REQ_STATE_SEPARATE ||
536  request->state == COAP_REQ_STATE_OBSERVE)
537  {
538  //Check the type of the response
539  if(respHeader->type == COAP_TYPE_CON ||
540  respHeader->type == COAP_TYPE_NON)
541  {
542  //Tokens are used to match a response with a request
543  if(coapCompareToken(respHeader, reqHeader))
544  {
545  //A matching response has been received
546  error = NO_ERROR;
547  }
548  }
549  }
550  else
551  {
552  //Just for sanity
553  }
554 
555  //Return status code
556  return error;
557 }
558 
559 
560 /**
561  * @brief Process CoAP response
562  * @param[in] request CoAP request handle
563  * @param[in] response Pointer to the response message
564  * @return Error code
565  **/
566 
568  const CoapMessage *response)
569 {
570  error_t error;
571  CoapClientContext *context;
572  const CoapMessageHeader *header;
573 
574  //Point to the CoAP client context
575  context = request->context;
576  //Point to CoAP response header
577  header = (CoapMessageHeader *) response->buffer;
578 
579  //Confirmable response received?
580  if(header->type == COAP_TYPE_CON)
581  {
582  //The Acknowledgment message must echo the message ID of the
583  //Confirmable message
584  coapClientSendAck(context, ntohs(header->mid));
585  }
586 
587  //Check the type of the response
588  if(header->type == COAP_TYPE_ACK &&
589  header->code == COAP_CODE_EMPTY)
590  {
591  //When a Confirmable message carrying a request is acknowledged with
592  //an Empty message, a separate response is sent in a separate message
593  //exchange
595  }
596  else if(header->type == COAP_TYPE_CON ||
597  header->type == COAP_TYPE_NON ||
598  header->type == COAP_TYPE_ACK)
599  {
600 #if (COAP_CLIENT_OBSERVE_SUPPORT == ENABLED)
601  uint32_t value;
602 
603  //Search the CoAP request for an Observe option
604  error = coapGetUintOption(&request->message, COAP_OPT_OBSERVE, 0, &value);
605 
606  //Observe option included in the request?
607  if(!error)
608  {
609  //The client requests the server to add or remove an entry in the
610  //list of observers of the resource depending on the option value
612  {
613  //Process notification response
614  error = coapClientProcessNotification(request, response);
615  }
616  else
617  {
618  //When the client deregisters, it is considered no longer
619  //interested in the resource
620  error = coapClientChangeRequestState(request,
622  }
623  }
624  else
625 #endif
626  {
627  //The request has successfully completed
629  }
630  }
631  else if(header->type == COAP_TYPE_RST)
632  {
633  //A Reset message indicates that the request was received by the server,
634  //but some context is missing to properly process it
636  }
637  else
638  {
639  //Report an error
640  error = ERROR_INVALID_TYPE;
641  }
642 
643  //Return status code
644  return error;
645 }
646 
647 
648 /**
649  * @brief Reject a CoAP response
650  * @param[in] context Pointer to the CoAP client context
651  * @param[in] response Pointer to the response message to be rejected
652  * @return Error code
653  **/
654 
656  const CoapMessage *response)
657 {
658  error_t error;
659  const CoapMessageHeader *header;
660 
661  //Debug message
662  TRACE_INFO("Rejecting CoAP message...\r\n");
663 
664  //Point to the CoAP message header
665  header = (CoapMessageHeader *) response;
666 
667  //Check the type of the response
668  if(header->type == COAP_TYPE_CON)
669  {
670  //Rejecting a Confirmable message is effected by sending a matching
671  //Reset message
672  error = coapClientSendReset(context, ntohs(header->mid));
673  }
674  else if(header->type == COAP_TYPE_NON)
675  {
676  //Rejecting a Non-confirmable message may involve sending a matching
677  //Reset message, and apart from the Reset message the rejected message
678  //must be silently ignored (refer to RFC 7252, section 4.3)
679  error = NO_ERROR;
680  }
681  else
682  {
683  //Rejecting an Acknowledgment or Reset message is effected by
684  //silently ignoring it (refer to RFC 7252, section 4.2)
685  error = NO_ERROR;
686  }
687 
688  //Return status code
689  return error;
690 }
691 
692 
693 /**
694  * @brief Send Acknowledgment message
695  * @param[in] context Pointer to the CoAP client context
696  * @param[in] mid Message ID
697  * @return Error code
698  **/
699 
701 {
703 
704  //Format Acknowledgment message
705  message.version = COAP_VERSION_1;
706  message.type = COAP_TYPE_ACK;
707  message.tokenLen = 0;
708  message.code = COAP_CODE_EMPTY;
709 
710  //The Acknowledgment message message must echo the message ID of the
711  //confirmable message and must be empty
712  message.mid = htons(mid);
713 
714  //Debug message
715  TRACE_INFO("Sending Acknowledgment message (%" PRIuSIZE " bytes)...\r\n",
716  sizeof(message));
717 
718  //Dump the contents of the message for debugging purpose
719  coapDumpMessage(&message, sizeof(message));
720 
721  //Send CoAP message
722  return coapClientSendDatagram(context, &message, sizeof(message));
723 }
724 
725 
726 /**
727  * @brief Send Reset message
728  * @param[in] context Pointer to the CoAP client context
729  * @param[in] mid Message ID
730  * @return Error code
731  **/
732 
734 {
736 
737  //Format Reset message
738  message.version = COAP_VERSION_1;
739  message.type = COAP_TYPE_RST;
740  message.tokenLen = 0;
741  message.code = COAP_CODE_EMPTY;
742 
743  //The Reset message message must echo the message ID of the confirmable
744  //message and must be empty
745  message.mid = htons(mid);
746 
747  //Debug message
748  TRACE_INFO("Sending Reset message (%" PRIuSIZE " bytes)...\r\n",
749  sizeof(message));
750 
751  //Dump the contents of the message for debugging purpose
752  coapDumpMessage(&message, sizeof(message));
753 
754  //Send CoAP message
755  return coapClientSendDatagram(context, &message, sizeof(message));
756 }
757 
758 
759 /**
760  * @brief Generate a new message identifier
761  * @param[in] context Pointer to the CoAP client context
762  * @param[in] header Pointer to the CoAP message header
763  **/
764 
766  CoapMessageHeader *header)
767 {
768  //The message ID is a 16-bit unsigned integer that is generated by
769  //the sender of a Confirmable or Non-confirmable message
770  header->mid = htons(context->mid);
771 
772  //Increment message identifier
773  context->mid++;
774 }
775 
776 
777 /**
778  * @brief Generate a new token
779  * @param[in] context Pointer to the CoAP client context
780  * @param[in] header Pointer to the CoAP message header
781  **/
782 
784  CoapMessageHeader *header)
785 {
786  uint8_t i;
787 
788  //Generate a random token
789  for(i = 0; i < header->tokenLen; i++)
790  {
791  header->token[i] = (uint8_t) netGetRand();
792  }
793 }
794 
795 #endif
#define htons(value)
Definition: cpu_endian.h:392
error_t coapClientProcessRequestEvents(CoapClientRequest *request)
Process request-specific events.
error_t coapGetUintOption(const CoapMessage *message, uint16_t optionNum, uint_t optionIndex, uint32_t *optionValue)
Get the value of the specified uint option.
Definition: coap_option.c:651
error_t coapClientSendDatagram(CoapClientContext *context, const void *data, size_t length)
Send a datagram.
@ ERROR_WOULD_BLOCK
Definition: error.h:95
error_t coapClientSendReset(CoapClientContext *context, uint16_t mid)
Send Reset message.
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:192
@ COAP_REQ_STATE_TRANSMIT
@ COAP_REQ_STATE_RESET
@ COAP_REQUEST_STATUS_SUCCESS
@ COAP_REQ_STATE_DONE
#define CoapClientContext
Definition: coap_client.h:139
#define timeCompare(t1, t2)
Definition: os_port.h:42
error_t coapClientChangeRequestState(CoapClientRequest *request, CoapRequestState newState)
Update CoAP request state.
#define COAP_CLIENT_NSTART
Definition: coap_client.h:84
#define CoapClientRequest
Definition: coap_client.h:143
@ COAP_REQUEST_STATUS_RESET
@ COAP_OBSERVE_REGISTER
Definition: coap_option.h:134
#define COAP_MAX_MSG_SIZE
Definition: coap_common.h:39
#define COAP_CLIENT_TICK_INTERVAL
Definition: coap_client.h:70
@ COAP_VERSION_1
CoAP version 1.
Definition: coap_common.h:74
@ COAP_REQ_STATE_OBSERVE
uint16_t mid
Definition: coap_common.h:182
error_t
Error codes.
Definition: error.h:42
bool_t coapCompareToken(const CoapMessageHeader *header1, const CoapMessageHeader *header2)
Token comparison.
Definition: coap_message.c:547
error_t coapClientWaitForDatagram(CoapClientContext *context, systime_t timeout)
Wait for incoming datagrams.
#define COAP_CLIENT_ACK_TIMEOUT_MIN
Definition: coap_client.h:98
error_t coapClientReceiveDatagram(CoapClientContext *context, void *data, size_t size, size_t *received)
Receive a datagram.
CoAP message.
Definition: coap_message.h:55
__start_packed struct @106 CoapMessageHeader
CoAP message format.
CoapRequestStatus
Request status.
CoAP client.
error_t coapClientProcessEvents(CoapClientContext *context, systime_t timeout)
Process CoAP client events.
@ ERROR_INVALID_TYPE
Definition: error.h:113
@ COAP_OPT_OBSERVE
Definition: coap_option.h:96
Error codes description.
@ COAP_TYPE_ACK
Acknowledgment message.
Definition: coap_common.h:96
#define COAP_CLIENT_MAX_RETRANSMIT
Definition: coap_client.h:91
#define TRACE_INFO(...)
Definition: debug.h:94
@ COAP_TYPE_CON
Confirmable message.
Definition: coap_common.h:94
#define MIN(a, b)
Definition: os_port.h:62
@ COAP_TYPE_RST
Reset message.
Definition: coap_common.h:97
@ COAP_REQ_STATE_CANCELED
error_t coapClientProcessNotification(CoapClientRequest *request, const CoapMessage *response)
Process notification response.
uint32_t netGetRand(void)
Get a random value.
Definition: net.c:1810
@ COAP_REQ_STATE_UNUSED
int32_t netGetRandRange(int32_t min, int32_t max)
Get a random value in the specified range.
Definition: net.c:1841
void coapClientGenerateToken(CoapClientContext *context, CoapMessageHeader *header)
Generate a new token.
#define COAP_CLIENT_ACK_TIMEOUT_MAX
Definition: coap_client.h:105
#define ntohs(value)
Definition: cpu_endian.h:398
Helper functions for CoAP client.
#define TRACE_DEBUG(...)
Definition: debug.h:106
error_t coapClientMatchResponse(const CoapClientRequest *request, const CoapMessage *response)
Check whether a response matches the specified request.
void coapClientGenerateMessageId(CoapClientContext *context, CoapMessageHeader *header)
Generate a new message identifier.
@ ERROR_TIMEOUT
Definition: error.h:94
@ COAP_REQUEST_STATUS_TIMEOUT
uint32_t time
error_t coapClientSendAck(CoapClientContext *context, uint16_t mid)
Send Acknowledgment message.
@ COAP_REQ_STATE_RECEIVE
Data logging functions for debugging purpose (CoAP)
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
uint8_t message[]
Definition: chap.h:152
@ COAP_REQ_STATE_SEPARATE
@ COAP_REQUEST_STATUS_CANCELED
@ COAP_CODE_EMPTY
Definition: coap_common.h:119
error_t coapParseMessage(const CoapMessage *message)
Parse CoAP message.
Definition: coap_message.c:51
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
uint8_t buffer[COAP_MAX_MSG_SIZE]
Definition: coap_message.h:57
Transport protocol abstraction layer.
error_t coapClientProcessResponse(CoapClientRequest *request, const CoapMessage *response)
Process CoAP response.
uint8_t value[]
Definition: dtls_misc.h:150
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
@ COAP_TYPE_NON
Non-confirmable message.
Definition: coap_common.h:95
Definitions common to CoAP client and server.
uint32_t systime_t
Definition: compiler_port.h:46
error_t coapClientRejectResponse(CoapClientContext *context, const CoapMessage *response)
Reject a CoAP response.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
error_t coapDumpMessage(const void *message, size_t length)
Dump CoAP message for debugging purpose.
Definition: coap_debug.c:123
@ COAP_REQ_STATE_TIMEOUT
CoapRequestState
CoAP request states.
systime_t osGetSystemTime(void)
Retrieve system time.