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"
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 defines the OpenThread Backbone Router API (for Thread 1.2 FTD with
32  *  `OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE`).
33  */
34 
35 #include "openthread-core-config.h"
36 
37 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
38 
39 #include <openthread/backbone_router_ftd.h>
40 
41 #include "common/instance.hpp"
42 
43 using namespace ot;
44 
otBackboneRouterSetEnabled(otInstance * aInstance,bool aEnabled)45 void otBackboneRouterSetEnabled(otInstance *aInstance, bool aEnabled)
46 {
47     Instance &instance = *static_cast<Instance *>(aInstance);
48 
49     return instance.Get<BackboneRouter::Local>().SetEnabled(aEnabled);
50 }
51 
otBackboneRouterGetState(otInstance * aInstance)52 otBackboneRouterState otBackboneRouterGetState(otInstance *aInstance)
53 {
54     Instance &instance = *static_cast<Instance *>(aInstance);
55 
56     return instance.Get<BackboneRouter::Local>().GetState();
57 }
58 
otBackboneRouterGetConfig(otInstance * aInstance,otBackboneRouterConfig * aConfig)59 void otBackboneRouterGetConfig(otInstance *aInstance, otBackboneRouterConfig *aConfig)
60 {
61     Instance &instance = *static_cast<Instance *>(aInstance);
62 
63     OT_ASSERT(aConfig != nullptr);
64 
65     instance.Get<BackboneRouter::Local>().GetConfig(*aConfig);
66 }
67 
otBackboneRouterSetConfig(otInstance * aInstance,const otBackboneRouterConfig * aConfig)68 otError otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConfig *aConfig)
69 {
70     Instance &instance = *static_cast<Instance *>(aInstance);
71 
72     OT_ASSERT(aConfig != nullptr);
73 
74     return instance.Get<BackboneRouter::Local>().SetConfig(*aConfig);
75 }
76 
otBackboneRouterRegister(otInstance * aInstance)77 otError otBackboneRouterRegister(otInstance *aInstance)
78 {
79     Instance &instance = *static_cast<Instance *>(aInstance);
80 
81     return instance.Get<BackboneRouter::Local>().AddService(true /* Force registration */);
82 }
83 
otBackboneRouterGetRegistrationJitter(otInstance * aInstance)84 uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance)
85 {
86     Instance &instance = *static_cast<Instance *>(aInstance);
87 
88     return instance.Get<BackboneRouter::Local>().GetRegistrationJitter();
89 }
90 
otBackboneRouterSetRegistrationJitter(otInstance * aInstance,uint8_t aJitter)91 void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter)
92 {
93     Instance &instance = *static_cast<Instance *>(aInstance);
94 
95     return instance.Get<BackboneRouter::Local>().SetRegistrationJitter(aJitter);
96 }
97 
otBackboneRouterGetDomainPrefix(otInstance * aInstance,otBorderRouterConfig * aConfig)98 otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig)
99 {
100     Instance &instance = *static_cast<Instance *>(aInstance);
101 
102     OT_ASSERT(aConfig != nullptr);
103 
104     return instance.Get<BackboneRouter::Local>().GetDomainPrefix(
105         *static_cast<NetworkData::OnMeshPrefixConfig *>(aConfig));
106 }
107 
otBackboneRouterSetDomainPrefixCallback(otInstance * aInstance,otBackboneRouterDomainPrefixCallback aCallback,void * aContext)108 void otBackboneRouterSetDomainPrefixCallback(otInstance *                         aInstance,
109                                              otBackboneRouterDomainPrefixCallback aCallback,
110                                              void *                               aContext)
111 {
112     Instance &instance = *static_cast<Instance *>(aInstance);
113 
114     return instance.Get<BackboneRouter::Local>().SetDomainPrefixCallback(aCallback, aContext);
115 }
116 
117 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
otBackboneRouterSetNdProxyCallback(otInstance * aInstance,otBackboneRouterNdProxyCallback aCallback,void * aContext)118 void otBackboneRouterSetNdProxyCallback(otInstance *                    aInstance,
119                                         otBackboneRouterNdProxyCallback aCallback,
120                                         void *                          aContext)
121 {
122     Instance &instance = *static_cast<Instance *>(aInstance);
123 
124     instance.Get<BackboneRouter::NdProxyTable>().SetCallback(aCallback, aContext);
125 }
126 
otBackboneRouterGetNdProxyInfo(otInstance * aInstance,const otIp6Address * aDua,otBackboneRouterNdProxyInfo * aNdProxyInfo)127 otError otBackboneRouterGetNdProxyInfo(otInstance *                 aInstance,
128                                        const otIp6Address *         aDua,
129                                        otBackboneRouterNdProxyInfo *aNdProxyInfo)
130 {
131     Instance &instance = *static_cast<Instance *>(aInstance);
132 
133     return instance.Get<BackboneRouter::NdProxyTable>().GetInfo(reinterpret_cast<const Ip6::Address &>(*aDua),
134                                                                 *aNdProxyInfo);
135 }
136 #endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
137 
138 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
otBackboneRouterSetMulticastListenerCallback(otInstance * aInstance,otBackboneRouterMulticastListenerCallback aCallback,void * aContext)139 void otBackboneRouterSetMulticastListenerCallback(otInstance *                              aInstance,
140                                                   otBackboneRouterMulticastListenerCallback aCallback,
141                                                   void *                                    aContext)
142 {
143     Instance &instance = *static_cast<Instance *>(aInstance);
144 
145     instance.Get<BackboneRouter::MulticastListenersTable>().SetCallback(aCallback, aContext);
146 }
147 
otBackboneRouterMulticastListenerGetNext(otInstance * aInstance,otChildIp6AddressIterator * aIterator,otBackboneRouterMulticastListenerInfo * aListenerInfo)148 otError otBackboneRouterMulticastListenerGetNext(otInstance *                           aInstance,
149                                                  otChildIp6AddressIterator *            aIterator,
150                                                  otBackboneRouterMulticastListenerInfo *aListenerInfo)
151 {
152     Instance &instance = *static_cast<Instance *>(aInstance);
153 
154     OT_ASSERT(aIterator != nullptr);
155     OT_ASSERT(aListenerInfo != nullptr);
156 
157     return instance.Get<BackboneRouter::MulticastListenersTable>().GetNext(*aIterator, *aListenerInfo);
158 }
159 #endif
160 
161 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
162 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
otBackboneRouterConfigNextDuaRegistrationResponse(otInstance * aInstance,const otIp6InterfaceIdentifier * aMlIid,uint8_t aStatus)163 void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance *                    aInstance,
164                                                        const otIp6InterfaceIdentifier *aMlIid,
165                                                        uint8_t                         aStatus)
166 {
167     Instance &instance = *static_cast<Instance *>(aInstance);
168 
169     instance.Get<BackboneRouter::Manager>().ConfigNextDuaRegistrationResponse(
170         static_cast<const Ip6::InterfaceIdentifier *>(aMlIid), aStatus);
171 }
172 #endif
173 
174 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
otBackboneRouterConfigNextMulticastListenerRegistrationResponse(otInstance * aInstance,uint8_t aStatus)175 void otBackboneRouterConfigNextMulticastListenerRegistrationResponse(otInstance *aInstance, uint8_t aStatus)
176 {
177     Instance &instance = *static_cast<Instance *>(aInstance);
178 
179     OT_ASSERT(aStatus <= ThreadStatusTlv::kMlrStatusMax);
180 
181     instance.Get<BackboneRouter::Manager>().ConfigNextMulticastListenerRegistrationResponse(
182         static_cast<ThreadStatusTlv::MlrStatus>(aStatus));
183 }
184 
otBackboneRouterMulticastListenerClear(otInstance * aInstance)185 void otBackboneRouterMulticastListenerClear(otInstance *aInstance)
186 {
187     Instance &instance = *static_cast<Instance *>(aInstance);
188 
189     instance.Get<BackboneRouter::MulticastListenersTable>().Clear();
190 }
191 
otBackboneRouterMulticastListenerAdd(otInstance * aInstance,const otIp6Address * aAddress,uint32_t aTimeout)192 otError otBackboneRouterMulticastListenerAdd(otInstance *aInstance, const otIp6Address *aAddress, uint32_t aTimeout)
193 {
194     Instance &instance = *static_cast<Instance *>(aInstance);
195 
196     OT_ASSERT(aAddress != nullptr);
197 
198     if (aTimeout == 0)
199     {
200         BackboneRouter::BackboneRouterConfig config;
201         instance.Get<BackboneRouter::Local>().GetConfig(config);
202         aTimeout = config.mMlrTimeout;
203     }
204 
205     aTimeout =
206         aTimeout > static_cast<uint32_t>(Mle::kMlrTimeoutMax) ? static_cast<uint32_t>(Mle::kMlrTimeoutMax) : aTimeout;
207     aTimeout = Time::SecToMsec(aTimeout);
208 
209     return instance.Get<BackboneRouter::MulticastListenersTable>().Add(static_cast<const Ip6::Address &>(*aAddress),
210                                                                        TimerMilli::GetNow() + aTimeout);
211 }
212 #endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
213 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
214 
215 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
216