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