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