0.01.00
coap.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, The OpenThread Authors.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holder nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef COAP_HPP_
30 #define COAP_HPP_
31 
32 #include "openthread-core-config.h"
33 
34 #include <openthread/coap.h>
35 
36 #include "coap/coap_header.hpp"
37 #include "common/debug.hpp"
38 #include "common/locator.hpp"
39 #include "common/message.hpp"
40 #include "common/timer.hpp"
41 #include "net/ip6.hpp"
42 #include "net/netif.hpp"
43 #include "net/udp6.hpp"
44 
50 namespace ot {
51 
52 class ThreadNetif;
53 
54 namespace Coap {
55 
67 enum
68 {
70  kAckRandomFactorNumerator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR,
71  kAckRandomFactorDenominator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR,
73  kNStart = 1,
74  kDefaultLeisure = 5,
75  kProbingRate = 1,
76 
77  // Note that 2 << (kMaxRetransmit - 1) is equal to kMaxRetransmit power of 2
78  kMaxTransmitSpan = kAckTimeout * ((2 << (kMaxRetransmit - 1)) - 1) *
79  kAckRandomFactorNumerator / kAckRandomFactorDenominator,
80  kMaxTransmitWait = kAckTimeout * ((2 << kMaxRetransmit) - 1) *
81  kAckRandomFactorNumerator / kAckRandomFactorDenominator,
82  kMaxLatency = 100,
83  kProcessingDelay = kAckTimeout,
84  kMaxRtt = 2 * kMaxLatency + kProcessingDelay,
85  kExchangeLifetime = kMaxTransmitSpan + 2 * (kMaxLatency) + kProcessingDelay,
86  kNonLifetime = kMaxTransmitSpan + kMaxLatency
87 };
88 
95 {
96  friend class CoapBase;
97 
98 public:
99 
105  mDestinationPort(0),
106  mResponseHandler(NULL),
107  mResponseContext(NULL),
108  mNextTimerShot(0),
109  mRetransmissionTimeout(0),
110  mRetransmissionCount(0),
111  mAcknowledged(false),
112  mConfirmable(false) {};
113 
123  CoapMetadata(bool aConfirmable, const Ip6::MessageInfo &aMessageInfo,
124  otCoapResponseHandler aHandler, void *aContext);
125 
135  otError AppendTo(Message &aMessage) const {
136  return aMessage.Append(this, sizeof(*this));
137  };
138 
147  uint16_t ReadFrom(const Message &aMessage) {
148  return aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
149  };
150 
159  int UpdateIn(Message &aMessage) const {
160  return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
161  }
162 
171  bool IsEarlier(uint32_t aTime) const { return (static_cast<int32_t>(aTime - mNextTimerShot) > 0); };
172 
181  bool IsLater(uint32_t aTime) const { return (static_cast<int32_t>(aTime - mNextTimerShot) < 0); };
182 
183 private:
184  Ip6::Address mSourceAddress;
185  Ip6::Address mDestinationAddress;
186  uint16_t mDestinationPort;
187  otCoapResponseHandler mResponseHandler;
188  void *mResponseContext;
189  uint32_t mNextTimerShot;
190  uint32_t mRetransmissionTimeout;
191  uint8_t mRetransmissionCount;
192  bool mAcknowledged: 1;
193  bool mConfirmable: 1;
195 
200 class Resource : public otCoapResource
201 {
202  friend class CoapBase;
203 
204 public:
205  enum
206  {
207  kMaxReceivedUriPath = 32,
208  };
209 
217  Resource(const char *aUriPath, otCoapRequestHandler aHandler, void *aContext) {
218  mUriPath = aUriPath;
219  mHandler = aHandler;
220  mContext = aContext;
221  mNext = NULL;
222  }
223 
230  Resource *GetNext(void) const { return static_cast<Resource *>(mNext); };
231 
232 private:
233  void HandleRequest(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const {
234  mHandler(mContext, &aHeader, &aMessage, &aMessageInfo);
235  }
236 };
237 
243 {
244 public:
249  EnqueuedResponseHeader(void): mDequeueTime(0), mMessageInfo() {}
250 
258  mDequeueTime(TimerMilli::GetNow() + TimerMilli::SecToMsec(kExchangeLifetime)),
259  mMessageInfo(aMessageInfo) {}
260 
269  otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
270 
279  uint16_t ReadFrom(const Message &aMessage) {
280  return aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
281  }
282 
289  static void RemoveFrom(Message &aMessage) {
290  assert(aMessage.SetLength(aMessage.GetLength() - sizeof(EnqueuedResponseHeader)) == OT_ERROR_NONE);
291  }
292 
302  bool IsEarlier(uint32_t aTime) const { return (static_cast<int32_t>(aTime - mDequeueTime) > 0); }
303 
310  uint32_t GetRemainingTime(void) const;
311 
318  const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
319 
320 private:
321  uint32_t mDequeueTime;
322  const Ip6::MessageInfo mMessageInfo;
323 };
324 
330 {
331 public:
340  ResponsesQueue(otInstance &aInstance, Timer::Handler aHandler, void *aContext);
341 
353  void EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
354 
359  void DequeueOldestResponse(void);
360 
365  void DequeueAllResponses(void);
366 
379  otError GetMatchedResponseCopy(const Header &aHeader,
380  const Ip6::MessageInfo &aMessageInfo,
381  Message **aResponse);
382 
396  otError GetMatchedResponseCopy(const Message &aRequest,
397  const Ip6::MessageInfo &aMessageInfo,
398  Message **aResponse);
399 
406  const MessageQueue &GetResponses(void) const { return mQueue; }
407 
415  void HandleTimer(void);
416 
417 private:
418  enum
419  {
421  };
422 
423  void DequeueResponse(Message &aMessage) { mQueue.Dequeue(aMessage); aMessage.Free(); }
424 
425  MessageQueue mQueue;
426  TimerMilli mTimer;
427 };
428 
434 {
435  friend class ResponsesQueue;
436 
437 public:
451  typedef otError(* Interceptor)(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext);
452 
461  otError Start(uint16_t aPort);
462 
469  otError Stop(void);
470 
477  uint16_t GetPort(void) { return mSocket.GetSockName().mPort; };
478 
488  otError AddResource(Resource &aResource);
489 
496  void RemoveResource(Resource &aResource);
497 
498  /* This function sets the default handler for unhandled CoAP requests.
499  *
500  * @param[in] aHandler A function pointer that shall be called when an unhandled request arrives.
501  * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used.
502  */
503  void SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext);
504 
514  Message *NewMessage(const Header &aHeader, uint8_t aPriority = kDefaultCoapMessagePriority);
515 
532  otError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
533  otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
534 
546  otError SendReset(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
547  return SendEmptyMessage(OT_COAP_TYPE_RESET, aRequestHeader, aMessageInfo);
548  };
549 
562  otError SendHeaderResponse(Header::Code aCode, const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo);
563 
575  otError SendAck(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
576  return SendEmptyMessage(OT_COAP_TYPE_ACKNOWLEDGMENT, aRequestHeader, aMessageInfo);
577  };
578 
590  otError SendEmptyAck(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
591  return (aRequestHeader.GetType() == OT_COAP_TYPE_CONFIRMABLE ?
592  SendHeaderResponse(OT_COAP_CODE_CHANGED, aRequestHeader, aMessageInfo) :
594  }
595 
606  otError SendNotFound(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
607  return SendHeaderResponse(OT_COAP_CODE_NOT_FOUND, aRequestHeader, aMessageInfo);
608  }
609 
620  otError AbortTransaction(otCoapResponseHandler aHandler, void *aContext);
621 
629  void SetInterceptor(Interceptor aInterceptor, void *aContext) {
630  mInterceptor = aInterceptor;
631  mContext = aContext;
632  }
633 
640  const MessageQueue &GetRequestMessages(void) const { return mPendingRequests; }
641 
648  const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); }
649 
650 protected:
659  CoapBase(otInstance &aInstance, Timer::Handler aRetransmissionTimerHandler,
660  Timer::Handler aResponsesQueueTimerHandler);
661 
669  void HandleRetransmissionTimer(void);
670 
678  void HandleResponsesQueueTimer(void) { mResponsesQueue.HandleTimer(); }
679 
687  virtual otError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
688 
696  virtual void Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
697 
698  Ip6::UdpSocket mSocket;
699 
700 private:
701  enum
702  {
703  kDefaultCoapMessagePriority = Message::kPriorityLow,
704  };
705 
706  static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
707 
708  Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength,
709  const CoapMetadata &aCoapMetadata);
710  void DequeueMessage(Message &aMessage);
711  Message *FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo,
712  Header &aRequestHeader, CoapMetadata &aCoapMetadata);
713  void FinalizeCoapTransaction(Message &aRequest, const CoapMetadata &aCoapMetadata, Header *aResponseHeader,
714  Message *aResponse, const Ip6::MessageInfo *aMessageInfo, otError aResult);
715 
716  void ProcessReceivedRequest(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
717  void ProcessReceivedResponse(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
718 
719  otError SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
720  otError SendEmptyMessage(Header::Type aType, const Header &aRequestHeader,
721  const Ip6::MessageInfo &aMessageInfo);
722 
723  MessageQueue mPendingRequests;
724  uint16_t mMessageId;
725  TimerMilli mRetransmissionTimer;
726 
727  Resource *mResources;
728 
729  void *mContext;
730  Interceptor mInterceptor;
731  ResponsesQueue mResponsesQueue;
732 
733  otCoapRequestHandler mDefaultHandler;
734  void *mDefaultHandlerContext;
735 };
736 
741 class Coap: public CoapBase
742 {
743 public:
750  Coap(otInstance &aInstance);
751 
752 private:
753  static Coap &GetOwner(const Context &aContext);
754  static void HandleRetransmissionTimer(Timer &aTimer);
755  static void HandleResponsesQueueTimer(Timer &aTimer);
756 };
757 
758 #if OPENTHREAD_ENABLE_APPLICATION_COAP
759 
764 class ApplicationCoap: public CoapBase
765 {
766 public:
773  ApplicationCoap(otInstance &aInstance);
774 
775 private:
776  static ApplicationCoap &GetOwner(const Context &aContext);
777  static void HandleRetransmissionTimer(Timer &aTimer);
778  static void HandleResponsesQueueTimer(Timer &aTimer);
779 };
780 
781 #endif
782 
783 } // namespace Coap
784 } // namespace ot
785 
786 #endif // COAP_HPP_
otError AppendTo(Message &aMessage) const
This method append metadata to the message.
Definition: coap.hpp:269
This type represents all the static / global variables used by OpenThread allocated in one place...
Definition: openthread-instance.h:59
This class implements metadata required for caching CoAP responses.
Definition: coap.hpp:242
Definition: cli.cpp:90
This class implements a message queue.
Definition: message.hpp:806
#define OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT
Maximum number of retransmissions for CoAP Confirmable messages (RFC7252 default value is 4)...
Definition: openthread-core-default-config.h:413
uint16_t ReadFrom(const Message &aMessage)
This method reads request data from the message.
Definition: coap.hpp:147
otCoapCode
CoAP Code values.
Definition: coap.h:84
void(* Handler)(Timer &aTimer)
This function pointer is called when the timer expires.
Definition: timer.hpp:86
This class implements CoAP resource handling.
Definition: coap.hpp:200
This class implements an IPv6 address object.
Definition: ip6_address.hpp:60
#define OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR
Numerator of ACK_RANDOM_FACTOR used to calculate maximum spacing before first retransmission when ACK...
Definition: openthread-core-default-config.h:392
Type GetType(void) const
This method returns the Type value.
Definition: coap_header.hpp:147
void HandleResponsesQueueTimer(void)
ResponsesQueue timer handler.
Definition: coap.hpp:678
This file includes definitions for locator class for OpenThread objects.
uint16_t GetLength(void) const
This method returns the number of bytes in the message.
Definition: message.hpp:252
otError SendEmptyAck(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo)
This method sends a CoAP ACK message on which a dummy CoAP response is piggybacked.
Definition: coap.hpp:590
Acknowledgment.
Definition: coap.h:70
Changed.
Definition: coap.h:96
const Ip6::MessageInfo & GetMessageInfo(void) const
This method returns the message info of cached CoAP response.
Definition: coap.hpp:318
This file includes definitions for generating and processing CoAP headers.
Input arguments are invalid.
Definition: types.h:147
otError SendNotFound(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo)
This method sends a header-only CoAP message to indicate no resource matched for the request...
Definition: coap.hpp:606
This class implements message information for an IPv6 message.
Definition: socket.hpp:57
const MessageQueue & GetRequestMessages(void) const
This method returns a reference to the request message list.
Definition: coap.hpp:640
uint16_t Read(uint16_t aOffset, uint16_t aLength, void *aBuf) const
This method reads bytes from the message.
Definition: message.cpp:475
otError SendReset(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo)
This method sends a CoAP reset message.
Definition: coap.hpp:546
Resource * GetNext(void) const
This method returns a pointer to the next resource.
Definition: coap.hpp:230
Resource(const char *aUriPath, otCoapRequestHandler aHandler, void *aContext)
This constructor initializes the resource.
Definition: coap.hpp:217
Reset.
Definition: coap.h:71
This class caches CoAP responses to implement message deduplication.
Definition: coap.hpp:329
This type points to an OpenThread message buffer.
Definition: types.h:479
This class implements CoAP header generation and parsing.
Definition: coap_header.hpp:72
otError SendAck(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo)
This method sends a CoAP ACK empty message which is used in Separate Response for confirmable request...
Definition: coap.hpp:575
EnqueuedResponseHeader(const Ip6::MessageInfo &aMessageInfo)
Constructor creating object with valid dequeue time and message info.
Definition: coap.hpp:257
#define OT_TOOL_PACKED_BEGIN
Compiler-specific indication that a class or struct must be byte packed.
Definition: toolchain.h:170
This class implements a timer.
Definition: timer.hpp:69
This class implements the millisecond timer.
Definition: timer.hpp:145
static void RemoveFrom(Message &aMessage)
This method removes metadata from the message.
Definition: coap.hpp:289
otCoapType
CoAP Type values.
Definition: coap.h:66
This structure represents a CoAP resource.
Definition: coap.h:224
uint16_t GetPort(void)
This method returns a port number used by CoAP service.
Definition: coap.hpp:477
Low priority level.
Definition: message.hpp:227
This file includes definitions for UDP/IPv6 sockets.
Not Found.
Definition: coap.h:103
void SetInterceptor(Interceptor aInterceptor, void *aContext)
This method sets interceptor to be called before processing a CoAP packet.
Definition: coap.hpp:629
const MessageQueue & GetResponses(void) const
Get a reference to the cached CoAP responses queue.
Definition: coap.hpp:406
This class implements definitions for maintaining a pointer to arbitrary context information.
Definition: context.hpp:61
This class represents a message.
Definition: message.hpp:195
This class implements the common base for CoAP client and server.
Definition: coap.hpp:433
int Write(uint16_t aOffset, uint16_t aLength, const void *aBuf)
This method writes bytes to the message.
Definition: message.cpp:553
bool IsEarlier(uint32_t aTime) const
This method checks if the message shall be sent before the given time.
Definition: coap.hpp:302
This class implements the CoAP client and server.
Definition: coap.hpp:741
int UpdateIn(Message &aMessage) const
This method updates request data in the message.
Definition: coap.hpp:159
otError Append(const void *aBuf, uint16_t aLength)
This method appends bytes to the end of the message.
Definition: message.cpp:405
otError AppendTo(Message &aMessage) const
This method appends request data to the message.
Definition: coap.hpp:135
This file includes definitions for the message buffer pool and message buffers.
CoapMetadata(void)
Default constructor for the object.
Definition: coap.hpp:104
This class implements locator for otInstance object.
Definition: locator.hpp:63
#define OPENTHREAD_CONFIG_COAP_SERVER_MAX_CACHED_RESPONSES
Maximum number of cached responses for CoAP Confirmable messages.
Definition: openthread-core-default-config.h:425
void(* otCoapResponseHandler)(void *aContext, otCoapHeader *aHeader, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aResult)
This function pointer is called when a CoAP response is received or on the request timeout...
Definition: coap.h:205
This file includes definitions for the multiplexed timer service.
#define OT_TOOL_PACKED_END
Compiler-specific indication at the end of a byte packed class or struct.
Definition: toolchain.h:172
bool IsLater(uint32_t aTime) const
This method checks if the message shall be sent after the given time.
Definition: coap.hpp:181
This file includes functions for debugging.
This file includes definitions for IPv6 packet processing.
#define OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT
Minimum spacing before first retransmission when ACK is not received (RFC7252 default value is 2)...
Definition: openthread-core-default-config.h:381
This structure represents the local and peer IPv6 socket addresses.
Definition: types.h:436
uint16_t ReadFrom(const Message &aMessage)
This method reads request data from the message.
Definition: coap.hpp:279
EnqueuedResponseHeader(void)
Default constructor creating empty object.
Definition: coap.hpp:249
void Free(void)
This method frees this message buffer.
Definition: message.cpp:260
This class implements a UDP/IPv6 socket.
Definition: udp6.hpp:63
bool IsEarlier(uint32_t aTime) const
This method checks if the message shall be sent before the given time.
Definition: coap.hpp:171
#define OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR
Denominator of ACK_RANDOM_FACTOR used to calculate maximum spacing before first retransmission when A...
Definition: openthread-core-default-config.h:403
This file includes definitions for IPv6 network interfaces.
This file defines the top-level functions for the OpenThread CoAP implementation. ...
void(* otCoapRequestHandler)(void *aContext, otCoapHeader *aHeader, otMessage *aMessage, const otMessageInfo *aMessageInfo)
This function pointer is called when a CoAP request with a given Uri-Path is received.
Definition: coap.h:217
const MessageQueue & GetCachedResponses(void) const
This method returns a reference to the cached response list.
Definition: coap.hpp:648
Confirmable.
Definition: coap.h:68
otError
This enumeration represents error codes used throughout OpenThread.
Definition: types.h:107
otError SetLength(uint16_t aLength)
This method sets the number of bytes in the message.
Definition: message.cpp:289
This file includes compile-time configuration constants for OpenThread.
No error.
Definition: types.h:112
This class implements metadata required for CoAP retransmission.
Definition: coap.hpp:94