1 /*
2  *  Copyright (c) 2020, 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 /**
30  * @file
31  *   This file includes definitions for TMF functionality.
32  */
33 
34 #ifndef OT_CORE_THREAD_TMF_HPP_
35 #define OT_CORE_THREAD_TMF_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "coap/coap.hpp"
40 #include "coap/coap_secure.hpp"
41 #include "common/locator.hpp"
42 
43 namespace ot {
44 namespace Tmf {
45 
46 /**
47  * Declares a TMF handler (a full template specialization of `HandleTmf<Uri>` method) in a given `Type`.
48  *
49  * The class `Type` MUST declare a template method of the following format:
50  *
51  *  template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
52  *
53  * @param[in] Type      The `Type` in which the TMF handler is declared.
54  * @param[in] kUri      The `Uri` which is handled.
55  *
56  */
57 #define DeclareTmfHandler(Type, kUri) \
58     template <> void Type::HandleTmf<kUri>(Coap::Message & aMessage, const Ip6::MessageInfo &aMessageInfo)
59 
60 constexpr uint16_t kUdpPort = 61631; ///< TMF UDP Port
61 
62 typedef Coap::Message Message; ///< A TMF message.
63 
64 /**
65  * Represents message information for a TMF message.
66  *
67  * This is sub-class of `Ip6::MessageInfo` intended for use when sending TMF messages.
68  *
69  */
70 class MessageInfo : public InstanceLocator, public Ip6::MessageInfo
71 {
72 public:
73     /**
74      * Initializes the `MessageInfo`.
75      *
76      * The peer port is set to `Tmf::kUdpPort` and all other properties are cleared (set to zero).
77      *
78      * @param[in] aInstance    The OpenThread instance.
79      *
80      */
MessageInfo(Instance & aInstance)81     explicit MessageInfo(Instance &aInstance)
82         : InstanceLocator(aInstance)
83     {
84         SetPeerPort(kUdpPort);
85     }
86 
87     /**
88      * Sets the local socket port to TMF port.
89      *
90      */
SetSockPortToTmf(void)91     void SetSockPortToTmf(void) { SetSockPort(kUdpPort); }
92 
93     /**
94      * Sets the local socket address to mesh-local RLOC address.
95      *
96      */
97     void SetSockAddrToRloc(void);
98 
99     /**
100      * Sets the local socket address to RLOC address and the peer socket address to leader ALOC.
101      *
102      */
103     void SetSockAddrToRlocPeerAddrToLeaderAloc(void);
104 
105     /**
106      * Sets the local socket address to RLOC address and the peer socket address to leader RLOC.
107 q     *
108      */
109     void SetSockAddrToRlocPeerAddrToLeaderRloc(void);
110 
111     /**
112      * Sets the local socket address to RLOC address and the peer socket address to realm-local all
113      * routers multicast address.
114      *
115      */
116     void SetSockAddrToRlocPeerAddrToRealmLocalAllRoutersMulticast(void);
117 
118     /**
119      * Sets the local socket address to RLOC address and the peer socket address to a router RLOC based on
120      * a given RLOC16.
121      *
122      * @param[in] aRloc16     The RLOC16 to use for peer address.
123      *
124      */
125     void SetSockAddrToRlocPeerAddrTo(uint16_t aRloc16);
126 
127     /**
128      * Sets the local socket address to RLOC address and the peer socket address to a given address.
129      *
130      * @param[in] aPeerAddress  The peer address.
131      *
132      */
133     void SetSockAddrToRlocPeerAddrTo(const Ip6::Address &aPeerAddress);
134 };
135 
136 /**
137  * Implements functionality of the Thread TMF agent.
138  *
139  */
140 class Agent : public Coap::Coap
141 {
142 public:
143     /**
144      * Initializes the object.
145      *
146      * @param[in] aInstance      A reference to the OpenThread instance.
147      *
148      */
149     explicit Agent(Instance &aInstance);
150 
151     /**
152      * Starts the TMF agent.
153      *
154      * @retval kErrorNone    Successfully started the CoAP service.
155      * @retval kErrorFailed  Failed to start the TMF agent.
156      *
157      */
158     Error Start(void);
159 
160     /**
161      * Indicates whether or not a message meets TMF addressing rules.
162      *
163      * A TMF message MUST comply with following rules:
164      *
165      * - The destination port is `Tmf::kUdpPort`.
166      * - Both source and destination addresses are Link-Local, or
167      * - Source is Mesh Local and then destination is Mesh Local or Link-Local Multicast or Realm-Local Multicast.
168      *
169      * @param[in] aSourceAddress   Source IPv6 address.
170      * @param[in] aDestAddress     Destination IPv6 address.
171      * @param[in] aDestPort        Destination port number.
172      *
173      * @retval TRUE   if TMF addressing rules are met.
174      * @retval FALSE  if TMF addressing rules are not met.
175      *
176      */
177     bool IsTmfMessage(const Ip6::Address &aSourceAddress, const Ip6::Address &aDestAddress, uint16_t aDestPort) const;
178 
179     /**
180      * Converts a TMF message priority to IPv6 header DSCP value.
181      *
182      * @param[in] aPriority  The message priority to convert.
183      *
184      * @returns The DSCP value corresponding to @p aPriority.
185      *
186      */
187     static uint8_t PriorityToDscp(Message::Priority aPriority);
188 
189     /**
190      * Converts a IPv6 header DSCP value to message priority for TMF message.
191      *
192      * @param[in] aDscp      The IPv6 header DSCP value in a TMF message.
193      *
194      * @returns The message priority corresponding to the @p aDscp.
195      *
196      */
197     static Message::Priority DscpToPriority(uint8_t aDscp);
198 
199 private:
200     template <Uri kUri> void HandleTmf(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
201 
202     static bool HandleResource(CoapBase               &aCoapBase,
203                                const char             *aUriPath,
204                                Message                &aMessage,
205                                const Ip6::MessageInfo &aMessageInfo);
206     bool        HandleResource(const char *aUriPath, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
207 
208     static Error Filter(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext);
209 };
210 
211 #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
212 
213 /**
214  * Implements functionality of the secure TMF agent.
215  *
216  */
217 class SecureAgent : public Coap::CoapSecure
218 {
219 public:
220     /**
221      * Initializes the object.
222      *
223      * @param[in] aInstance      A reference to the OpenThread instance.
224      *
225      */
226     explicit SecureAgent(Instance &aInstance);
227 
228 private:
229     static bool HandleResource(CoapBase               &aCoapBase,
230                                const char             *aUriPath,
231                                Message                &aMessage,
232                                const Ip6::MessageInfo &aMessageInfo);
233     bool        HandleResource(const char *aUriPath, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
234 };
235 
236 #endif
237 
238 } // namespace Tmf
239 } // namespace ot
240 
241 #endif //  OT_CORE_THREAD_TMF_HPP_
242