xref: /aosp_15_r20/external/ot-br-posix/src/openwrt/ubus/otubus.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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/rcp_host.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::RcpHost * aHost,std::mutex * aMutex)61 UbusServer::UbusServer(Ncp::RcpHost *aHost, std::mutex *aMutex)
62     : mIfFinishScan(false)
63     , mContext(nullptr)
64     , mSockPath(nullptr)
65     , mHost(aHost)
66     , mHostMutex(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::RcpHost * aHost,std::mutex * aMutex)81 void UbusServer::Initialize(Ncp::RcpHost *aHost, std::mutex *aMutex)
82 {
83     sUbusServerInstance = new UbusServer(aHost, 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     mHostMutex->lock();
233     SuccessOrExit(error = otLinkActiveScan(mHost->GetInstance(), scanChannels, scanDuration,
234                                            &UbusServer::HandleActiveScanResult, this));
235 exit:
236     mHostMutex->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     mHostMutex->lock();
683     otInstanceFactoryReset(mHost->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     mHostMutex->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         mHostMutex->lock();
718         SuccessOrExit(error = otIp6SetEnabled(mHost->GetInstance(), true));
719         SuccessOrExit(error = otThreadSetEnabled(mHost->GetInstance(), true));
720     }
721     else if (!strcmp(aAction, "stop"))
722     {
723         mHostMutex->lock();
724         SuccessOrExit(error = otThreadSetEnabled(mHost->GetInstance(), false));
725         SuccessOrExit(error = otIp6SetEnabled(mHost->GetInstance(), false));
726     }
727 
728 exit:
729     mHostMutex->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     mHostMutex->lock();
754     SuccessOrExit(error = otThreadGetParentInfo(mHost->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     mHostMutex->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     mHostMutex->lock();
803     while (otThreadGetNextNeighborInfo(mHost->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     mHostMutex->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(mHost->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(mHost->GetInstance()) == OT_COMMISSIONER_STATE_DISABLED)
923     {
924         otCommissionerStop(mHost->GetInstance());
925     }
926     SuccessOrExit(error = otDatasetSendMgmtActiveSet(mHost->GetInstance(), &dataset, tlvs, static_cast<uint8_t>(length),
927                                                      /* 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     mHostMutex->lock();
948 
949     if (!strcmp(aAction, "start"))
950     {
951         if (otCommissionerGetState(mHost->GetInstance()) == OT_COMMISSIONER_STATE_DISABLED)
952         {
953             error = otCommissionerStart(mHost->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(error =
986                           otCommissionerAddJoiner(mHost->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(mHost->GetInstance(), addrPtr));
1010     }
1011 
1012 exit:
1013     mHostMutex->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     mHostMutex->lock();
1091     if (!strcmp(aAction, "networkname"))
1092         blobmsg_add_string(&mBuf, "NetworkName", otThreadGetNetworkName(mHost->GetInstance()));
1093     else if (!strcmp(aAction, "interfacename"))
1094     {
1095         blobmsg_add_string(&mBuf, "InterfaceName", mHost->GetInterfaceName());
1096     }
1097     else if (!strcmp(aAction, "state"))
1098     {
1099         char state[10];
1100         GetState(mHost->GetInstance(), state);
1101         blobmsg_add_string(&mBuf, "State", state);
1102     }
1103     else if (!strcmp(aAction, "channel"))
1104         blobmsg_add_u32(&mBuf, "Channel", otLinkGetChannel(mHost->GetInstance()));
1105     else if (!strcmp(aAction, "panid"))
1106     {
1107         char panIdString[PANID_LENGTH];
1108         sprintf(panIdString, "0x%04x", otLinkGetPanId(mHost->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(mHost->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(mHost->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(mHost->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 = reinterpret_cast<const uint8_t *>(otThreadGetExtendedPanId(mHost->GetInstance()));
1139         OutputBytes(extPanId, OT_EXT_PAN_ID_SIZE, outputExtPanId);
1140         blobmsg_add_string(&mBuf, "ExtPanId", outputExtPanId);
1141     }
1142     else if (!strcmp(aAction, "mode"))
1143     {
1144         otLinkModeConfig linkMode;
1145         char             mode[5] = "";
1146 
1147         memset(&linkMode, 0, sizeof(otLinkModeConfig));
1148 
1149         linkMode = otThreadGetLinkMode(mHost->GetInstance());
1150 
1151         if (linkMode.mRxOnWhenIdle)
1152         {
1153             strcat(mode, "r");
1154         }
1155 
1156         if (linkMode.mDeviceType)
1157         {
1158             strcat(mode, "d");
1159         }
1160 
1161         if (linkMode.mNetworkData)
1162         {
1163             strcat(mode, "n");
1164         }
1165         blobmsg_add_string(&mBuf, "Mode", mode);
1166     }
1167     else if (!strcmp(aAction, "partitionid"))
1168     {
1169         blobmsg_add_u32(&mBuf, "Partitionid", otThreadGetPartitionId(mHost->GetInstance()));
1170     }
1171     else if (!strcmp(aAction, "leaderdata"))
1172     {
1173         otLeaderData leaderData;
1174 
1175         SuccessOrExit(error = otThreadGetLeaderData(mHost->GetInstance(), &leaderData));
1176 
1177         sJsonUri = blobmsg_open_table(&mBuf, "leaderdata");
1178 
1179         blobmsg_add_u32(&mBuf, "PartitionId", leaderData.mPartitionId);
1180         blobmsg_add_u32(&mBuf, "Weighting", leaderData.mWeighting);
1181         blobmsg_add_u32(&mBuf, "DataVersion", leaderData.mDataVersion);
1182         blobmsg_add_u32(&mBuf, "StableDataVersion", leaderData.mStableDataVersion);
1183         blobmsg_add_u32(&mBuf, "LeaderRouterId", leaderData.mLeaderRouterId);
1184 
1185         blobmsg_close_table(&mBuf, sJsonUri);
1186     }
1187     else if (!strcmp(aAction, "networkdata"))
1188     {
1189         ubus_send_reply(aContext, aRequest, mNetworkdataBuf.head);
1190         if (time(nullptr) - mSecond > 10)
1191         {
1192             static constexpr uint16_t kMaxTlvs = 35;
1193 
1194             struct otIp6Address address;
1195             uint8_t             tlvTypes[kMaxTlvs];
1196             uint8_t             count             = 0;
1197             char                multicastAddr[10] = "ff03::2";
1198 
1199             blob_buf_init(&mNetworkdataBuf, 0);
1200 
1201             SuccessOrExit(error = otIp6AddressFromString(multicastAddr, &address));
1202 
1203             tlvTypes[count++] = static_cast<uint8_t>(OT_NETWORK_DIAGNOSTIC_TLV_ROUTE);
1204             tlvTypes[count++] = static_cast<uint8_t>(OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE);
1205 
1206             sBufNum = 0;
1207             otThreadSendDiagnosticGet(mHost->GetInstance(), &address, tlvTypes, count,
1208                                       &UbusServer::HandleDiagnosticGetResponse, this);
1209             mSecond = time(nullptr);
1210         }
1211         goto exit;
1212     }
1213     else if (!strcmp(aAction, "joinernum"))
1214     {
1215         void        *jsonTable = nullptr;
1216         void        *jsonArray = nullptr;
1217         otJoinerInfo joinerInfo;
1218         uint16_t     iterator        = 0;
1219         int          joinerNum       = 0;
1220         char         eui64[EXTPANID] = "";
1221 
1222         blob_buf_init(&mBuf, 0);
1223 
1224         jsonArray = blobmsg_open_array(&mBuf, "joinerList");
1225         while (otCommissionerGetNextJoinerInfo(mHost->GetInstance(), &iterator, &joinerInfo) == OT_ERROR_NONE)
1226         {
1227             memset(eui64, 0, sizeof(eui64));
1228 
1229             jsonTable = blobmsg_open_table(&mBuf, nullptr);
1230 
1231             blobmsg_add_string(&mBuf, "pskd", joinerInfo.mPskd.m8);
1232 
1233             switch (joinerInfo.mType)
1234             {
1235             case OT_JOINER_INFO_TYPE_ANY:
1236                 blobmsg_add_u16(&mBuf, "isAny", 1);
1237                 break;
1238             case OT_JOINER_INFO_TYPE_EUI64:
1239                 blobmsg_add_u16(&mBuf, "isAny", 0);
1240                 OutputBytes(joinerInfo.mSharedId.mEui64.m8, sizeof(joinerInfo.mSharedId.mEui64.m8), eui64);
1241                 blobmsg_add_string(&mBuf, "eui64", eui64);
1242                 break;
1243             case OT_JOINER_INFO_TYPE_DISCERNER:
1244                 blobmsg_add_u16(&mBuf, "isAny", 0);
1245                 blobmsg_add_u64(&mBuf, "discernerValue", joinerInfo.mSharedId.mDiscerner.mValue);
1246                 blobmsg_add_u16(&mBuf, "discernerLength", joinerInfo.mSharedId.mDiscerner.mLength);
1247                 break;
1248             }
1249 
1250             blobmsg_close_table(&mBuf, jsonTable);
1251 
1252             joinerNum++;
1253         }
1254         blobmsg_close_array(&mBuf, jsonArray);
1255 
1256         blobmsg_add_u32(&mBuf, "joinernum", joinerNum);
1257     }
1258     else if (!strcmp(aAction, "macfilterstate"))
1259     {
1260         otMacFilterAddressMode mode = otLinkFilterGetAddressMode(mHost->GetInstance());
1261 
1262         blob_buf_init(&mBuf, 0);
1263 
1264         if (mode == OT_MAC_FILTER_ADDRESS_MODE_DISABLED)
1265         {
1266             blobmsg_add_string(&mBuf, "state", "disable");
1267         }
1268         else if (mode == OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST)
1269         {
1270             blobmsg_add_string(&mBuf, "state", "allowlist");
1271         }
1272         else if (mode == OT_MAC_FILTER_ADDRESS_MODE_DENYLIST)
1273         {
1274             blobmsg_add_string(&mBuf, "state", "denylist");
1275         }
1276         else
1277         {
1278             blobmsg_add_string(&mBuf, "state", "error");
1279         }
1280     }
1281     else if (!strcmp(aAction, "macfilteraddr"))
1282     {
1283         otMacFilterEntry    entry;
1284         otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
1285 
1286         blob_buf_init(&mBuf, 0);
1287 
1288         sJsonUri = blobmsg_open_array(&mBuf, "addrlist");
1289 
1290         while (otLinkFilterGetNextAddress(mHost->GetInstance(), &iterator, &entry) == OT_ERROR_NONE)
1291         {
1292             char extAddress[XPANID_LENGTH] = "";
1293             OutputBytes(entry.mExtAddress.m8, sizeof(entry.mExtAddress.m8), extAddress);
1294             blobmsg_add_string(&mBuf, "addr", extAddress);
1295         }
1296 
1297         blobmsg_close_array(&mBuf, sJsonUri);
1298     }
1299     else
1300     {
1301         perror("invalid argument in get information ubus\n");
1302     }
1303 
1304     AppendResult(error, aContext, aRequest);
1305 exit:
1306     mHostMutex->unlock();
1307     return 0;
1308 }
1309 
HandleDiagnosticGetResponse(otError aError,otMessage * aMessage,const otMessageInfo * aMessageInfo,void * aContext)1310 void UbusServer::HandleDiagnosticGetResponse(otError              aError,
1311                                              otMessage           *aMessage,
1312                                              const otMessageInfo *aMessageInfo,
1313                                              void                *aContext)
1314 {
1315     static_cast<UbusServer *>(aContext)->HandleDiagnosticGetResponse(aError, aMessage, aMessageInfo);
1316 }
1317 
IsRoutingLocator(const otIp6Address * aAddress)1318 static bool IsRoutingLocator(const otIp6Address *aAddress)
1319 {
1320     enum
1321     {
1322         kAloc16Mask            = 0xfc, ///< The mask for Aloc16.
1323         kRloc16ReservedBitMask = 0x02, ///< The mask for the reserved bit of Rloc16.
1324     };
1325 
1326     return (aAddress->mFields.m32[2] == htonl(0x000000ff) && aAddress->mFields.m16[6] == htons(0xfe00) &&
1327             aAddress->mFields.m8[14] < kAloc16Mask && (aAddress->mFields.m8[14] & kRloc16ReservedBitMask) == 0);
1328 }
1329 
HandleDiagnosticGetResponse(otError aError,otMessage * aMessage,const otMessageInfo * aMessageInfo)1330 void UbusServer::HandleDiagnosticGetResponse(otError aError, otMessage *aMessage, const otMessageInfo *aMessageInfo)
1331 {
1332     uint16_t              rloc16;
1333     uint16_t              sockRloc16 = 0;
1334     void                 *jsonArray  = nullptr;
1335     void                 *jsonItem   = nullptr;
1336     char                  xrloc[10];
1337     otNetworkDiagTlv      diagTlv;
1338     otNetworkDiagIterator iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT;
1339 
1340     SuccessOrExit(aError);
1341 
1342     char networkdata[20];
1343     sprintf(networkdata, "networkdata%d", sBufNum);
1344     sJsonUri = blobmsg_open_table(&mNetworkdataBuf, networkdata);
1345     sBufNum++;
1346 
1347     if (IsRoutingLocator(&aMessageInfo->mSockAddr))
1348     {
1349         sockRloc16 = ntohs(aMessageInfo->mPeerAddr.mFields.m16[7]);
1350         sprintf(xrloc, "0x%04x", sockRloc16);
1351         blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1352     }
1353 
1354     while (otThreadGetNextDiagnosticTlv(aMessage, &iterator, &diagTlv) == OT_ERROR_NONE)
1355     {
1356         switch (diagTlv.mType)
1357         {
1358         case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE:
1359         {
1360             const otNetworkDiagRoute &route = diagTlv.mData.mRoute;
1361 
1362             jsonArray = blobmsg_open_array(&mNetworkdataBuf, "routedata");
1363 
1364             for (uint16_t i = 0; i < route.mRouteCount; ++i)
1365             {
1366                 uint8_t in, out;
1367                 in  = route.mRouteData[i].mLinkQualityIn;
1368                 out = route.mRouteData[i].mLinkQualityOut;
1369                 if (in != 0 && out != 0)
1370                 {
1371                     jsonItem = blobmsg_open_table(&mNetworkdataBuf, "router");
1372                     rloc16   = route.mRouteData[i].mRouterId << 10;
1373                     blobmsg_add_u32(&mNetworkdataBuf, "routerid", route.mRouteData[i].mRouterId);
1374                     sprintf(xrloc, "0x%04x", rloc16);
1375                     blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1376                     blobmsg_close_table(&mNetworkdataBuf, jsonItem);
1377                 }
1378             }
1379             blobmsg_close_array(&mNetworkdataBuf, jsonArray);
1380             break;
1381         }
1382 
1383         case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE:
1384         {
1385             jsonArray = blobmsg_open_array(&mNetworkdataBuf, "childdata");
1386             for (uint16_t i = 0; i < diagTlv.mData.mChildTable.mCount; ++i)
1387             {
1388                 enum
1389                 {
1390                     kModeRxOnWhenIdle     = 1 << 3, ///< If the device has its receiver on when not transmitting.
1391                     kModeFullThreadDevice = 1 << 1, ///< If the device is an FTD.
1392                     kModeFullNetworkData  = 1 << 0, ///< If the device requires the full Network Data.
1393                 };
1394                 const otNetworkDiagChildEntry &entry = diagTlv.mData.mChildTable.mTable[i];
1395 
1396                 uint8_t mode = 0;
1397 
1398                 jsonItem = blobmsg_open_table(&mNetworkdataBuf, "child");
1399                 sprintf(xrloc, "0x%04x", (sockRloc16 | entry.mChildId));
1400                 blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1401 
1402                 mode = (entry.mMode.mRxOnWhenIdle ? kModeRxOnWhenIdle : 0) |
1403                        (entry.mMode.mDeviceType ? kModeFullThreadDevice : 0) |
1404                        (entry.mMode.mNetworkData ? kModeFullNetworkData : 0);
1405                 blobmsg_add_u16(&mNetworkdataBuf, "mode", mode);
1406                 blobmsg_close_table(&mNetworkdataBuf, jsonItem);
1407             }
1408             blobmsg_close_array(&mNetworkdataBuf, jsonArray);
1409             break;
1410         }
1411 
1412         default:
1413             // Ignore other network diagnostics data.
1414             break;
1415         }
1416     }
1417 
1418     blobmsg_close_table(&mNetworkdataBuf, sJsonUri);
1419 
1420 exit:
1421     if (aError != OT_ERROR_NONE)
1422     {
1423         otbrLogWarning("Failed to receive diagnostic response: %s", otThreadErrorToString(aError));
1424     }
1425 }
1426 
UbusSetInformation(struct ubus_context * aContext,struct ubus_object * aObj,struct ubus_request_data * aRequest,const char * aMethod,struct blob_attr * aMsg,const char * aAction)1427 int UbusServer::UbusSetInformation(struct ubus_context      *aContext,
1428                                    struct ubus_object       *aObj,
1429                                    struct ubus_request_data *aRequest,
1430                                    const char               *aMethod,
1431                                    struct blob_attr         *aMsg,
1432                                    const char               *aAction)
1433 {
1434     OT_UNUSED_VARIABLE(aObj);
1435     OT_UNUSED_VARIABLE(aMethod);
1436     OT_UNUSED_VARIABLE(aMsg);
1437 
1438     otError error = OT_ERROR_NONE;
1439 
1440     blob_buf_init(&mBuf, 0);
1441 
1442     mHostMutex->lock();
1443     if (!strcmp(aAction, "networkname"))
1444     {
1445         struct blob_attr *tb[SET_NETWORK_MAX];
1446 
1447         blobmsg_parse(setNetworknamePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1448         if (tb[SETNETWORK] != nullptr)
1449         {
1450             char *newName = blobmsg_get_string(tb[SETNETWORK]);
1451             SuccessOrExit(error = otThreadSetNetworkName(mHost->GetInstance(), newName));
1452         }
1453     }
1454     else if (!strcmp(aAction, "channel"))
1455     {
1456         struct blob_attr *tb[SET_NETWORK_MAX];
1457 
1458         blobmsg_parse(setChannelPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1459         if (tb[SETNETWORK] != nullptr)
1460         {
1461             uint32_t channel = blobmsg_get_u32(tb[SETNETWORK]);
1462             SuccessOrExit(error = otLinkSetChannel(mHost->GetInstance(), static_cast<uint8_t>(channel)));
1463         }
1464     }
1465     else if (!strcmp(aAction, "panid"))
1466     {
1467         struct blob_attr *tb[SET_NETWORK_MAX];
1468 
1469         blobmsg_parse(setPanIdPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1470         if (tb[SETNETWORK] != nullptr)
1471         {
1472             long  value;
1473             char *panid = blobmsg_get_string(tb[SETNETWORK]);
1474             SuccessOrExit(error = ParseLong(panid, value));
1475             error = otLinkSetPanId(mHost->GetInstance(), static_cast<otPanId>(value));
1476         }
1477     }
1478     else if (!strcmp(aAction, "networkkey"))
1479     {
1480         struct blob_attr *tb[SET_NETWORK_MAX];
1481 
1482         blobmsg_parse(setNetworkkeyPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1483         if (tb[SETNETWORK] != nullptr)
1484         {
1485             otNetworkKey key;
1486             char        *networkkey = blobmsg_get_string(tb[SETNETWORK]);
1487 
1488             VerifyOrExit(Hex2Bin(networkkey, key.m8, sizeof(key.m8)) == OT_NETWORK_KEY_SIZE, error = OT_ERROR_PARSE);
1489             SuccessOrExit(error = otThreadSetNetworkKey(mHost->GetInstance(), &key));
1490         }
1491     }
1492     else if (!strcmp(aAction, "pskc"))
1493     {
1494         struct blob_attr *tb[SET_NETWORK_MAX];
1495 
1496         blobmsg_parse(setPskcPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1497         if (tb[SETNETWORK] != nullptr)
1498         {
1499             otPskc pskc;
1500 
1501             VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[SETNETWORK]), pskc.m8, sizeof(pskc)) == OT_PSKC_MAX_SIZE,
1502                          error = OT_ERROR_PARSE);
1503             SuccessOrExit(error = otThreadSetPskc(mHost->GetInstance(), &pskc));
1504         }
1505     }
1506     else if (!strcmp(aAction, "extpanid"))
1507     {
1508         struct blob_attr *tb[SET_NETWORK_MAX];
1509 
1510         blobmsg_parse(setExtPanIdPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1511         if (tb[SETNETWORK] != nullptr)
1512         {
1513             otExtendedPanId extPanId;
1514             char           *input = blobmsg_get_string(tb[SETNETWORK]);
1515             VerifyOrExit(Hex2Bin(input, extPanId.m8, sizeof(extPanId)) >= 0, error = OT_ERROR_PARSE);
1516             error = otThreadSetExtendedPanId(mHost->GetInstance(), &extPanId);
1517         }
1518     }
1519     else if (!strcmp(aAction, "mode"))
1520     {
1521         otLinkModeConfig  linkMode;
1522         struct blob_attr *tb[SET_NETWORK_MAX];
1523 
1524         blobmsg_parse(setModePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1525         if (tb[SETNETWORK] != nullptr)
1526         {
1527             char *inputMode = blobmsg_get_string(tb[SETNETWORK]);
1528             for (char *ch = inputMode; *ch != '\0'; ch++)
1529             {
1530                 switch (*ch)
1531                 {
1532                 case 'r':
1533                     linkMode.mRxOnWhenIdle = 1;
1534                     break;
1535 
1536                 case 'd':
1537                     linkMode.mDeviceType = 1;
1538                     break;
1539 
1540                 case 'n':
1541                     linkMode.mNetworkData = 1;
1542                     break;
1543 
1544                 default:
1545                     ExitNow(error = OT_ERROR_PARSE);
1546                 }
1547             }
1548 
1549             SuccessOrExit(error = otThreadSetLinkMode(mHost->GetInstance(), linkMode));
1550         }
1551     }
1552     else if (!strcmp(aAction, "macfilteradd"))
1553     {
1554         struct blob_attr *tb[SET_NETWORK_MAX];
1555         otExtAddress      extAddr;
1556 
1557         blobmsg_parse(macfilterAddPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1558         if (tb[SETNETWORK] != nullptr)
1559         {
1560             char *addr = blobmsg_get_string(tb[SETNETWORK]);
1561 
1562             VerifyOrExit(Hex2Bin(addr, extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE, error = OT_ERROR_PARSE);
1563 
1564             error = otLinkFilterAddAddress(mHost->GetInstance(), &extAddr);
1565 
1566             VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY);
1567         }
1568     }
1569     else if (!strcmp(aAction, "macfilterremove"))
1570     {
1571         struct blob_attr *tb[SET_NETWORK_MAX];
1572         otExtAddress      extAddr;
1573 
1574         blobmsg_parse(macfilterRemovePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1575         if (tb[SETNETWORK] != nullptr)
1576         {
1577             char *addr = blobmsg_get_string(tb[SETNETWORK]);
1578             VerifyOrExit(Hex2Bin(addr, extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE, error = OT_ERROR_PARSE);
1579 
1580             otLinkFilterRemoveAddress(mHost->GetInstance(), &extAddr);
1581         }
1582     }
1583     else if (!strcmp(aAction, "macfiltersetstate"))
1584     {
1585         struct blob_attr *tb[SET_NETWORK_MAX];
1586 
1587         blobmsg_parse(macfilterSetStatePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1588         if (tb[SETNETWORK] != nullptr)
1589         {
1590             char *state = blobmsg_get_string(tb[SETNETWORK]);
1591 
1592             if (strcmp(state, "disable") == 0)
1593             {
1594                 otLinkFilterSetAddressMode(mHost->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_DISABLED);
1595             }
1596             else if (strcmp(state, "allowlist") == 0)
1597             {
1598                 otLinkFilterSetAddressMode(mHost->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST);
1599             }
1600             else if (strcmp(state, "denylist") == 0)
1601             {
1602                 otLinkFilterSetAddressMode(mHost->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_DENYLIST);
1603             }
1604         }
1605     }
1606     else if (!strcmp(aAction, "macfilterclear"))
1607     {
1608         otLinkFilterClearAddresses(mHost->GetInstance());
1609     }
1610     else
1611     {
1612         perror("invalid argument in get information ubus\n");
1613     }
1614 
1615 exit:
1616     mHostMutex->unlock();
1617     AppendResult(error, aContext, aRequest);
1618     return 0;
1619 }
1620 
GetState(otInstance * aInstance,char * aState)1621 void UbusServer::GetState(otInstance *aInstance, char *aState)
1622 {
1623     switch (otThreadGetDeviceRole(aInstance))
1624     {
1625     case OT_DEVICE_ROLE_DISABLED:
1626         strcpy(aState, "disabled");
1627         break;
1628 
1629     case OT_DEVICE_ROLE_DETACHED:
1630         strcpy(aState, "detached");
1631         break;
1632 
1633     case OT_DEVICE_ROLE_CHILD:
1634         strcpy(aState, "child");
1635         break;
1636 
1637     case OT_DEVICE_ROLE_ROUTER:
1638         strcpy(aState, "router");
1639         break;
1640 
1641     case OT_DEVICE_ROLE_LEADER:
1642         strcpy(aState, "leader");
1643         break;
1644     default:
1645         strcpy(aState, "invalid aState");
1646         break;
1647     }
1648 }
1649 
UbusAddFd()1650 void UbusServer::UbusAddFd()
1651 {
1652     // ubus library function
1653     ubus_add_uloop(mContext);
1654 
1655 #ifdef FD_CLOEXEC
1656     fcntl(mContext->sock.fd, F_SETFD, fcntl(mContext->sock.fd, F_GETFD) | FD_CLOEXEC);
1657 #endif
1658 }
1659 
UbusReconnTimer(struct uloop_timeout * aTimeout)1660 void UbusServer::UbusReconnTimer(struct uloop_timeout *aTimeout)
1661 {
1662     GetInstance().UbusReconnTimerDetail(aTimeout);
1663 }
1664 
UbusReconnTimerDetail(struct uloop_timeout * aTimeout)1665 void UbusServer::UbusReconnTimerDetail(struct uloop_timeout *aTimeout)
1666 {
1667     OT_UNUSED_VARIABLE(aTimeout);
1668 
1669     static struct uloop_timeout retry = {
1670         list : {},
1671         pending : false,
1672         cb : UbusReconnTimer,
1673         time : {},
1674     };
1675     int time = 2;
1676 
1677     if (ubus_reconnect(mContext, mSockPath) != 0)
1678     {
1679         uloop_timeout_set(&retry, time * 1000);
1680         return;
1681     }
1682 
1683     UbusAddFd();
1684 }
1685 
UbusConnectionLost(struct ubus_context * aContext)1686 void UbusServer::UbusConnectionLost(struct ubus_context *aContext)
1687 {
1688     OT_UNUSED_VARIABLE(aContext);
1689 
1690     UbusReconnTimer(nullptr);
1691 }
1692 
DisplayUbusInit(const char * aPath)1693 int UbusServer::DisplayUbusInit(const char *aPath)
1694 {
1695     uloop_init();
1696     signal(SIGPIPE, SIG_IGN);
1697 
1698     mSockPath = aPath;
1699 
1700     mContext = ubus_connect(aPath);
1701     if (!mContext)
1702     {
1703         otbrLogErr("Ubus connect failed");
1704         return -1;
1705     }
1706 
1707     otbrLogInfo("Connected as %08x\n", mContext->local_id);
1708     mContext->connection_lost = UbusConnectionLost;
1709 
1710     /* file description */
1711     UbusAddFd();
1712 
1713     /* Add a object */
1714     if (ubus_add_object(mContext, &otbr) != 0)
1715     {
1716         otbrLogErr("Ubus add obj failed");
1717         return -1;
1718     }
1719 
1720     return 0;
1721 }
1722 
DisplayUbusDone(void)1723 void UbusServer::DisplayUbusDone(void)
1724 {
1725     if (mContext)
1726     {
1727         ubus_free(mContext);
1728         mContext = nullptr;
1729     }
1730 }
1731 
InstallUbusObject(void)1732 void UbusServer::InstallUbusObject(void)
1733 {
1734     char *path = nullptr;
1735 
1736     if (-1 == DisplayUbusInit(path))
1737     {
1738         otbrLogErr("Ubus connect failed");
1739         return;
1740     }
1741 
1742     otbrLogInfo("Uloop run");
1743     uloop_run();
1744 
1745     DisplayUbusDone();
1746 
1747     uloop_done();
1748 }
1749 
ParseLong(char * aString,long & aLong)1750 otError UbusServer::ParseLong(char *aString, long &aLong)
1751 {
1752     char *endptr;
1753     aLong = strtol(aString, &endptr, 0);
1754     return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
1755 }
1756 
Hex2Bin(const char * aHex,uint8_t * aBin,uint16_t aBinLength)1757 int UbusServer::Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength)
1758 {
1759     size_t      hexLength = strlen(aHex);
1760     const char *hexEnd    = aHex + hexLength;
1761     uint8_t    *cur       = aBin;
1762     uint8_t     numChars  = hexLength & 1;
1763     uint8_t     byte      = 0;
1764     int         rval;
1765 
1766     VerifyOrExit((hexLength + 1) / 2 <= aBinLength, rval = -1);
1767 
1768     while (aHex < hexEnd)
1769     {
1770         if ('A' <= *aHex && *aHex <= 'F')
1771         {
1772             byte |= 10 + (*aHex - 'A');
1773         }
1774         else if ('a' <= *aHex && *aHex <= 'f')
1775         {
1776             byte |= 10 + (*aHex - 'a');
1777         }
1778         else if ('0' <= *aHex && *aHex <= '9')
1779         {
1780             byte |= *aHex - '0';
1781         }
1782         else
1783         {
1784             ExitNow(rval = -1);
1785         }
1786 
1787         aHex++;
1788         numChars++;
1789 
1790         if (numChars >= 2)
1791         {
1792             numChars = 0;
1793             *cur++   = byte;
1794             byte     = 0;
1795         }
1796         else
1797         {
1798             byte <<= 4;
1799         }
1800     }
1801 
1802     rval = static_cast<int>(cur - aBin);
1803 
1804 exit:
1805     return rval;
1806 }
1807 
Init(void)1808 void UBusAgent::Init(void)
1809 {
1810     otbr::ubus::sUbusEfd = eventfd(0, 0);
1811 
1812     otbr::ubus::UbusServer::Initialize(&mHost, &mThreadMutex);
1813 
1814     if (otbr::ubus::sUbusEfd == -1)
1815     {
1816         perror("Failed to create eventfd for ubus");
1817         exit(EXIT_FAILURE);
1818     }
1819 
1820     std::thread(UbusServerRun).detach();
1821 }
1822 
Update(MainloopContext & aMainloop)1823 void UBusAgent::Update(MainloopContext &aMainloop)
1824 {
1825     VerifyOrExit(otbr::ubus::sUbusEfd != -1);
1826 
1827     aMainloop.AddFdToReadSet(otbr::ubus::sUbusEfd);
1828 exit:
1829     mThreadMutex.unlock();
1830     return;
1831 }
1832 
Process(const MainloopContext & aMainloop)1833 void UBusAgent::Process(const MainloopContext &aMainloop)
1834 {
1835     ssize_t  retval;
1836     uint64_t num;
1837 
1838     mThreadMutex.lock();
1839 
1840     VerifyOrExit(otbr::ubus::sUbusEfd != -1);
1841 
1842     if (FD_ISSET(otbr::ubus::sUbusEfd, &aMainloop.mReadFdSet))
1843     {
1844         retval = read(otbr::ubus::sUbusEfd, &num, sizeof(uint64_t));
1845         if (retval != sizeof(uint64_t))
1846         {
1847             perror("read ubus eventfd failed\n");
1848             exit(EXIT_FAILURE);
1849         }
1850     }
1851 
1852 exit:
1853     return;
1854 }
1855 
1856 } // namespace ubus
1857 } // namespace otbr
1858