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      * @retval kErrorNone      Successfully set the addresses.
103      * @retval kErrorDetached  Cannot set leader ALOC since device is currently detached.
104      *
105      */
106     Error SetSockAddrToRlocPeerAddrToLeaderAloc(void);
107 
108     /**
109      * Sets the local socket address to RLOC address and the peer socket address to leader RLOC.
110      *
111      * @retval kErrorNone      Successfully set the addresses.
112      * @retval kErrorDetached  Cannot set leader RLOC since device is currently detached.
113      *
114      */
115     Error SetSockAddrToRlocPeerAddrToLeaderRloc(void);
116 
117     /**
118      * Sets the local socket address to RLOC address and the peer socket address to realm-local all
119      * routers multicast address.
120      *
121      */
122     void SetSockAddrToRlocPeerAddrToRealmLocalAllRoutersMulticast(void);
123 
124     /**
125      * Sets the local socket address to RLOC address and the peer socket address to a router RLOC based on
126      * a given RLOC16.
127      *
128      * @param[in] aRloc16     The RLOC16 to use for peer address.
129      *
130      */
131     void SetSockAddrToRlocPeerAddrTo(uint16_t aRloc16);
132 
133     /**
134      * Sets the local socket address to RLOC address and the peer socket address to a given address.
135      *
136      * @param[in] aPeerAddress  The peer address.
137      *
138      */
139     void SetSockAddrToRlocPeerAddrTo(const Ip6::Address &aPeerAddress);
140 };
141 
142 /**
143  * Implements functionality of the Thread TMF agent.
144  *
145  */
146 class Agent : public Coap::Coap
147 {
148 public:
149     /**
150      * Initializes the object.
151      *
152      * @param[in] aInstance      A reference to the OpenThread instance.
153      *
154      */
155     explicit Agent(Instance &aInstance);
156 
157     /**
158      * Starts the TMF agent.
159      *
160      * @retval kErrorNone    Successfully started the CoAP service.
161      * @retval kErrorFailed  Failed to start the TMF agent.
162      *
163      */
164     Error Start(void);
165 
166     /**
167      * Indicates whether or not a message meets TMF addressing rules.
168      *
169      * A TMF message MUST comply with following rules:
170      *
171      * - The destination port is `Tmf::kUdpPort`.
172      * - Both source and destination addresses are Link-Local, or
173      * - Source is Mesh Local and then destination is Mesh Local or Link-Local Multicast or Realm-Local Multicast.
174      *
175      * @param[in] aSourceAddress   Source IPv6 address.
176      * @param[in] aDestAddress     Destination IPv6 address.
177      * @param[in] aDestPort        Destination port number.
178      *
179      * @retval TRUE   if TMF addressing rules are met.
180      * @retval FALSE  if TMF addressing rules are not met.
181      *
182      */
183     bool IsTmfMessage(const Ip6::Address &aSourceAddress, const Ip6::Address &aDestAddress, uint16_t aDestPort) const;
184 
185     /**
186      * Converts a TMF message priority to IPv6 header DSCP value.
187      *
188      * @param[in] aPriority  The message priority to convert.
189      *
190      * @returns The DSCP value corresponding to @p aPriority.
191      *
192      */
193     static uint8_t PriorityToDscp(Message::Priority aPriority);
194 
195     /**
196      * Converts a IPv6 header DSCP value to message priority for TMF message.
197      *
198      * @param[in] aDscp      The IPv6 header DSCP value in a TMF message.
199      *
200      * @returns The message priority corresponding to the @p aDscp.
201      *
202      */
203     static Message::Priority DscpToPriority(uint8_t aDscp);
204 
205 private:
206     template <Uri kUri> void HandleTmf(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
207 
208     static bool HandleResource(CoapBase               &aCoapBase,
209                                const char             *aUriPath,
210                                Message                &aMessage,
211                                const Ip6::MessageInfo &aMessageInfo);
212     bool        HandleResource(const char *aUriPath, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
213 
214     static Error Filter(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext);
215 };
216 
217 #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
218 
219 /**
220  * Implements functionality of the secure TMF agent.
221  *
222  */
223 class SecureAgent : public Coap::CoapSecure
224 {
225 public:
226     /**
227      * Initializes the object.
228      *
229      * @param[in] aInstance      A reference to the OpenThread instance.
230      *
231      */
232     explicit SecureAgent(Instance &aInstance);
233 
234 private:
235     static bool HandleResource(CoapBase               &aCoapBase,
236                                const char             *aUriPath,
237                                Message                &aMessage,
238                                const Ip6::MessageInfo &aMessageInfo);
239     bool        HandleResource(const char *aUriPath, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
240 };
241 
242 #endif
243 
244 } // namespace Tmf
245 } // namespace ot
246 
247 #endif //  OT_CORE_THREAD_TMF_HPP_
248