1 /*
2  *    Copyright (c) 2019, 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" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file implements Thread Radio Encapsulation Link (TREL) interface.
31  */
32 
33 #include "trel_interface.hpp"
34 
35 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
36 
37 #include <openthread/platform/trel-udp6.h>
38 
39 #include "common/code_utils.hpp"
40 #include "common/instance.hpp"
41 #include "common/locator_getters.hpp"
42 #include "common/logging.hpp"
43 
44 namespace ot {
45 namespace Trel {
46 
Interface(Instance & aInstance)47 Interface::Interface(Instance &aInstance)
48     : InstanceLocator(aInstance)
49     , mInitialized(false)
50 {
51 }
52 
Init(void)53 void Interface::Init(void)
54 {
55     Ip6::Address ip6Address;
56 
57     OT_ASSERT(!mInitialized);
58 
59     ip6Address.SetToLinkLocalAddress(Get<Mac::Mac>().GetExtAddress());
60     otPlatTrelUdp6Init(&GetInstance(), &ip6Address, kUdpPort);
61 
62     CreateMulticastIp6Address(ip6Address);
63     otPlatTrelUdp6SubscribeMulticastAddress(&GetInstance(), &ip6Address);
64 
65     mInitialized = true;
66 }
67 
HandleExtAddressChange(void)68 void Interface::HandleExtAddressChange(void)
69 {
70     Ip6::Address ip6Address;
71 
72     VerifyOrExit(mInitialized);
73 
74     ip6Address.SetToLinkLocalAddress(Get<Mac::Mac>().GetExtAddress());
75     otPlatTrelUdp6UpdateAddress(&GetInstance(), &ip6Address);
76 
77 exit:
78     return;
79 }
80 
Send(const Packet & aPacket)81 Error Interface::Send(const Packet &aPacket)
82 {
83     Ip6::Address destIp6Address;
84 
85     switch (aPacket.GetHeader().GetType())
86     {
87     case Header::kTypeBroadcast:
88         CreateMulticastIp6Address(destIp6Address);
89         break;
90 
91     case Header::kTypeUnicast:
92     case Header::kTypeAck:
93         destIp6Address.SetToLinkLocalAddress(aPacket.GetHeader().GetDestination());
94         break;
95     }
96 
97     return otPlatTrelUdp6SendTo(&GetInstance(), aPacket.GetBuffer(), aPacket.GetLength(), &destIp6Address);
98 }
99 
HandleReceived(uint8_t * aBuffer,uint16_t aLength)100 void Interface::HandleReceived(uint8_t *aBuffer, uint16_t aLength)
101 {
102     mRxPacket.Init(aBuffer, aLength);
103     Get<Link>().ProcessReceivedPacket(mRxPacket);
104 }
105 
CreateMulticastIp6Address(Ip6::Address & aIp6Address)106 void Interface::CreateMulticastIp6Address(Ip6::Address &aIp6Address)
107 {
108     // Use ff02::1 (Link-local All Nodes multicast address).
109     aIp6Address.SetToLinkLocalAllNodesMulticast();
110 }
111 
112 } // namespace Trel
113 } // namespace ot
114 
otPlatTrelUdp6HandleReceived(otInstance * aInstance,uint8_t * aBuffer,uint16_t aLength)115 extern "C" void otPlatTrelUdp6HandleReceived(otInstance *aInstance, uint8_t *aBuffer, uint16_t aLength)
116 {
117     ot::Instance &instance = *static_cast<ot::Instance *>(aInstance);
118 
119     VerifyOrExit(instance.IsInitialized());
120     instance.Get<ot::Trel::Interface>().HandleReceived(aBuffer, aLength);
121 
122 exit:
123     return;
124 }
125 
otPlatTrelUdp6SetTestMode(otInstance * aInstance,bool aEnable)126 extern "C" OT_TOOL_WEAK otError otPlatTrelUdp6SetTestMode(otInstance *aInstance, bool aEnable)
127 {
128     OT_UNUSED_VARIABLE(aInstance);
129     OT_UNUSED_VARIABLE(aEnable);
130 
131     return ot::kErrorNotImplemented;
132 }
133 
134 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
135