• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if __ORDER_BIG_ENDIAN__
30 #define BYTE_ORDER_BIG_ENDIAN 1
31 #endif
32 
33 #define OTBR_LOG_TAG "UBUS"
34 
35 #include "openwrt/ubus/otubus.hpp"
36 
37 #include <mutex>
38 
39 #include <arpa/inet.h>
40 #include <sys/eventfd.h>
41 
42 #include <openthread/commissioner.h>
43 #include <openthread/thread.h>
44 #include <openthread/thread_ftd.h>
45 
46 #include "common/logging.hpp"
47 #include "ncp/ncp_openthread.hpp"
48 
49 namespace otbr {
50 namespace ubus {
51 
52 static UbusServer *sUbusServerInstance = nullptr;
53 static int         sUbusEfd            = -1;
54 static void       *sJsonUri            = nullptr;
55 static int         sBufNum;
56 
57 const static int PANID_LENGTH      = 10;
58 const static int XPANID_LENGTH     = 64;
59 const static int NETWORKKEY_LENGTH = 64;
60 
UbusServer(Ncp::ControllerOpenThread * aController,std::mutex * aMutex)61 UbusServer::UbusServer(Ncp::ControllerOpenThread *aController, std::mutex *aMutex)
62     : mIfFinishScan(false)
63     , mContext(nullptr)
64     , mSockPath(nullptr)
65     , mController(aController)
66     , mNcpThreadMutex(aMutex)
67     , mSecond(0)
68 {
69     memset(&mNetworkdataBuf, 0, sizeof(mNetworkdataBuf));
70     memset(&mBuf, 0, sizeof(mBuf));
71 
72     blob_buf_init(&mBuf, 0);
73     blob_buf_init(&mNetworkdataBuf, 0);
74 }
75 
GetInstance(void)76 UbusServer &UbusServer::GetInstance(void)
77 {
78     return *sUbusServerInstance;
79 }
80 
Initialize(Ncp::ControllerOpenThread * aController,std::mutex * aMutex)81 void UbusServer::Initialize(Ncp::ControllerOpenThread *aController, std::mutex *aMutex)
82 {
83     sUbusServerInstance = new UbusServer(aController, aMutex);
84 }
85 
86 enum
87 {
88     SETNETWORK,
89     SET_NETWORK_MAX,
90 };
91 
92 enum
93 {
94     PSKD,
95     EUI64,
96     ADD_JOINER_MAX,
97 };
98 
99 enum
100 {
101     NETWORKKEY,
102     NETWORKNAME,
103     EXTPANID,
104     PANID,
105     CHANNEL,
106     PSKC,
107     MGMTSET_MAX,
108 };
109 
110 static const struct blobmsg_policy setNetworknamePolicy[SET_NETWORK_MAX] = {
111     [SETNETWORK] = {.name = "networkname", .type = BLOBMSG_TYPE_STRING},
112 };
113 
114 static const struct blobmsg_policy setPanIdPolicy[SET_NETWORK_MAX] = {
115     [SETNETWORK] = {.name = "panid", .type = BLOBMSG_TYPE_STRING},
116 };
117 
118 static const struct blobmsg_policy setExtPanIdPolicy[SET_NETWORK_MAX] = {
119     [SETNETWORK] = {.name = "extpanid", .type = BLOBMSG_TYPE_STRING},
120 };
121 
122 static const struct blobmsg_policy setChannelPolicy[SET_NETWORK_MAX] = {
123     [SETNETWORK] = {.name = "channel", .type = BLOBMSG_TYPE_INT32},
124 };
125 
126 static const struct blobmsg_policy setPskcPolicy[SET_NETWORK_MAX] = {
127     [SETNETWORK] = {.name = "pskc", .type = BLOBMSG_TYPE_STRING},
128 };
129 
130 static const struct blobmsg_policy setNetworkkeyPolicy[SET_NETWORK_MAX] = {
131     [SETNETWORK] = {.name = "networkkey", .type = BLOBMSG_TYPE_STRING},
132 };
133 
134 static const struct blobmsg_policy setModePolicy[SET_NETWORK_MAX] = {
135     [SETNETWORK] = {.name = "mode", .type = BLOBMSG_TYPE_STRING},
136 };
137 
138 static const struct blobmsg_policy macfilterAddPolicy[SET_NETWORK_MAX] = {
139     [SETNETWORK] = {.name = "addr", .type = BLOBMSG_TYPE_STRING},
140 };
141 
142 static const struct blobmsg_policy macfilterRemovePolicy[SET_NETWORK_MAX] = {
143     [SETNETWORK] = {.name = "addr", .type = BLOBMSG_TYPE_STRING},
144 };
145 
146 static const struct blobmsg_policy macfilterSetStatePolicy[SET_NETWORK_MAX] = {
147     [SETNETWORK] = {.name = "state", .type = BLOBMSG_TYPE_STRING},
148 };
149 
150 static const struct blobmsg_policy removeJoinerPolicy[SET_NETWORK_MAX] = {
151     [SETNETWORK] = {.name = "eui64", .type = BLOBMSG_TYPE_STRING},
152 };
153 
154 static const struct blobmsg_policy addJoinerPolicy[ADD_JOINER_MAX] = {
155     [PSKD]  = {.name = "pskd", .type = BLOBMSG_TYPE_STRING},
156     [EUI64] = {.name = "eui64", .type = BLOBMSG_TYPE_STRING},
157 };
158 
159 static const struct blobmsg_policy mgmtsetPolicy[MGMTSET_MAX] = {
160     [NETWORKKEY]  = {.name = "networkkey", .type = BLOBMSG_TYPE_STRING},
161     [NETWORKNAME] = {.name = "networkname", .type = BLOBMSG_TYPE_STRING},
162     [EXTPANID]    = {.name = "extpanid", .type = BLOBMSG_TYPE_STRING},
163     [PANID]       = {.name = "panid", .type = BLOBMSG_TYPE_STRING},
164     [CHANNEL]     = {.name = "channel", .type = BLOBMSG_TYPE_STRING},
165     [PSKC]        = {.name = "pskc", .type = BLOBMSG_TYPE_STRING},
166 };
167 
168 static const struct ubus_method otbrMethods[] = {
169     {"scan", &UbusServer::UbusScanHandler, 0, 0, nullptr, 0},
170     {"channel", &UbusServer::UbusChannelHandler, 0, 0, nullptr, 0},
171     {"setchannel", &UbusServer::UbusSetChannelHandler, 0, 0, setChannelPolicy, ARRAY_SIZE(setChannelPolicy)},
172     {"networkname", &UbusServer::UbusNetworknameHandler, 0, 0, nullptr, 0},
173     {"setnetworkname", &UbusServer::UbusSetNetworknameHandler, 0, 0, setNetworknamePolicy,
174      ARRAY_SIZE(setNetworknamePolicy)},
175     {"state", &UbusServer::UbusStateHandler, 0, 0, nullptr, 0},
176     {"panid", &UbusServer::UbusPanIdHandler, 0, 0, nullptr, 0},
177     {"setpanid", &UbusServer::UbusSetPanIdHandler, 0, 0, setPanIdPolicy, ARRAY_SIZE(setPanIdPolicy)},
178     {"rloc16", &UbusServer::UbusRloc16Handler, 0, 0, nullptr, 0},
179     {"extpanid", &UbusServer::UbusExtPanIdHandler, 0, 0, nullptr, 0},
180     {"setextpanid", &UbusServer::UbusSetExtPanIdHandler, 0, 0, setExtPanIdPolicy, ARRAY_SIZE(setExtPanIdPolicy)},
181     {"networkkey", &UbusServer::UbusNetworkkeyHandler, 0, 0, nullptr, 0},
182     {"setnetworkkey", &UbusServer::UbusSetNetworkkeyHandler, 0, 0, setNetworkkeyPolicy,
183      ARRAY_SIZE(setNetworkkeyPolicy)},
184     {"pskc", &UbusServer::UbusPskcHandler, 0, 0, nullptr, 0},
185     {"setpskc", &UbusServer::UbusSetPskcHandler, 0, 0, setPskcPolicy, ARRAY_SIZE(setPskcPolicy)},
186     {"threadstart", &UbusServer::UbusThreadStartHandler, 0, 0, nullptr, 0},
187     {"threadstop", &UbusServer::UbusThreadStopHandler, 0, 0, nullptr, 0},
188     {"neighbor", &UbusServer::UbusNeighborHandler, 0, 0, nullptr, 0},
189     {"parent", &UbusServer::UbusParentHandler, 0, 0, nullptr, 0},
190     {"mode", &UbusServer::UbusModeHandler, 0, 0, nullptr, 0},
191     {"setmode", &UbusServer::UbusSetModeHandler, 0, 0, setModePolicy, ARRAY_SIZE(setModePolicy)},
192     {"partitionid", &UbusServer::UbusPartitionIdHandler, 0, 0, nullptr, 0},
193     {"leave", &UbusServer::UbusLeaveHandler, 0, 0, nullptr, 0},
194     {"leaderdata", &UbusServer::UbusLeaderdataHandler, 0, 0, nullptr, 0},
195     {"networkdata", &UbusServer::UbusNetworkdataHandler, 0, 0, nullptr, 0},
196     {"commissionerstart", &UbusServer::UbusCommissionerStartHandler, 0, 0, nullptr, 0},
197     {"joinernum", &UbusServer::UbusJoinerNumHandler, 0, 0, nullptr, 0},
198     {"joinerremove", &UbusServer::UbusJoinerRemoveHandler, 0, 0, nullptr, 0},
199     {"macfiltersetstate", &UbusServer::UbusMacfilterSetStateHandler, 0, 0, macfilterSetStatePolicy,
200      ARRAY_SIZE(macfilterSetStatePolicy)},
201     {"macfilteradd", &UbusServer::UbusMacfilterAddHandler, 0, 0, macfilterAddPolicy, ARRAY_SIZE(macfilterAddPolicy)},
202     {"macfilterremove", &UbusServer::UbusMacfilterRemoveHandler, 0, 0, macfilterRemovePolicy,
203      ARRAY_SIZE(macfilterRemovePolicy)},
204     {"macfilterclear", &UbusServer::UbusMacfilterClearHandler, 0, 0, nullptr, 0},
205     {"macfilterstate", &UbusServer::UbusMacfilterStateHandler, 0, 0, nullptr, 0},
206     {"macfilteraddr", &UbusServer::UbusMacfilterAddrHandler, 0, 0, nullptr, 0},
207     {"joineradd", &UbusServer::UbusJoinerAddHandler, 0, 0, addJoinerPolicy, ARRAY_SIZE(addJoinerPolicy)},
208     {"mgmtset", &UbusServer::UbusMgmtsetHandler, 0, 0, mgmtsetPolicy, ARRAY_SIZE(mgmtsetPolicy)},
209     {"interfacename", &UbusServer::UbusInterfaceNameHandler, 0, 0, nullptr, 0},
210 };
211 
212 static struct ubus_object_type otbrObjType = {"otbr_prog", 0, otbrMethods, ARRAY_SIZE(otbrMethods)};
213 
214 static struct ubus_object otbr = {
215     avl : {},
216     name : "otbr",
217     id : 0,
218     path : nullptr,
219     type : &otbrObjType,
220     subscribe_cb : nullptr,
221     has_subscribers : false,
222     methods : otbrMethods,
223     n_methods : ARRAY_SIZE(otbrMethods),
224 };
225 
ProcessScan(void)226 void UbusServer::ProcessScan(void)
227 {
228     otError  error        = OT_ERROR_NONE;
229     uint32_t scanChannels = 0;
230     uint16_t scanDuration = 0;
231 
232     mNcpThreadMutex->lock();
233     SuccessOrExit(error = otLinkActiveScan(mController->GetInstance(), scanChannels, scanDuration,
234                                            &UbusServer::HandleActiveScanResult, this));
235 exit:
236     mNcpThreadMutex->unlock();
237     return;
238 }
239 
HandleActiveScanResult(otActiveScanResult * aResult,void * aContext)240 void UbusServer::HandleActiveScanResult(otActiveScanResult *aResult, void *aContext)
241 {
242     static_cast<UbusServer *>(aContext)->HandleActiveScanResultDetail(aResult);
243 }
244 
OutputBytes(const uint8_t * aBytes,uint8_t aLength,char * aOutput)245 void UbusServer::OutputBytes(const uint8_t *aBytes, uint8_t aLength, char *aOutput)
246 {
247     char byte2char[5] = "";
248     for (int i = 0; i < aLength; i++)
249     {
250         sprintf(byte2char, "%02x", aBytes[i]);
251         strcat(aOutput, byte2char);
252     }
253 }
254 
AppendResult(otError aError,struct ubus_context * aContext,struct ubus_request_data * aRequest)255 void UbusServer::AppendResult(otError aError, struct ubus_context *aContext, struct ubus_request_data *aRequest)
256 {
257     blobmsg_add_u16(&mBuf, "Error", aError);
258     ubus_send_reply(aContext, aRequest, mBuf.head);
259 }
260 
HandleActiveScanResultDetail(otActiveScanResult * aResult)261 void UbusServer::HandleActiveScanResultDetail(otActiveScanResult *aResult)
262 {
263     void *jsonList = nullptr;
264 
265     char panidstring[PANID_LENGTH];
266     char xpanidstring[XPANID_LENGTH] = "";
267 
268     if (aResult == nullptr)
269     {
270         blobmsg_close_array(&mBuf, sJsonUri);
271         mIfFinishScan = true;
272         goto exit;
273     }
274 
275     jsonList = blobmsg_open_table(&mBuf, nullptr);
276 
277     blobmsg_add_string(&mBuf, "NetworkName", aResult->mNetworkName.m8);
278 
279     OutputBytes(aResult->mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE, xpanidstring);
280     blobmsg_add_string(&mBuf, "ExtendedPanId", xpanidstring);
281 
282     sprintf(panidstring, "0x%04x", aResult->mPanId);
283     blobmsg_add_string(&mBuf, "PanId", panidstring);
284 
285     blobmsg_add_u32(&mBuf, "Channel", aResult->mChannel);
286 
287     blobmsg_add_u32(&mBuf, "Rssi", aResult->mRssi);
288 
289     blobmsg_add_u32(&mBuf, "Lqi", aResult->mLqi);
290 
291     blobmsg_close_table(&mBuf, jsonList);
292 
293 exit:
294     return;
295 }
296 
UbusScanHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)297 int UbusServer::UbusScanHandler(struct ubus_context      *aContext,
298                                 struct ubus_object       *aObj,
299                                 struct ubus_request_data *aRequest,
300                                 const char               *aMethod,
301                                 struct blob_attr         *aMsg)
302 {
303     return GetInstance().UbusScanHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
304 }
305 
UbusScanHandlerDetail(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)306 int UbusServer::UbusScanHandlerDetail(struct ubus_context      *aContext,
307                                       struct ubus_object       *aObj,
308                                       struct ubus_request_data *aRequest,
309                                       const char               *aMethod,
310                                       struct blob_attr         *aMsg)
311 {
312     OT_UNUSED_VARIABLE(aObj);
313     OT_UNUSED_VARIABLE(aMethod);
314     OT_UNUSED_VARIABLE(aMsg);
315 
316     otError  error = OT_ERROR_NONE;
317     uint64_t eventNum;
318     ssize_t  retval;
319 
320     blob_buf_init(&mBuf, 0);
321     sJsonUri = blobmsg_open_array(&mBuf, "scan_list");
322 
323     mIfFinishScan = 0;
324     sUbusServerInstance->ProcessScan();
325 
326     eventNum = 1;
327     retval   = write(sUbusEfd, &eventNum, sizeof(uint64_t));
328     if (retval != sizeof(uint64_t))
329     {
330         error = OT_ERROR_FAILED;
331         goto exit;
332     }
333 
334     while (!mIfFinishScan)
335     {
336         sleep(1);
337     }
338 
339 exit:
340     AppendResult(error, aContext, aRequest);
341     return 0;
342 }
343 
UbusChannelHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)344 int UbusServer::UbusChannelHandler(struct ubus_context      *aContext,
345                                    struct ubus_object       *aObj,
346                                    struct ubus_request_data *aRequest,
347                                    const char               *aMethod,
348                                    struct blob_attr         *aMsg)
349 {
350     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "channel");
351 }
352 
UbusSetChannelHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)353 int UbusServer::UbusSetChannelHandler(struct ubus_context      *aContext,
354                                       struct ubus_object       *aObj,
355                                       struct ubus_request_data *aRequest,
356                                       const char               *aMethod,
357                                       struct blob_attr         *aMsg)
358 {
359     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "channel");
360 }
361 
UbusJoinerNumHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)362 int UbusServer::UbusJoinerNumHandler(struct ubus_context      *aContext,
363                                      struct ubus_object       *aObj,
364                                      struct ubus_request_data *aRequest,
365                                      const char               *aMethod,
366                                      struct blob_attr         *aMsg)
367 {
368     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "joinernum");
369 }
370 
UbusNetworknameHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)371 int UbusServer::UbusNetworknameHandler(struct ubus_context      *aContext,
372                                        struct ubus_object       *aObj,
373                                        struct ubus_request_data *aRequest,
374                                        const char               *aMethod,
375                                        struct blob_attr         *aMsg)
376 {
377     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkname");
378 }
379 
UbusSetNetworknameHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)380 int UbusServer::UbusSetNetworknameHandler(struct ubus_context      *aContext,
381                                           struct ubus_object       *aObj,
382                                           struct ubus_request_data *aRequest,
383                                           const char               *aMethod,
384                                           struct blob_attr         *aMsg)
385 {
386     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkname");
387 }
388 
UbusStateHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)389 int UbusServer::UbusStateHandler(struct ubus_context      *aContext,
390                                  struct ubus_object       *aObj,
391                                  struct ubus_request_data *aRequest,
392                                  const char               *aMethod,
393                                  struct blob_attr         *aMsg)
394 {
395     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "state");
396 }
397 
UbusRloc16Handler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)398 int UbusServer::UbusRloc16Handler(struct ubus_context      *aContext,
399                                   struct ubus_object       *aObj,
400                                   struct ubus_request_data *aRequest,
401                                   const char               *aMethod,
402                                   struct blob_attr         *aMsg)
403 {
404     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "rloc16");
405 }
406 
UbusPanIdHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)407 int UbusServer::UbusPanIdHandler(struct ubus_context      *aContext,
408                                  struct ubus_object       *aObj,
409                                  struct ubus_request_data *aRequest,
410                                  const char               *aMethod,
411                                  struct blob_attr         *aMsg)
412 {
413     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "panid");
414 }
415 
UbusSetPanIdHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)416 int UbusServer::UbusSetPanIdHandler(struct ubus_context      *aContext,
417                                     struct ubus_object       *aObj,
418                                     struct ubus_request_data *aRequest,
419                                     const char               *aMethod,
420                                     struct blob_attr         *aMsg)
421 {
422     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "panid");
423 }
424 
UbusExtPanIdHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)425 int UbusServer::UbusExtPanIdHandler(struct ubus_context      *aContext,
426                                     struct ubus_object       *aObj,
427                                     struct ubus_request_data *aRequest,
428                                     const char               *aMethod,
429                                     struct blob_attr         *aMsg)
430 {
431     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "extpanid");
432 }
433 
UbusSetExtPanIdHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)434 int UbusServer::UbusSetExtPanIdHandler(struct ubus_context      *aContext,
435                                        struct ubus_object       *aObj,
436                                        struct ubus_request_data *aRequest,
437                                        const char               *aMethod,
438                                        struct blob_attr         *aMsg)
439 {
440     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "extpanid");
441 }
442 
UbusPskcHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)443 int UbusServer::UbusPskcHandler(struct ubus_context      *aContext,
444                                 struct ubus_object       *aObj,
445                                 struct ubus_request_data *aRequest,
446                                 const char               *aMethod,
447                                 struct blob_attr         *aMsg)
448 {
449     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "pskc");
450 }
451 
UbusSetPskcHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)452 int UbusServer::UbusSetPskcHandler(struct ubus_context      *aContext,
453                                    struct ubus_object       *aObj,
454                                    struct ubus_request_data *aRequest,
455                                    const char               *aMethod,
456                                    struct blob_attr         *aMsg)
457 {
458     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "pskc");
459 }
460 
UbusNetworkkeyHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)461 int UbusServer::UbusNetworkkeyHandler(struct ubus_context      *aContext,
462                                       struct ubus_object       *aObj,
463                                       struct ubus_request_data *aRequest,
464                                       const char               *aMethod,
465                                       struct blob_attr         *aMsg)
466 {
467     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkkey");
468 }
469 
UbusSetNetworkkeyHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)470 int UbusServer::UbusSetNetworkkeyHandler(struct ubus_context      *aContext,
471                                          struct ubus_object       *aObj,
472                                          struct ubus_request_data *aRequest,
473                                          const char               *aMethod,
474                                          struct blob_attr         *aMsg)
475 {
476     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkkey");
477 }
478 
UbusThreadStartHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)479 int UbusServer::UbusThreadStartHandler(struct ubus_context      *aContext,
480                                        struct ubus_object       *aObj,
481                                        struct ubus_request_data *aRequest,
482                                        const char               *aMethod,
483                                        struct blob_attr         *aMsg)
484 {
485     return GetInstance().UbusThreadHandler(aContext, aObj, aRequest, aMethod, aMsg, "start");
486 }
487 
UbusThreadStopHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)488 int UbusServer::UbusThreadStopHandler(struct ubus_context      *aContext,
489                                       struct ubus_object       *aObj,
490                                       struct ubus_request_data *aRequest,
491                                       const char               *aMethod,
492                                       struct blob_attr         *aMsg)
493 {
494     return GetInstance().UbusThreadHandler(aContext, aObj, aRequest, aMethod, aMsg, "stop");
495 }
496 
UbusParentHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)497 int UbusServer::UbusParentHandler(struct ubus_context      *aContext,
498                                   struct ubus_object       *aObj,
499                                   struct ubus_request_data *aRequest,
500                                   const char               *aMethod,
501                                   struct blob_attr         *aMsg)
502 {
503     return GetInstance().UbusParentHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
504 }
505 
UbusNeighborHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)506 int UbusServer::UbusNeighborHandler(struct ubus_context      *aContext,
507                                     struct ubus_object       *aObj,
508                                     struct ubus_request_data *aRequest,
509                                     const char               *aMethod,
510                                     struct blob_attr         *aMsg)
511 {
512     return GetInstance().UbusNeighborHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
513 }
514 
UbusModeHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)515 int UbusServer::UbusModeHandler(struct ubus_context      *aContext,
516                                 struct ubus_object       *aObj,
517                                 struct ubus_request_data *aRequest,
518                                 const char               *aMethod,
519                                 struct blob_attr         *aMsg)
520 {
521     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "mode");
522 }
523 
UbusSetModeHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)524 int UbusServer::UbusSetModeHandler(struct ubus_context      *aContext,
525                                    struct ubus_object       *aObj,
526                                    struct ubus_request_data *aRequest,
527                                    const char               *aMethod,
528                                    struct blob_attr         *aMsg)
529 {
530     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "mode");
531 }
532 
UbusPartitionIdHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)533 int UbusServer::UbusPartitionIdHandler(struct ubus_context      *aContext,
534                                        struct ubus_object       *aObj,
535                                        struct ubus_request_data *aRequest,
536                                        const char               *aMethod,
537                                        struct blob_attr         *aMsg)
538 {
539     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "partitionid");
540 }
541 
UbusLeaveHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)542 int UbusServer::UbusLeaveHandler(struct ubus_context      *aContext,
543                                  struct ubus_object       *aObj,
544                                  struct ubus_request_data *aRequest,
545                                  const char               *aMethod,
546                                  struct blob_attr         *aMsg)
547 {
548     return GetInstance().UbusLeaveHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
549 }
550 
UbusLeaderdataHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)551 int UbusServer::UbusLeaderdataHandler(struct ubus_context      *aContext,
552                                       struct ubus_object       *aObj,
553                                       struct ubus_request_data *aRequest,
554                                       const char               *aMethod,
555                                       struct blob_attr         *aMsg)
556 {
557     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "leaderdata");
558 }
559 
UbusNetworkdataHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)560 int UbusServer::UbusNetworkdataHandler(struct ubus_context      *aContext,
561                                        struct ubus_object       *aObj,
562                                        struct ubus_request_data *aRequest,
563                                        const char               *aMethod,
564                                        struct blob_attr         *aMsg)
565 {
566     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkdata");
567 }
568 
UbusCommissionerStartHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)569 int UbusServer::UbusCommissionerStartHandler(struct ubus_context      *aContext,
570                                              struct ubus_object       *aObj,
571                                              struct ubus_request_data *aRequest,
572                                              const char               *aMethod,
573                                              struct blob_attr         *aMsg)
574 {
575     return GetInstance().UbusCommissioner(aContext, aObj, aRequest, aMethod, aMsg, "start");
576 }
577 
UbusJoinerRemoveHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)578 int UbusServer::UbusJoinerRemoveHandler(struct ubus_context      *aContext,
579                                         struct ubus_object       *aObj,
580                                         struct ubus_request_data *aRequest,
581                                         const char               *aMethod,
582                                         struct blob_attr         *aMsg)
583 {
584     return GetInstance().UbusCommissioner(aContext, aObj, aRequest, aMethod, aMsg, "joinerremove");
585 }
586 
UbusMgmtsetHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)587 int UbusServer::UbusMgmtsetHandler(struct ubus_context      *aContext,
588                                    struct ubus_object       *aObj,
589                                    struct ubus_request_data *aRequest,
590                                    const char               *aMethod,
591                                    struct blob_attr         *aMsg)
592 {
593     return GetInstance().UbusMgmtset(aContext, aObj, aRequest, aMethod, aMsg);
594 }
595 
UbusInterfaceNameHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)596 int UbusServer::UbusInterfaceNameHandler(struct ubus_context      *aContext,
597                                          struct ubus_object       *aObj,
598                                          struct ubus_request_data *aRequest,
599                                          const char               *aMethod,
600                                          struct blob_attr         *aMsg)
601 {
602     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "interfacename");
603 }
604 
UbusJoinerAddHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)605 int UbusServer::UbusJoinerAddHandler(struct ubus_context      *aContext,
606                                      struct ubus_object       *aObj,
607                                      struct ubus_request_data *aRequest,
608                                      const char               *aMethod,
609                                      struct blob_attr         *aMsg)
610 {
611     return GetInstance().UbusCommissioner(aContext, aObj, aRequest, aMethod, aMsg, "joineradd");
612 }
613 
UbusMacfilterAddrHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)614 int UbusServer::UbusMacfilterAddrHandler(struct ubus_context      *aContext,
615                                          struct ubus_object       *aObj,
616                                          struct ubus_request_data *aRequest,
617                                          const char               *aMethod,
618                                          struct blob_attr         *aMsg)
619 {
620     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilteraddr");
621 }
622 
UbusMacfilterStateHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)623 int UbusServer::UbusMacfilterStateHandler(struct ubus_context      *aContext,
624                                           struct ubus_object       *aObj,
625                                           struct ubus_request_data *aRequest,
626                                           const char               *aMethod,
627                                           struct blob_attr         *aMsg)
628 {
629     return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilterstate");
630 }
631 
UbusMacfilterAddHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)632 int UbusServer::UbusMacfilterAddHandler(struct ubus_context      *aContext,
633                                         struct ubus_object       *aObj,
634                                         struct ubus_request_data *aRequest,
635                                         const char               *aMethod,
636                                         struct blob_attr         *aMsg)
637 {
638     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilteradd");
639 }
640 
UbusMacfilterRemoveHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)641 int UbusServer::UbusMacfilterRemoveHandler(struct ubus_context      *aContext,
642                                            struct ubus_object       *aObj,
643                                            struct ubus_request_data *aRequest,
644                                            const char               *aMethod,
645                                            struct blob_attr         *aMsg)
646 {
647     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilterremove");
648 }
649 
UbusMacfilterSetStateHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)650 int UbusServer::UbusMacfilterSetStateHandler(struct ubus_context      *aContext,
651                                              struct ubus_object       *aObj,
652                                              struct ubus_request_data *aRequest,
653                                              const char               *aMethod,
654                                              struct blob_attr         *aMsg)
655 {
656     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfiltersetstate");
657 }
658 
UbusMacfilterClearHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)659 int UbusServer::UbusMacfilterClearHandler(struct ubus_context      *aContext,
660                                           struct ubus_object       *aObj,
661                                           struct ubus_request_data *aRequest,
662                                           const char               *aMethod,
663                                           struct blob_attr         *aMsg)
664 {
665     return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilterclear");
666 }
667 
UbusLeaveHandlerDetail(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)668 int UbusServer::UbusLeaveHandlerDetail(struct ubus_context      *aContext,
669                                        struct ubus_object       *aObj,
670                                        struct ubus_request_data *aRequest,
671                                        const char               *aMethod,
672                                        struct blob_attr         *aMsg)
673 {
674     OT_UNUSED_VARIABLE(aObj);
675     OT_UNUSED_VARIABLE(aMethod);
676     OT_UNUSED_VARIABLE(aMsg);
677 
678     otError  error = OT_ERROR_NONE;
679     uint64_t eventNum;
680     ssize_t  retval;
681 
682     mNcpThreadMutex->lock();
683     otInstanceFactoryReset(mController->GetInstance());
684 
685     eventNum = 1;
686     retval   = write(sUbusEfd, &eventNum, sizeof(uint64_t));
687     if (retval != sizeof(uint64_t))
688     {
689         error = OT_ERROR_FAILED;
690         goto exit;
691     }
692 
693     blob_buf_init(&mBuf, 0);
694 
695 exit:
696     mNcpThreadMutex->unlock();
697     AppendResult(error, aContext, aRequest);
698     return 0;
699 }
UbusThreadHandler(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg,const char * aAction)700 int UbusServer::UbusThreadHandler(struct ubus_context      *aContext,
701                                   struct ubus_object       *aObj,
702                                   struct ubus_request_data *aRequest,
703                                   const char               *aMethod,
704                                   struct blob_attr         *aMsg,
705                                   const char               *aAction)
706 {
707     OT_UNUSED_VARIABLE(aObj);
708     OT_UNUSED_VARIABLE(aMethod);
709     OT_UNUSED_VARIABLE(aMsg);
710 
711     otError error = OT_ERROR_NONE;
712 
713     blob_buf_init(&mBuf, 0);
714 
715     if (!strcmp(aAction, "start"))
716     {
717         mNcpThreadMutex->lock();
718         SuccessOrExit(error = otIp6SetEnabled(mController->GetInstance(), true));
719         SuccessOrExit(error = otThreadSetEnabled(mController->GetInstance(), true));
720     }
721     else if (!strcmp(aAction, "stop"))
722     {
723         mNcpThreadMutex->lock();
724         SuccessOrExit(error = otThreadSetEnabled(mController->GetInstance(), false));
725         SuccessOrExit(error = otIp6SetEnabled(mController->GetInstance(), false));
726     }
727 
728 exit:
729     mNcpThreadMutex->unlock();
730     AppendResult(error, aContext, aRequest);
731     return 0;
732 }
733 
UbusParentHandlerDetail(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)734 int UbusServer::UbusParentHandlerDetail(struct ubus_context      *aContext,
735                                         struct ubus_object       *aObj,
736                                         struct ubus_request_data *aRequest,
737                                         const char               *aMethod,
738                                         struct blob_attr         *aMsg)
739 {
740     OT_UNUSED_VARIABLE(aObj);
741     OT_UNUSED_VARIABLE(aMethod);
742     OT_UNUSED_VARIABLE(aMsg);
743 
744     otError      error = OT_ERROR_NONE;
745     otRouterInfo parentInfo;
746     char         extAddress[XPANID_LENGTH] = "";
747     char         transfer[XPANID_LENGTH]   = "";
748     void        *jsonList                  = nullptr;
749     void        *jsonArray                 = nullptr;
750 
751     blob_buf_init(&mBuf, 0);
752 
753     mNcpThreadMutex->lock();
754     SuccessOrExit(error = otThreadGetParentInfo(mController->GetInstance(), &parentInfo));
755 
756     jsonArray = blobmsg_open_array(&mBuf, "parent_list");
757     jsonList  = blobmsg_open_table(&mBuf, "parent");
758     blobmsg_add_string(&mBuf, "Role", "R");
759 
760     sprintf(transfer, "0x%04x", parentInfo.mRloc16);
761     blobmsg_add_string(&mBuf, "Rloc16", transfer);
762 
763     sprintf(transfer, "%3d", parentInfo.mAge);
764     blobmsg_add_string(&mBuf, "Age", transfer);
765 
766     OutputBytes(parentInfo.mExtAddress.m8, sizeof(parentInfo.mExtAddress.m8), extAddress);
767     blobmsg_add_string(&mBuf, "ExtAddress", extAddress);
768 
769     blobmsg_add_u16(&mBuf, "LinkQualityIn", parentInfo.mLinkQualityIn);
770 
771     blobmsg_close_table(&mBuf, jsonList);
772     blobmsg_close_array(&mBuf, jsonArray);
773 
774 exit:
775     mNcpThreadMutex->unlock();
776     AppendResult(error, aContext, aRequest);
777     return error;
778 }
779 
UbusNeighborHandlerDetail(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)780 int UbusServer::UbusNeighborHandlerDetail(struct ubus_context      *aContext,
781                                           struct ubus_object       *aObj,
782                                           struct ubus_request_data *aRequest,
783                                           const char               *aMethod,
784                                           struct blob_attr         *aMsg)
785 {
786     OT_UNUSED_VARIABLE(aObj);
787     OT_UNUSED_VARIABLE(aMethod);
788     OT_UNUSED_VARIABLE(aMsg);
789 
790     otError                error = OT_ERROR_NONE;
791     otNeighborInfo         neighborInfo;
792     otNeighborInfoIterator iterator                  = OT_NEIGHBOR_INFO_ITERATOR_INIT;
793     char                   transfer[XPANID_LENGTH]   = "";
794     void                  *jsonList                  = nullptr;
795     char                   mode[5]                   = "";
796     char                   extAddress[XPANID_LENGTH] = "";
797 
798     blob_buf_init(&mBuf, 0);
799 
800     sJsonUri = blobmsg_open_array(&mBuf, "neighbor_list");
801 
802     mNcpThreadMutex->lock();
803     while (otThreadGetNextNeighborInfo(mController->GetInstance(), &iterator, &neighborInfo) == OT_ERROR_NONE)
804     {
805         jsonList = blobmsg_open_table(&mBuf, nullptr);
806 
807         blobmsg_add_string(&mBuf, "Role", neighborInfo.mIsChild ? "C" : "R");
808 
809         sprintf(transfer, "0x%04x", neighborInfo.mRloc16);
810         blobmsg_add_string(&mBuf, "Rloc16", transfer);
811 
812         sprintf(transfer, "%3d", neighborInfo.mAge);
813         blobmsg_add_string(&mBuf, "Age", transfer);
814 
815         sprintf(transfer, "%8d", neighborInfo.mAverageRssi);
816         blobmsg_add_string(&mBuf, "AvgRssi", transfer);
817 
818         sprintf(transfer, "%9d", neighborInfo.mLastRssi);
819         blobmsg_add_string(&mBuf, "LastRssi", transfer);
820 
821         if (neighborInfo.mRxOnWhenIdle)
822         {
823             strcat(mode, "r");
824         }
825 
826         if (neighborInfo.mFullThreadDevice)
827         {
828             strcat(mode, "d");
829         }
830 
831         if (neighborInfo.mFullNetworkData)
832         {
833             strcat(mode, "n");
834         }
835         blobmsg_add_string(&mBuf, "Mode", mode);
836 
837         OutputBytes(neighborInfo.mExtAddress.m8, sizeof(neighborInfo.mExtAddress.m8), extAddress);
838         blobmsg_add_string(&mBuf, "ExtAddress", extAddress);
839 
840         blobmsg_add_u16(&mBuf, "LinkQualityIn", neighborInfo.mLinkQualityIn);
841 
842         blobmsg_close_table(&mBuf, jsonList);
843 
844         memset(mode, 0, sizeof(mode));
845         memset(extAddress, 0, sizeof(extAddress));
846     }
847 
848     blobmsg_close_array(&mBuf, sJsonUri);
849 
850     mNcpThreadMutex->unlock();
851 
852     AppendResult(error, aContext, aRequest);
853     return 0;
854 }
855 
UbusMgmtset(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg)856 int UbusServer::UbusMgmtset(struct ubus_context      *aContext,
857                             struct ubus_object       *aObj,
858                             struct ubus_request_data *aRequest,
859                             const char               *aMethod,
860                             struct blob_attr         *aMsg)
861 {
862     OT_UNUSED_VARIABLE(aObj);
863     OT_UNUSED_VARIABLE(aMethod);
864     OT_UNUSED_VARIABLE(aMsg);
865 
866     otError              error = OT_ERROR_NONE;
867     struct blob_attr    *tb[MGMTSET_MAX];
868     otOperationalDataset dataset;
869     uint8_t              tlvs[128];
870     long                 value;
871     int                  length = 0;
872 
873     SuccessOrExit(error = otDatasetGetActive(mController->GetInstance(), &dataset));
874 
875     blobmsg_parse(mgmtsetPolicy, MGMTSET_MAX, tb, blob_data(aMsg), blob_len(aMsg));
876     if (tb[NETWORKKEY] != nullptr)
877     {
878         dataset.mComponents.mIsNetworkKeyPresent = true;
879         VerifyOrExit((length = Hex2Bin(blobmsg_get_string(tb[NETWORKKEY]), dataset.mNetworkKey.m8,
880                                        sizeof(dataset.mNetworkKey.m8))) == OT_NETWORK_KEY_SIZE,
881                      error = OT_ERROR_PARSE);
882         length = 0;
883     }
884     if (tb[NETWORKNAME] != nullptr)
885     {
886         dataset.mComponents.mIsNetworkNamePresent = true;
887         VerifyOrExit((length = static_cast<int>(strlen(blobmsg_get_string(tb[NETWORKNAME])))) <=
888                          OT_NETWORK_NAME_MAX_SIZE,
889                      error = OT_ERROR_PARSE);
890         memset(&dataset.mNetworkName, 0, sizeof(dataset.mNetworkName));
891         memcpy(dataset.mNetworkName.m8, blobmsg_get_string(tb[NETWORKNAME]), static_cast<size_t>(length));
892         length = 0;
893     }
894     if (tb[EXTPANID] != nullptr)
895     {
896         dataset.mComponents.mIsExtendedPanIdPresent = true;
897         VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[EXTPANID]), dataset.mExtendedPanId.m8,
898                              sizeof(dataset.mExtendedPanId.m8)) >= 0,
899                      error = OT_ERROR_PARSE);
900     }
901     if (tb[PANID] != nullptr)
902     {
903         dataset.mComponents.mIsPanIdPresent = true;
904         SuccessOrExit(error = ParseLong(blobmsg_get_string(tb[PANID]), value));
905         dataset.mPanId = static_cast<otPanId>(value);
906     }
907     if (tb[CHANNEL] != nullptr)
908     {
909         dataset.mComponents.mIsChannelPresent = true;
910         SuccessOrExit(error = ParseLong(blobmsg_get_string(tb[CHANNEL]), value));
911         dataset.mChannel = static_cast<uint16_t>(value);
912     }
913     if (tb[PSKC] != nullptr)
914     {
915         dataset.mComponents.mIsPskcPresent = true;
916         VerifyOrExit((length = Hex2Bin(blobmsg_get_string(tb[PSKC]), dataset.mPskc.m8, sizeof(dataset.mPskc.m8))) ==
917                          OT_PSKC_MAX_SIZE,
918                      error = OT_ERROR_PARSE);
919         length = 0;
920     }
921     dataset.mActiveTimestamp.mSeconds++;
922     if (otCommissionerGetState(mController->GetInstance()) == OT_COMMISSIONER_STATE_DISABLED)
923     {
924         otCommissionerStop(mController->GetInstance());
925     }
926     SuccessOrExit(error = otDatasetSendMgmtActiveSet(mController->GetInstance(), &dataset, tlvs,
927                                                      static_cast<uint8_t>(length), /* aCallback */ nullptr,
928                                                      /* aContext */ nullptr));
929 exit:
930     AppendResult(error, aContext, aRequest);
931     return 0;
932 }
933 
UbusCommissioner(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg,const char * aAction)934 int UbusServer::UbusCommissioner(struct ubus_context      *aContext,
935                                  struct ubus_object       *aObj,
936                                  struct ubus_request_data *aRequest,
937                                  const char               *aMethod,
938                                  struct blob_attr         *aMsg,
939                                  const char               *aAction)
940 {
941     OT_UNUSED_VARIABLE(aObj);
942     OT_UNUSED_VARIABLE(aMethod);
943     OT_UNUSED_VARIABLE(aMsg);
944 
945     otError error = OT_ERROR_NONE;
946 
947     mNcpThreadMutex->lock();
948 
949     if (!strcmp(aAction, "start"))
950     {
951         if (otCommissionerGetState(mController->GetInstance()) == OT_COMMISSIONER_STATE_DISABLED)
952         {
953             error = otCommissionerStart(mController->GetInstance(), &UbusServer::HandleStateChanged,
954                                         &UbusServer::HandleJoinerEvent, this);
955         }
956     }
957     else if (!strcmp(aAction, "joineradd"))
958     {
959         struct blob_attr   *tb[ADD_JOINER_MAX];
960         otExtAddress        addr;
961         const otExtAddress *addrPtr = nullptr;
962         char               *pskd    = nullptr;
963 
964         blobmsg_parse(addJoinerPolicy, ADD_JOINER_MAX, tb, blob_data(aMsg), blob_len(aMsg));
965         if (tb[PSKD] != nullptr)
966         {
967             pskd = blobmsg_get_string(tb[PSKD]);
968         }
969         if (tb[EUI64] != nullptr)
970         {
971             if (!strcmp(blobmsg_get_string(tb[EUI64]), "*"))
972             {
973                 addrPtr = nullptr;
974                 memset(&addr, 0, sizeof(addr));
975             }
976             else
977             {
978                 VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[EUI64]), addr.m8, sizeof(addr)) == sizeof(addr),
979                              error = OT_ERROR_PARSE);
980                 addrPtr = &addr;
981             }
982         }
983 
984         unsigned long timeout = kDefaultJoinerTimeout;
985         SuccessOrExit(
986             error = otCommissionerAddJoiner(mController->GetInstance(), addrPtr, pskd, static_cast<uint32_t>(timeout)));
987     }
988     else if (!strcmp(aAction, "joinerremove"))
989     {
990         struct blob_attr   *tb[SET_NETWORK_MAX];
991         otExtAddress        addr;
992         const otExtAddress *addrPtr = nullptr;
993 
994         blobmsg_parse(removeJoinerPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
995         if (tb[SETNETWORK] != nullptr)
996         {
997             if (strcmp(blobmsg_get_string(tb[SETNETWORK]), "*") == 0)
998             {
999                 addrPtr = nullptr;
1000             }
1001             else
1002             {
1003                 VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[SETNETWORK]), addr.m8, sizeof(addr)) == sizeof(addr),
1004                              error = OT_ERROR_PARSE);
1005                 addrPtr = &addr;
1006             }
1007         }
1008 
1009         SuccessOrExit(error = otCommissionerRemoveJoiner(mController->GetInstance(), addrPtr));
1010     }
1011 
1012 exit:
1013     mNcpThreadMutex->unlock();
1014     blob_buf_init(&mBuf, 0);
1015     AppendResult(error, aContext, aRequest);
1016     return 0;
1017 }
1018 
HandleStateChanged(otCommissionerState aState,void * aContext)1019 void UbusServer::HandleStateChanged(otCommissionerState aState, void *aContext)
1020 {
1021     static_cast<UbusServer *>(aContext)->HandleStateChanged(aState);
1022 }
1023 
HandleStateChanged(otCommissionerState aState)1024 void UbusServer::HandleStateChanged(otCommissionerState aState)
1025 {
1026     switch (aState)
1027     {
1028     case OT_COMMISSIONER_STATE_DISABLED:
1029         otbrLogInfo("Commissioner state disabled");
1030         break;
1031     case OT_COMMISSIONER_STATE_ACTIVE:
1032         otbrLogInfo("Commissioner state active");
1033         break;
1034     case OT_COMMISSIONER_STATE_PETITION:
1035         otbrLogInfo("Commissioner state petition");
1036         break;
1037     }
1038 }
1039 
HandleJoinerEvent(otCommissionerJoinerEvent aEvent,const otJoinerInfo * aJoinerInfo,const otExtAddress * aJoinerId,void * aContext)1040 void UbusServer::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
1041                                    const otJoinerInfo       *aJoinerInfo,
1042                                    const otExtAddress       *aJoinerId,
1043                                    void                     *aContext)
1044 {
1045     static_cast<UbusServer *>(aContext)->HandleJoinerEvent(aEvent, aJoinerInfo, aJoinerId);
1046 }
1047 
HandleJoinerEvent(otCommissionerJoinerEvent aEvent,const otJoinerInfo * aJoinerInfo,const otExtAddress * aJoinerId)1048 void UbusServer::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
1049                                    const otJoinerInfo       *aJoinerInfo,
1050                                    const otExtAddress       *aJoinerId)
1051 {
1052     OT_UNUSED_VARIABLE(aJoinerInfo);
1053     OT_UNUSED_VARIABLE(aJoinerId);
1054 
1055     switch (aEvent)
1056     {
1057     case OT_COMMISSIONER_JOINER_START:
1058         otbrLogInfo("Joiner start");
1059         break;
1060     case OT_COMMISSIONER_JOINER_CONNECTED:
1061         otbrLogInfo("Joiner connected");
1062         break;
1063     case OT_COMMISSIONER_JOINER_FINALIZE:
1064         otbrLogInfo("Joiner finalize");
1065         break;
1066     case OT_COMMISSIONER_JOINER_END:
1067         otbrLogInfo("Joiner end");
1068         break;
1069     case OT_COMMISSIONER_JOINER_REMOVED:
1070         otbrLogInfo("Joiner remove");
1071         break;
1072     }
1073 }
1074 
UbusGetInformation(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg,const char * aAction)1075 int UbusServer::UbusGetInformation(struct ubus_context      *aContext,
1076                                    struct ubus_object       *aObj,
1077                                    struct ubus_request_data *aRequest,
1078                                    const char               *aMethod,
1079                                    struct blob_attr         *aMsg,
1080                                    const char               *aAction)
1081 {
1082     OT_UNUSED_VARIABLE(aObj);
1083     OT_UNUSED_VARIABLE(aMethod);
1084     OT_UNUSED_VARIABLE(aMsg);
1085 
1086     otError error = OT_ERROR_NONE;
1087 
1088     blob_buf_init(&mBuf, 0);
1089 
1090     mNcpThreadMutex->lock();
1091     if (!strcmp(aAction, "networkname"))
1092         blobmsg_add_string(&mBuf, "NetworkName", otThreadGetNetworkName(mController->GetInstance()));
1093     else if (!strcmp(aAction, "interfacename"))
1094     {
1095         blobmsg_add_string(&mBuf, "InterfaceName", mController->GetInterfaceName());
1096     }
1097     else if (!strcmp(aAction, "state"))
1098     {
1099         char state[10];
1100         GetState(mController->GetInstance(), state);
1101         blobmsg_add_string(&mBuf, "State", state);
1102     }
1103     else if (!strcmp(aAction, "channel"))
1104         blobmsg_add_u32(&mBuf, "Channel", otLinkGetChannel(mController->GetInstance()));
1105     else if (!strcmp(aAction, "panid"))
1106     {
1107         char panIdString[PANID_LENGTH];
1108         sprintf(panIdString, "0x%04x", otLinkGetPanId(mController->GetInstance()));
1109         blobmsg_add_string(&mBuf, "PanId", panIdString);
1110     }
1111     else if (!strcmp(aAction, "rloc16"))
1112     {
1113         char rloc[PANID_LENGTH];
1114         sprintf(rloc, "0x%04x", otThreadGetRloc16(mController->GetInstance()));
1115         blobmsg_add_string(&mBuf, "rloc16", rloc);
1116     }
1117     else if (!strcmp(aAction, "networkkey"))
1118     {
1119         char         outputKey[NETWORKKEY_LENGTH] = "";
1120         otNetworkKey key;
1121 
1122         otThreadGetNetworkKey(mController->GetInstance(), &key);
1123         OutputBytes(key.m8, OT_NETWORK_KEY_SIZE, outputKey);
1124         blobmsg_add_string(&mBuf, "Networkkey", outputKey);
1125     }
1126     else if (!strcmp(aAction, "pskc"))
1127     {
1128         char   outputPskc[NETWORKKEY_LENGTH] = "";
1129         otPskc pskc;
1130 
1131         otThreadGetPskc(mController->GetInstance(), &pskc);
1132         OutputBytes(pskc.m8, OT_PSKC_MAX_SIZE, outputPskc);
1133         blobmsg_add_string(&mBuf, "pskc", outputPskc);
1134     }
1135     else if (!strcmp(aAction, "extpanid"))
1136     {
1137         char           outputExtPanId[XPANID_LENGTH] = "";
1138         const uint8_t *extPanId =
1139             reinterpret_cast<const uint8_t *>(otThreadGetExtendedPanId(mController->GetInstance()));
1140         OutputBytes(extPanId, OT_EXT_PAN_ID_SIZE, outputExtPanId);
1141         blobmsg_add_string(&mBuf, "ExtPanId", outputExtPanId);
1142     }
1143     else if (!strcmp(aAction, "mode"))
1144     {
1145         otLinkModeConfig linkMode;
1146         char             mode[5] = "";
1147 
1148         memset(&linkMode, 0, sizeof(otLinkModeConfig));
1149 
1150         linkMode = otThreadGetLinkMode(mController->GetInstance());
1151 
1152         if (linkMode.mRxOnWhenIdle)
1153         {
1154             strcat(mode, "r");
1155         }
1156 
1157         if (linkMode.mDeviceType)
1158         {
1159             strcat(mode, "d");
1160         }
1161 
1162         if (linkMode.mNetworkData)
1163         {
1164             strcat(mode, "n");
1165         }
1166         blobmsg_add_string(&mBuf, "Mode", mode);
1167     }
1168     else if (!strcmp(aAction, "partitionid"))
1169     {
1170         blobmsg_add_u32(&mBuf, "Partitionid", otThreadGetPartitionId(mController->GetInstance()));
1171     }
1172     else if (!strcmp(aAction, "leaderdata"))
1173     {
1174         otLeaderData leaderData;
1175 
1176         SuccessOrExit(error = otThreadGetLeaderData(mController->GetInstance(), &leaderData));
1177 
1178         sJsonUri = blobmsg_open_table(&mBuf, "leaderdata");
1179 
1180         blobmsg_add_u32(&mBuf, "PartitionId", leaderData.mPartitionId);
1181         blobmsg_add_u32(&mBuf, "Weighting", leaderData.mWeighting);
1182         blobmsg_add_u32(&mBuf, "DataVersion", leaderData.mDataVersion);
1183         blobmsg_add_u32(&mBuf, "StableDataVersion", leaderData.mStableDataVersion);
1184         blobmsg_add_u32(&mBuf, "LeaderRouterId", leaderData.mLeaderRouterId);
1185 
1186         blobmsg_close_table(&mBuf, sJsonUri);
1187     }
1188     else if (!strcmp(aAction, "networkdata"))
1189     {
1190         ubus_send_reply(aContext, aRequest, mNetworkdataBuf.head);
1191         if (time(nullptr) - mSecond > 10)
1192         {
1193             static constexpr uint16_t kMaxTlvs = 35;
1194 
1195             struct otIp6Address address;
1196             uint8_t             tlvTypes[kMaxTlvs];
1197             uint8_t             count             = 0;
1198             char                multicastAddr[10] = "ff03::2";
1199 
1200             blob_buf_init(&mNetworkdataBuf, 0);
1201 
1202             SuccessOrExit(error = otIp6AddressFromString(multicastAddr, &address));
1203 
1204             tlvTypes[count++] = static_cast<uint8_t>(OT_NETWORK_DIAGNOSTIC_TLV_ROUTE);
1205             tlvTypes[count++] = static_cast<uint8_t>(OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE);
1206 
1207             sBufNum = 0;
1208             otThreadSendDiagnosticGet(mController->GetInstance(), &address, tlvTypes, count,
1209                                       &UbusServer::HandleDiagnosticGetResponse, this);
1210             mSecond = time(nullptr);
1211         }
1212         goto exit;
1213     }
1214     else if (!strcmp(aAction, "joinernum"))
1215     {
1216         void        *jsonTable = nullptr;
1217         void        *jsonArray = nullptr;
1218         otJoinerInfo joinerInfo;
1219         uint16_t     iterator        = 0;
1220         int          joinerNum       = 0;
1221         char         eui64[EXTPANID] = "";
1222 
1223         blob_buf_init(&mBuf, 0);
1224 
1225         jsonArray = blobmsg_open_array(&mBuf, "joinerList");
1226         while (otCommissionerGetNextJoinerInfo(mController->GetInstance(), &iterator, &joinerInfo) == OT_ERROR_NONE)
1227         {
1228             memset(eui64, 0, sizeof(eui64));
1229 
1230             jsonTable = blobmsg_open_table(&mBuf, nullptr);
1231 
1232             blobmsg_add_string(&mBuf, "pskd", joinerInfo.mPskd.m8);
1233 
1234             switch (joinerInfo.mType)
1235             {
1236             case OT_JOINER_INFO_TYPE_ANY:
1237                 blobmsg_add_u16(&mBuf, "isAny", 1);
1238                 break;
1239             case OT_JOINER_INFO_TYPE_EUI64:
1240                 blobmsg_add_u16(&mBuf, "isAny", 0);
1241                 OutputBytes(joinerInfo.mSharedId.mEui64.m8, sizeof(joinerInfo.mSharedId.mEui64.m8), eui64);
1242                 blobmsg_add_string(&mBuf, "eui64", eui64);
1243                 break;
1244             case OT_JOINER_INFO_TYPE_DISCERNER:
1245                 blobmsg_add_u16(&mBuf, "isAny", 0);
1246                 blobmsg_add_u64(&mBuf, "discernerValue", joinerInfo.mSharedId.mDiscerner.mValue);
1247                 blobmsg_add_u16(&mBuf, "discernerLength", joinerInfo.mSharedId.mDiscerner.mLength);
1248                 break;
1249             }
1250 
1251             blobmsg_close_table(&mBuf, jsonTable);
1252 
1253             joinerNum++;
1254         }
1255         blobmsg_close_array(&mBuf, jsonArray);
1256 
1257         blobmsg_add_u32(&mBuf, "joinernum", joinerNum);
1258     }
1259     else if (!strcmp(aAction, "macfilterstate"))
1260     {
1261         otMacFilterAddressMode mode = otLinkFilterGetAddressMode(mController->GetInstance());
1262 
1263         blob_buf_init(&mBuf, 0);
1264 
1265         if (mode == OT_MAC_FILTER_ADDRESS_MODE_DISABLED)
1266         {
1267             blobmsg_add_string(&mBuf, "state", "disable");
1268         }
1269         else if (mode == OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST)
1270         {
1271             blobmsg_add_string(&mBuf, "state", "allowlist");
1272         }
1273         else if (mode == OT_MAC_FILTER_ADDRESS_MODE_DENYLIST)
1274         {
1275             blobmsg_add_string(&mBuf, "state", "denylist");
1276         }
1277         else
1278         {
1279             blobmsg_add_string(&mBuf, "state", "error");
1280         }
1281     }
1282     else if (!strcmp(aAction, "macfilteraddr"))
1283     {
1284         otMacFilterEntry    entry;
1285         otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
1286 
1287         blob_buf_init(&mBuf, 0);
1288 
1289         sJsonUri = blobmsg_open_array(&mBuf, "addrlist");
1290 
1291         while (otLinkFilterGetNextAddress(mController->GetInstance(), &iterator, &entry) == OT_ERROR_NONE)
1292         {
1293             char extAddress[XPANID_LENGTH] = "";
1294             OutputBytes(entry.mExtAddress.m8, sizeof(entry.mExtAddress.m8), extAddress);
1295             blobmsg_add_string(&mBuf, "addr", extAddress);
1296         }
1297 
1298         blobmsg_close_array(&mBuf, sJsonUri);
1299     }
1300     else
1301     {
1302         perror("invalid argument in get information ubus\n");
1303     }
1304 
1305     AppendResult(error, aContext, aRequest);
1306 exit:
1307     mNcpThreadMutex->unlock();
1308     return 0;
1309 }
1310 
HandleDiagnosticGetResponse(otError aError,otMessage * aMessage,const otMessageInfo * aMessageInfo,void * aContext)1311 void UbusServer::HandleDiagnosticGetResponse(otError              aError,
1312                                              otMessage           *aMessage,
1313                                              const otMessageInfo *aMessageInfo,
1314                                              void                *aContext)
1315 {
1316     static_cast<UbusServer *>(aContext)->HandleDiagnosticGetResponse(aError, aMessage, aMessageInfo);
1317 }
1318 
IsRoutingLocator(const otIp6Address * aAddress)1319 static bool IsRoutingLocator(const otIp6Address *aAddress)
1320 {
1321     enum
1322     {
1323         kAloc16Mask            = 0xfc, ///< The mask for Aloc16.
1324         kRloc16ReservedBitMask = 0x02, ///< The mask for the reserved bit of Rloc16.
1325     };
1326 
1327     return (aAddress->mFields.m32[2] == htonl(0x000000ff) && aAddress->mFields.m16[6] == htons(0xfe00) &&
1328             aAddress->mFields.m8[14] < kAloc16Mask && (aAddress->mFields.m8[14] & kRloc16ReservedBitMask) == 0);
1329 }
1330 
HandleDiagnosticGetResponse(otError aError,otMessage * aMessage,const otMessageInfo * aMessageInfo)1331 void UbusServer::HandleDiagnosticGetResponse(otError aError, otMessage *aMessage, const otMessageInfo *aMessageInfo)
1332 {
1333     uint16_t              rloc16;
1334     uint16_t              sockRloc16 = 0;
1335     void                 *jsonArray  = nullptr;
1336     void                 *jsonItem   = nullptr;
1337     char                  xrloc[10];
1338     otNetworkDiagTlv      diagTlv;
1339     otNetworkDiagIterator iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT;
1340 
1341     SuccessOrExit(aError);
1342 
1343     char networkdata[20];
1344     sprintf(networkdata, "networkdata%d", sBufNum);
1345     sJsonUri = blobmsg_open_table(&mNetworkdataBuf, networkdata);
1346     sBufNum++;
1347 
1348     if (IsRoutingLocator(&aMessageInfo->mSockAddr))
1349     {
1350         sockRloc16 = ntohs(aMessageInfo->mPeerAddr.mFields.m16[7]);
1351         sprintf(xrloc, "0x%04x", sockRloc16);
1352         blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1353     }
1354 
1355     while (otThreadGetNextDiagnosticTlv(aMessage, &iterator, &diagTlv) == OT_ERROR_NONE)
1356     {
1357         switch (diagTlv.mType)
1358         {
1359         case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE:
1360         {
1361             const otNetworkDiagRoute &route = diagTlv.mData.mRoute;
1362 
1363             jsonArray = blobmsg_open_array(&mNetworkdataBuf, "routedata");
1364 
1365             for (uint16_t i = 0; i < route.mRouteCount; ++i)
1366             {
1367                 uint8_t in, out;
1368                 in  = route.mRouteData[i].mLinkQualityIn;
1369                 out = route.mRouteData[i].mLinkQualityOut;
1370                 if (in != 0 && out != 0)
1371                 {
1372                     jsonItem = blobmsg_open_table(&mNetworkdataBuf, "router");
1373                     rloc16   = route.mRouteData[i].mRouterId << 10;
1374                     blobmsg_add_u32(&mNetworkdataBuf, "routerid", route.mRouteData[i].mRouterId);
1375                     sprintf(xrloc, "0x%04x", rloc16);
1376                     blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1377                     blobmsg_close_table(&mNetworkdataBuf, jsonItem);
1378                 }
1379             }
1380             blobmsg_close_array(&mNetworkdataBuf, jsonArray);
1381             break;
1382         }
1383 
1384         case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE:
1385         {
1386             jsonArray = blobmsg_open_array(&mNetworkdataBuf, "childdata");
1387             for (uint16_t i = 0; i < diagTlv.mData.mChildTable.mCount; ++i)
1388             {
1389                 enum
1390                 {
1391                     kModeRxOnWhenIdle     = 1 << 3, ///< If the device has its receiver on when not transmitting.
1392                     kModeFullThreadDevice = 1 << 1, ///< If the device is an FTD.
1393                     kModeFullNetworkData  = 1 << 0, ///< If the device requires the full Network Data.
1394                 };
1395                 const otNetworkDiagChildEntry &entry = diagTlv.mData.mChildTable.mTable[i];
1396 
1397                 uint8_t mode = 0;
1398 
1399                 jsonItem = blobmsg_open_table(&mNetworkdataBuf, "child");
1400                 sprintf(xrloc, "0x%04x", (sockRloc16 | entry.mChildId));
1401                 blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1402 
1403                 mode = (entry.mMode.mRxOnWhenIdle ? kModeRxOnWhenIdle : 0) |
1404                        (entry.mMode.mDeviceType ? kModeFullThreadDevice : 0) |
1405                        (entry.mMode.mNetworkData ? kModeFullNetworkData : 0);
1406                 blobmsg_add_u16(&mNetworkdataBuf, "mode", mode);
1407                 blobmsg_close_table(&mNetworkdataBuf, jsonItem);
1408             }
1409             blobmsg_close_array(&mNetworkdataBuf, jsonArray);
1410             break;
1411         }
1412 
1413         default:
1414             // Ignore other network diagnostics data.
1415             break;
1416         }
1417     }
1418 
1419     blobmsg_close_table(&mNetworkdataBuf, sJsonUri);
1420 
1421 exit:
1422     if (aError != OT_ERROR_NONE)
1423     {
1424         otbrLogWarning("Failed to receive diagnostic response: %s", otThreadErrorToString(aError));
1425     }
1426 }
1427 
UbusSetInformation(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg,const char * aAction)1428 int UbusServer::UbusSetInformation(struct ubus_context      *aContext,
1429                                    struct ubus_object       *aObj,
1430                                    struct ubus_request_data *aRequest,
1431                                    const char               *aMethod,
1432                                    struct blob_attr         *aMsg,
1433                                    const char               *aAction)
1434 {
1435     OT_UNUSED_VARIABLE(aObj);
1436     OT_UNUSED_VARIABLE(aMethod);
1437     OT_UNUSED_VARIABLE(aMsg);
1438 
1439     otError error = OT_ERROR_NONE;
1440 
1441     blob_buf_init(&mBuf, 0);
1442 
1443     mNcpThreadMutex->lock();
1444     if (!strcmp(aAction, "networkname"))
1445     {
1446         struct blob_attr *tb[SET_NETWORK_MAX];
1447 
1448         blobmsg_parse(setNetworknamePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1449         if (tb[SETNETWORK] != nullptr)
1450         {
1451             char *newName = blobmsg_get_string(tb[SETNETWORK]);
1452             SuccessOrExit(error = otThreadSetNetworkName(mController->GetInstance(), newName));
1453         }
1454     }
1455     else if (!strcmp(aAction, "channel"))
1456     {
1457         struct blob_attr *tb[SET_NETWORK_MAX];
1458 
1459         blobmsg_parse(setChannelPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1460         if (tb[SETNETWORK] != nullptr)
1461         {
1462             uint32_t channel = blobmsg_get_u32(tb[SETNETWORK]);
1463             SuccessOrExit(error = otLinkSetChannel(mController->GetInstance(), static_cast<uint8_t>(channel)));
1464         }
1465     }
1466     else if (!strcmp(aAction, "panid"))
1467     {
1468         struct blob_attr *tb[SET_NETWORK_MAX];
1469 
1470         blobmsg_parse(setPanIdPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1471         if (tb[SETNETWORK] != nullptr)
1472         {
1473             long  value;
1474             char *panid = blobmsg_get_string(tb[SETNETWORK]);
1475             SuccessOrExit(error = ParseLong(panid, value));
1476             error = otLinkSetPanId(mController->GetInstance(), static_cast<otPanId>(value));
1477         }
1478     }
1479     else if (!strcmp(aAction, "networkkey"))
1480     {
1481         struct blob_attr *tb[SET_NETWORK_MAX];
1482 
1483         blobmsg_parse(setNetworkkeyPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1484         if (tb[SETNETWORK] != nullptr)
1485         {
1486             otNetworkKey key;
1487             char        *networkkey = blobmsg_get_string(tb[SETNETWORK]);
1488 
1489             VerifyOrExit(Hex2Bin(networkkey, key.m8, sizeof(key.m8)) == OT_NETWORK_KEY_SIZE, error = OT_ERROR_PARSE);
1490             SuccessOrExit(error = otThreadSetNetworkKey(mController->GetInstance(), &key));
1491         }
1492     }
1493     else if (!strcmp(aAction, "pskc"))
1494     {
1495         struct blob_attr *tb[SET_NETWORK_MAX];
1496 
1497         blobmsg_parse(setPskcPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1498         if (tb[SETNETWORK] != nullptr)
1499         {
1500             otPskc pskc;
1501 
1502             VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[SETNETWORK]), pskc.m8, sizeof(pskc)) == OT_PSKC_MAX_SIZE,
1503                          error = OT_ERROR_PARSE);
1504             SuccessOrExit(error = otThreadSetPskc(mController->GetInstance(), &pskc));
1505         }
1506     }
1507     else if (!strcmp(aAction, "extpanid"))
1508     {
1509         struct blob_attr *tb[SET_NETWORK_MAX];
1510 
1511         blobmsg_parse(setExtPanIdPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1512         if (tb[SETNETWORK] != nullptr)
1513         {
1514             otExtendedPanId extPanId;
1515             char           *input = blobmsg_get_string(tb[SETNETWORK]);
1516             VerifyOrExit(Hex2Bin(input, extPanId.m8, sizeof(extPanId)) >= 0, error = OT_ERROR_PARSE);
1517             error = otThreadSetExtendedPanId(mController->GetInstance(), &extPanId);
1518         }
1519     }
1520     else if (!strcmp(aAction, "mode"))
1521     {
1522         otLinkModeConfig  linkMode;
1523         struct blob_attr *tb[SET_NETWORK_MAX];
1524 
1525         blobmsg_parse(setModePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1526         if (tb[SETNETWORK] != nullptr)
1527         {
1528             char *inputMode = blobmsg_get_string(tb[SETNETWORK]);
1529             for (char *ch = inputMode; *ch != '\0'; ch++)
1530             {
1531                 switch (*ch)
1532                 {
1533                 case 'r':
1534                     linkMode.mRxOnWhenIdle = 1;
1535                     break;
1536 
1537                 case 'd':
1538                     linkMode.mDeviceType = 1;
1539                     break;
1540 
1541                 case 'n':
1542                     linkMode.mNetworkData = 1;
1543                     break;
1544 
1545                 default:
1546                     ExitNow(error = OT_ERROR_PARSE);
1547                 }
1548             }
1549 
1550             SuccessOrExit(error = otThreadSetLinkMode(mController->GetInstance(), linkMode));
1551         }
1552     }
1553     else if (!strcmp(aAction, "macfilteradd"))
1554     {
1555         struct blob_attr *tb[SET_NETWORK_MAX];
1556         otExtAddress      extAddr;
1557 
1558         blobmsg_parse(macfilterAddPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1559         if (tb[SETNETWORK] != nullptr)
1560         {
1561             char *addr = blobmsg_get_string(tb[SETNETWORK]);
1562 
1563             VerifyOrExit(Hex2Bin(addr, extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE, error = OT_ERROR_PARSE);
1564 
1565             error = otLinkFilterAddAddress(mController->GetInstance(), &extAddr);
1566 
1567             VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY);
1568         }
1569     }
1570     else if (!strcmp(aAction, "macfilterremove"))
1571     {
1572         struct blob_attr *tb[SET_NETWORK_MAX];
1573         otExtAddress      extAddr;
1574 
1575         blobmsg_parse(macfilterRemovePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1576         if (tb[SETNETWORK] != nullptr)
1577         {
1578             char *addr = blobmsg_get_string(tb[SETNETWORK]);
1579             VerifyOrExit(Hex2Bin(addr, extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE, error = OT_ERROR_PARSE);
1580 
1581             otLinkFilterRemoveAddress(mController->GetInstance(), &extAddr);
1582         }
1583     }
1584     else if (!strcmp(aAction, "macfiltersetstate"))
1585     {
1586         struct blob_attr *tb[SET_NETWORK_MAX];
1587 
1588         blobmsg_parse(macfilterSetStatePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1589         if (tb[SETNETWORK] != nullptr)
1590         {
1591             char *state = blobmsg_get_string(tb[SETNETWORK]);
1592 
1593             if (strcmp(state, "disable") == 0)
1594             {
1595                 otLinkFilterSetAddressMode(mController->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_DISABLED);
1596             }
1597             else if (strcmp(state, "allowlist") == 0)
1598             {
1599                 otLinkFilterSetAddressMode(mController->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST);
1600             }
1601             else if (strcmp(state, "denylist") == 0)
1602             {
1603                 otLinkFilterSetAddressMode(mController->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_DENYLIST);
1604             }
1605         }
1606     }
1607     else if (!strcmp(aAction, "macfilterclear"))
1608     {
1609         otLinkFilterClearAddresses(mController->GetInstance());
1610     }
1611     else
1612     {
1613         perror("invalid argument in get information ubus\n");
1614     }
1615 
1616 exit:
1617     mNcpThreadMutex->unlock();
1618     AppendResult(error, aContext, aRequest);
1619     return 0;
1620 }
1621 
GetState(otInstance * aInstance,char * aState)1622 void UbusServer::GetState(otInstance *aInstance, char *aState)
1623 {
1624     switch (otThreadGetDeviceRole(aInstance))
1625     {
1626     case OT_DEVICE_ROLE_DISABLED:
1627         strcpy(aState, "disabled");
1628         break;
1629 
1630     case OT_DEVICE_ROLE_DETACHED:
1631         strcpy(aState, "detached");
1632         break;
1633 
1634     case OT_DEVICE_ROLE_CHILD:
1635         strcpy(aState, "child");
1636         break;
1637 
1638     case OT_DEVICE_ROLE_ROUTER:
1639         strcpy(aState, "router");
1640         break;
1641 
1642     case OT_DEVICE_ROLE_LEADER:
1643         strcpy(aState, "leader");
1644         break;
1645     default:
1646         strcpy(aState, "invalid aState");
1647         break;
1648     }
1649 }
1650 
UbusAddFd()1651 void UbusServer::UbusAddFd()
1652 {
1653     // ubus library function
1654     ubus_add_uloop(mContext);
1655 
1656 #ifdef FD_CLOEXEC
1657     fcntl(mContext->sock.fd, F_SETFD, fcntl(mContext->sock.fd, F_GETFD) | FD_CLOEXEC);
1658 #endif
1659 }
1660 
UbusReconnTimer(struct uloop_timeout * aTimeout)1661 void UbusServer::UbusReconnTimer(struct uloop_timeout *aTimeout)
1662 {
1663     GetInstance().UbusReconnTimerDetail(aTimeout);
1664 }
1665 
UbusReconnTimerDetail(struct uloop_timeout * aTimeout)1666 void UbusServer::UbusReconnTimerDetail(struct uloop_timeout *aTimeout)
1667 {
1668     OT_UNUSED_VARIABLE(aTimeout);
1669 
1670     static struct uloop_timeout retry = {
1671         list : {},
1672         pending : false,
1673         cb : UbusReconnTimer,
1674         time : {},
1675     };
1676     int time = 2;
1677 
1678     if (ubus_reconnect(mContext, mSockPath) != 0)
1679     {
1680         uloop_timeout_set(&retry, time * 1000);
1681         return;
1682     }
1683 
1684     UbusAddFd();
1685 }
1686 
UbusConnectionLost(struct ubus_context * aContext)1687 void UbusServer::UbusConnectionLost(struct ubus_context *aContext)
1688 {
1689     OT_UNUSED_VARIABLE(aContext);
1690 
1691     UbusReconnTimer(nullptr);
1692 }
1693 
DisplayUbusInit(const char * aPath)1694 int UbusServer::DisplayUbusInit(const char *aPath)
1695 {
1696     uloop_init();
1697     signal(SIGPIPE, SIG_IGN);
1698 
1699     mSockPath = aPath;
1700 
1701     mContext = ubus_connect(aPath);
1702     if (!mContext)
1703     {
1704         otbrLogErr("Ubus connect failed");
1705         return -1;
1706     }
1707 
1708     otbrLogInfo("Connected as %08x\n", mContext->local_id);
1709     mContext->connection_lost = UbusConnectionLost;
1710 
1711     /* file description */
1712     UbusAddFd();
1713 
1714     /* Add a object */
1715     if (ubus_add_object(mContext, &otbr) != 0)
1716     {
1717         otbrLogErr("Ubus add obj failed");
1718         return -1;
1719     }
1720 
1721     return 0;
1722 }
1723 
DisplayUbusDone(void)1724 void UbusServer::DisplayUbusDone(void)
1725 {
1726     if (mContext)
1727     {
1728         ubus_free(mContext);
1729         mContext = nullptr;
1730     }
1731 }
1732 
InstallUbusObject(void)1733 void UbusServer::InstallUbusObject(void)
1734 {
1735     char *path = nullptr;
1736 
1737     if (-1 == DisplayUbusInit(path))
1738     {
1739         otbrLogErr("Ubus connect failed");
1740         return;
1741     }
1742 
1743     otbrLogInfo("Uloop run");
1744     uloop_run();
1745 
1746     DisplayUbusDone();
1747 
1748     uloop_done();
1749 }
1750 
ParseLong(char * aString,long & aLong)1751 otError UbusServer::ParseLong(char *aString, long &aLong)
1752 {
1753     char *endptr;
1754     aLong = strtol(aString, &endptr, 0);
1755     return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
1756 }
1757 
Hex2Bin(const char * aHex,uint8_t * aBin,uint16_t aBinLength)1758 int UbusServer::Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength)
1759 {
1760     size_t      hexLength = strlen(aHex);
1761     const char *hexEnd    = aHex + hexLength;
1762     uint8_t    *cur       = aBin;
1763     uint8_t     numChars  = hexLength & 1;
1764     uint8_t     byte      = 0;
1765     int         rval;
1766 
1767     VerifyOrExit((hexLength + 1) / 2 <= aBinLength, rval = -1);
1768 
1769     while (aHex < hexEnd)
1770     {
1771         if ('A' <= *aHex && *aHex <= 'F')
1772         {
1773             byte |= 10 + (*aHex - 'A');
1774         }
1775         else if ('a' <= *aHex && *aHex <= 'f')
1776         {
1777             byte |= 10 + (*aHex - 'a');
1778         }
1779         else if ('0' <= *aHex && *aHex <= '9')
1780         {
1781             byte |= *aHex - '0';
1782         }
1783         else
1784         {
1785             ExitNow(rval = -1);
1786         }
1787 
1788         aHex++;
1789         numChars++;
1790 
1791         if (numChars >= 2)
1792         {
1793             numChars = 0;
1794             *cur++   = byte;
1795             byte     = 0;
1796         }
1797         else
1798         {
1799             byte <<= 4;
1800         }
1801     }
1802 
1803     rval = static_cast<int>(cur - aBin);
1804 
1805 exit:
1806     return rval;
1807 }
1808 
Init(void)1809 void UBusAgent::Init(void)
1810 {
1811     otbr::ubus::sUbusEfd = eventfd(0, 0);
1812 
1813     otbr::ubus::UbusServer::Initialize(&mNcp, &mThreadMutex);
1814 
1815     if (otbr::ubus::sUbusEfd == -1)
1816     {
1817         perror("Failed to create eventfd for ubus");
1818         exit(EXIT_FAILURE);
1819     }
1820 
1821     std::thread(UbusServerRun).detach();
1822 }
1823 
Update(MainloopContext & aMainloop)1824 void UBusAgent::Update(MainloopContext &aMainloop)
1825 {
1826     VerifyOrExit(otbr::ubus::sUbusEfd != -1);
1827 
1828     FD_SET(otbr::ubus::sUbusEfd, &aMainloop.mReadFdSet);
1829 
1830     if (aMainloop.mMaxFd < otbr::ubus::sUbusEfd)
1831     {
1832         aMainloop.mMaxFd = otbr::ubus::sUbusEfd;
1833     }
1834 
1835 exit:
1836     mThreadMutex.unlock();
1837     return;
1838 }
1839 
Process(const MainloopContext & aMainloop)1840 void UBusAgent::Process(const MainloopContext &aMainloop)
1841 {
1842     ssize_t  retval;
1843     uint64_t num;
1844 
1845     mThreadMutex.lock();
1846 
1847     VerifyOrExit(otbr::ubus::sUbusEfd != -1);
1848 
1849     if (FD_ISSET(otbr::ubus::sUbusEfd, &aMainloop.mReadFdSet))
1850     {
1851         retval = read(otbr::ubus::sUbusEfd, &num, sizeof(uint64_t));
1852         if (retval != sizeof(uint64_t))
1853         {
1854             perror("read ubus eventfd failed\n");
1855             exit(EXIT_FAILURE);
1856         }
1857     }
1858 
1859 exit:
1860     return;
1861 }
1862 
1863 } // namespace ubus
1864 } // namespace otbr
1865