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 /**
30 * @file
31 * This file implements the OpenThread IPv6 API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #include "instance/instance.hpp"
37
38 using namespace ot;
39
otIp6SetEnabled(otInstance * aInstance,bool aEnabled)40 otError otIp6SetEnabled(otInstance *aInstance, bool aEnabled)
41 {
42 Error error = kErrorNone;
43 Instance &instance = AsCoreType(aInstance);
44
45 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
46 VerifyOrExit(!instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
47 #endif
48
49 if (aEnabled)
50 {
51 instance.Get<ThreadNetif>().Up();
52 }
53 else
54 {
55 instance.Get<ThreadNetif>().Down();
56 }
57
58 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
59 exit:
60 #endif
61 return error;
62 }
63
otIp6IsEnabled(otInstance * aInstance)64 bool otIp6IsEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<ThreadNetif>().IsUp(); }
65
otIp6GetUnicastAddresses(otInstance * aInstance)66 const otNetifAddress *otIp6GetUnicastAddresses(otInstance *aInstance)
67 {
68 return AsCoreType(aInstance).Get<ThreadNetif>().GetUnicastAddresses().GetHead();
69 }
70
otIp6HasUnicastAddress(otInstance * aInstance,const otIp6Address * aAddress)71 bool otIp6HasUnicastAddress(otInstance *aInstance, const otIp6Address *aAddress)
72 {
73 return AsCoreType(aInstance).Get<ThreadNetif>().HasUnicastAddress(AsCoreType(aAddress));
74 }
75
otIp6AddUnicastAddress(otInstance * aInstance,const otNetifAddress * aAddress)76 otError otIp6AddUnicastAddress(otInstance *aInstance, const otNetifAddress *aAddress)
77 {
78 return AsCoreType(aInstance).Get<ThreadNetif>().AddExternalUnicastAddress(AsCoreType(aAddress));
79 }
80
otIp6RemoveUnicastAddress(otInstance * aInstance,const otIp6Address * aAddress)81 otError otIp6RemoveUnicastAddress(otInstance *aInstance, const otIp6Address *aAddress)
82 {
83 return AsCoreType(aInstance).Get<ThreadNetif>().RemoveExternalUnicastAddress(AsCoreType(aAddress));
84 }
85
otIp6GetMulticastAddresses(otInstance * aInstance)86 const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance)
87 {
88 return AsCoreType(aInstance).Get<ThreadNetif>().GetMulticastAddresses().GetHead();
89 }
90
otIp6SubscribeMulticastAddress(otInstance * aInstance,const otIp6Address * aAddress)91 otError otIp6SubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
92 {
93 return AsCoreType(aInstance).Get<ThreadNetif>().SubscribeExternalMulticast(AsCoreType(aAddress));
94 }
95
otIp6UnsubscribeMulticastAddress(otInstance * aInstance,const otIp6Address * aAddress)96 otError otIp6UnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
97 {
98 return AsCoreType(aInstance).Get<ThreadNetif>().UnsubscribeExternalMulticast(AsCoreType(aAddress));
99 }
100
otIp6SetReceiveCallback(otInstance * aInstance,otIp6ReceiveCallback aCallback,void * aCallbackContext)101 void otIp6SetReceiveCallback(otInstance *aInstance, otIp6ReceiveCallback aCallback, void *aCallbackContext)
102 {
103 AsCoreType(aInstance).Get<Ip6::Ip6>().SetReceiveCallback(aCallback, aCallbackContext);
104 }
105
otIp6SetAddressCallback(otInstance * aInstance,otIp6AddressCallback aCallback,void * aCallbackContext)106 void otIp6SetAddressCallback(otInstance *aInstance, otIp6AddressCallback aCallback, void *aCallbackContext)
107 {
108 AsCoreType(aInstance).Get<ThreadNetif>().SetAddressCallback(aCallback, aCallbackContext);
109 }
110
otIp6IsReceiveFilterEnabled(otInstance * aInstance)111 bool otIp6IsReceiveFilterEnabled(otInstance *aInstance)
112 {
113 return AsCoreType(aInstance).Get<Ip6::Ip6>().IsReceiveIp6FilterEnabled();
114 }
115
otIp6SetReceiveFilterEnabled(otInstance * aInstance,bool aEnabled)116 void otIp6SetReceiveFilterEnabled(otInstance *aInstance, bool aEnabled)
117 {
118 AsCoreType(aInstance).Get<Ip6::Ip6>().SetReceiveIp6FilterEnabled(aEnabled);
119 }
120
otIp6Send(otInstance * aInstance,otMessage * aMessage)121 otError otIp6Send(otInstance *aInstance, otMessage *aMessage)
122 {
123 otError error;
124
125 VerifyOrExit(!AsCoreType(aMessage).IsOriginThreadNetif(), error = kErrorInvalidArgs);
126
127 error = AsCoreType(aInstance).Get<Ip6::Ip6>().SendRaw(OwnedPtr<Message>(AsCoreTypePtr(aMessage)));
128
129 exit:
130 return error;
131 }
132
otIp6NewMessage(otInstance * aInstance,const otMessageSettings * aSettings)133 otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
134 {
135 return AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessage(0, Message::Settings::From(aSettings));
136 }
137
otIp6NewMessageFromBuffer(otInstance * aInstance,const uint8_t * aData,uint16_t aDataLength,const otMessageSettings * aSettings)138 otMessage *otIp6NewMessageFromBuffer(otInstance *aInstance,
139 const uint8_t *aData,
140 uint16_t aDataLength,
141 const otMessageSettings *aSettings)
142 {
143 return AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessageFromData(aData, aDataLength,
144 Message::Settings::From(aSettings));
145 }
146
otIp6AddUnsecurePort(otInstance * aInstance,uint16_t aPort)147 otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort)
148 {
149 return AsCoreType(aInstance).Get<Ip6::Filter>().AddUnsecurePort(aPort);
150 }
151
otIp6RemoveUnsecurePort(otInstance * aInstance,uint16_t aPort)152 otError otIp6RemoveUnsecurePort(otInstance *aInstance, uint16_t aPort)
153 {
154 return AsCoreType(aInstance).Get<Ip6::Filter>().RemoveUnsecurePort(aPort);
155 }
156
otIp6RemoveAllUnsecurePorts(otInstance * aInstance)157 void otIp6RemoveAllUnsecurePorts(otInstance *aInstance)
158 {
159 AsCoreType(aInstance).Get<Ip6::Filter>().RemoveAllUnsecurePorts();
160 }
161
otIp6GetUnsecurePorts(otInstance * aInstance,uint8_t * aNumEntries)162 const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries)
163 {
164 AssertPointerIsNotNull(aNumEntries);
165
166 return AsCoreType(aInstance).Get<Ip6::Filter>().GetUnsecurePorts(*aNumEntries);
167 }
168
otIp6IsAddressEqual(const otIp6Address * aFirst,const otIp6Address * aSecond)169 bool otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Address *aSecond)
170 {
171 return AsCoreType(aFirst) == AsCoreType(aSecond);
172 }
173
otIp6ArePrefixesEqual(const otIp6Prefix * aFirst,const otIp6Prefix * aSecond)174 bool otIp6ArePrefixesEqual(const otIp6Prefix *aFirst, const otIp6Prefix *aSecond)
175 {
176 return AsCoreType(aFirst) == AsCoreType(aSecond);
177 }
178
otIp6AddressFromString(const char * aString,otIp6Address * aAddress)179 otError otIp6AddressFromString(const char *aString, otIp6Address *aAddress)
180 {
181 return AsCoreType(aAddress).FromString(aString);
182 }
183
otIp6PrefixFromString(const char * aString,otIp6Prefix * aPrefix)184 otError otIp6PrefixFromString(const char *aString, otIp6Prefix *aPrefix)
185 {
186 return AsCoreType(aPrefix).FromString(aString);
187 }
188
otIp6AddressToString(const otIp6Address * aAddress,char * aBuffer,uint16_t aSize)189 void otIp6AddressToString(const otIp6Address *aAddress, char *aBuffer, uint16_t aSize)
190 {
191 AssertPointerIsNotNull(aBuffer);
192
193 AsCoreType(aAddress).ToString(aBuffer, aSize);
194 }
195
otIp6SockAddrToString(const otSockAddr * aSockAddr,char * aBuffer,uint16_t aSize)196 void otIp6SockAddrToString(const otSockAddr *aSockAddr, char *aBuffer, uint16_t aSize)
197 {
198 AssertPointerIsNotNull(aBuffer);
199
200 AsCoreType(aSockAddr).ToString(aBuffer, aSize);
201 }
202
otIp6PrefixToString(const otIp6Prefix * aPrefix,char * aBuffer,uint16_t aSize)203 void otIp6PrefixToString(const otIp6Prefix *aPrefix, char *aBuffer, uint16_t aSize)
204 {
205 AssertPointerIsNotNull(aBuffer);
206
207 AsCoreType(aPrefix).ToString(aBuffer, aSize);
208 }
209
otIp6PrefixMatch(const otIp6Address * aFirst,const otIp6Address * aSecond)210 uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
211 {
212 return AsCoreType(aFirst).PrefixMatch(AsCoreType(aSecond));
213 }
214
otIp6GetPrefix(const otIp6Address * aAddress,uint8_t aLength,otIp6Prefix * aPrefix)215 void otIp6GetPrefix(const otIp6Address *aAddress, uint8_t aLength, otIp6Prefix *aPrefix)
216 {
217 AsCoreType(aAddress).GetPrefix(aLength, AsCoreType(aPrefix));
218 }
219
otIp6IsAddressUnspecified(const otIp6Address * aAddress)220 bool otIp6IsAddressUnspecified(const otIp6Address *aAddress) { return AsCoreType(aAddress).IsUnspecified(); }
221
otIp6SelectSourceAddress(otInstance * aInstance,otMessageInfo * aMessageInfo)222 otError otIp6SelectSourceAddress(otInstance *aInstance, otMessageInfo *aMessageInfo)
223 {
224 return AsCoreType(aInstance).Get<Ip6::Ip6>().SelectSourceAddress(AsCoreType(aMessageInfo));
225 }
226
227 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
otIp6RegisterMulticastListeners(otInstance * aInstance,const otIp6Address * aAddresses,uint8_t aAddressNum,const uint32_t * aTimeout,otIp6RegisterMulticastListenersCallback aCallback,void * aContext)228 otError otIp6RegisterMulticastListeners(otInstance *aInstance,
229 const otIp6Address *aAddresses,
230 uint8_t aAddressNum,
231 const uint32_t *aTimeout,
232 otIp6RegisterMulticastListenersCallback aCallback,
233 void *aContext)
234 {
235 return AsCoreType(aInstance).Get<MlrManager>().RegisterMulticastListeners(AsCoreTypePtr(aAddresses), aAddressNum,
236 aTimeout, aCallback, aContext);
237 }
238 #endif
239
240 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
241
otIp6IsSlaacEnabled(otInstance * aInstance)242 bool otIp6IsSlaacEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<Utils::Slaac>().IsEnabled(); }
243
otIp6SetSlaacEnabled(otInstance * aInstance,bool aEnabled)244 void otIp6SetSlaacEnabled(otInstance *aInstance, bool aEnabled)
245 {
246 Instance &instance = AsCoreType(aInstance);
247
248 if (aEnabled)
249 {
250 instance.Get<Utils::Slaac>().Enable();
251 }
252 else
253 {
254 instance.Get<Utils::Slaac>().Disable();
255 }
256 }
257
otIp6SetSlaacPrefixFilter(otInstance * aInstance,otIp6SlaacPrefixFilter aFilter)258 void otIp6SetSlaacPrefixFilter(otInstance *aInstance, otIp6SlaacPrefixFilter aFilter)
259 {
260 AsCoreType(aInstance).Get<Utils::Slaac>().SetFilter(aFilter);
261 }
262
263 #endif // OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
264
265 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
266
otIp6SetMeshLocalIid(otInstance * aInstance,const otIp6InterfaceIdentifier * aIid)267 otError otIp6SetMeshLocalIid(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
268 {
269 return AsCoreType(aInstance).Get<Mle::MleRouter>().SetMeshLocalIid(AsCoreType(aIid));
270 }
271
272 #endif
273
otIp6ProtoToString(uint8_t aIpProto)274 const char *otIp6ProtoToString(uint8_t aIpProto) { return Ip6::Ip6::IpProtoToString(aIpProto); }
275
276 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
otIp6GetBorderRoutingCounters(otInstance * aInstance)277 const otBorderRoutingCounters *otIp6GetBorderRoutingCounters(otInstance *aInstance)
278 {
279 return &AsCoreType(aInstance).Get<Ip6::Ip6>().GetBorderRoutingCounters();
280 }
281
otIp6ResetBorderRoutingCounters(otInstance * aInstance)282 void otIp6ResetBorderRoutingCounters(otInstance *aInstance)
283 {
284 AsCoreType(aInstance).Get<Ip6::Ip6>().ResetBorderRoutingCounters();
285 }
286 #endif
287