2 * Copyright (c) 2019, The OpenThread Authors.
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.
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.
29 #if __ORDER_BIG_ENDIAN__
30 #define BYTE_ORDER_BIG_ENDIAN 1
33 #include "openwrt/ubus/otubus.hpp"
37 #include <sys/eventfd.h>
39 #include <openthread/commissioner.h>
40 #include <openthread/thread.h>
41 #include <openthread/thread_ftd.h>
43 #include "agent/ncp_openthread.hpp"
44 #include "common/logging.hpp"
49 static UbusServer *sUbusServerInstance = nullptr;
50 static int sUbusEfd = -1;
51 static void * sJsonUri = nullptr;
53 static std::mutex *sNcpThreadMutex;
55 const static int PANID_LENGTH = 10;
56 const static int XPANID_LENGTH = 64;
57 const static int MASTERKEY_LENGTH = 64;
59 UbusServer::UbusServer(Ncp::ControllerOpenThread *aController)
60 : mIfFinishScan(false)
63 , mController(aController)
66 memset(&mNetworkdataBuf, 0, sizeof(mNetworkdataBuf));
67 memset(&mBuf, 0, sizeof(mBuf));
69 blob_buf_init(&mBuf, 0);
70 blob_buf_init(&mNetworkdataBuf, 0);
73 UbusServer &UbusServer::GetInstance(void)
75 return *sUbusServerInstance;
78 void UbusServer::Initialize(Ncp::ControllerOpenThread *aController)
80 sUbusServerInstance = new UbusServer(aController);
107 static const struct blobmsg_policy setNetworknamePolicy[SET_NETWORK_MAX] = {
108 [SETNETWORK] = {.name = "networkname", .type = BLOBMSG_TYPE_STRING},
111 static const struct blobmsg_policy setPanIdPolicy[SET_NETWORK_MAX] = {
112 [SETNETWORK] = {.name = "panid", .type = BLOBMSG_TYPE_STRING},
115 static const struct blobmsg_policy setExtPanIdPolicy[SET_NETWORK_MAX] = {
116 [SETNETWORK] = {.name = "extpanid", .type = BLOBMSG_TYPE_STRING},
119 static const struct blobmsg_policy setChannelPolicy[SET_NETWORK_MAX] = {
120 [SETNETWORK] = {.name = "channel", .type = BLOBMSG_TYPE_INT32},
123 static const struct blobmsg_policy setPskcPolicy[SET_NETWORK_MAX] = {
124 [SETNETWORK] = {.name = "pskc", .type = BLOBMSG_TYPE_STRING},
127 static const struct blobmsg_policy setMasterkeyPolicy[SET_NETWORK_MAX] = {
128 [SETNETWORK] = {.name = "masterkey", .type = BLOBMSG_TYPE_STRING},
131 static const struct blobmsg_policy setModePolicy[SET_NETWORK_MAX] = {
132 [SETNETWORK] = {.name = "mode", .type = BLOBMSG_TYPE_STRING},
135 static const struct blobmsg_policy macfilterAddPolicy[SET_NETWORK_MAX] = {
136 [SETNETWORK] = {.name = "addr", .type = BLOBMSG_TYPE_STRING},
139 static const struct blobmsg_policy macfilterRemovePolicy[SET_NETWORK_MAX] = {
140 [SETNETWORK] = {.name = "addr", .type = BLOBMSG_TYPE_STRING},
143 static const struct blobmsg_policy macfilterSetStatePolicy[SET_NETWORK_MAX] = {
144 [SETNETWORK] = {.name = "state", .type = BLOBMSG_TYPE_STRING},
147 static const struct blobmsg_policy removeJoinerPolicy[SET_NETWORK_MAX] = {
148 [SETNETWORK] = {.name = "eui64", .type = BLOBMSG_TYPE_STRING},
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},
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},
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)},
207 static struct ubus_object_type otbrObjType = {"otbr_prog", 0, otbrMethods, ARRAY_SIZE(otbrMethods)};
209 static struct ubus_object otbr = {
215 subscribe_cb : nullptr,
216 has_subscribers : false,
217 methods : otbrMethods,
218 n_methods : ARRAY_SIZE(otbrMethods),
221 void UbusServer::ProcessScan(void)
223 otError error = OT_ERROR_NONE;
224 uint32_t scanChannels = 0;
225 uint16_t scanDuration = 0;
227 sNcpThreadMutex->lock();
228 SuccessOrExit(error = otLinkActiveScan(mController->GetInstance(), scanChannels, scanDuration,
229 &UbusServer::HandleActiveScanResult, this));
231 sNcpThreadMutex->unlock();
235 void UbusServer::HandleActiveScanResult(otActiveScanResult *aResult, void *aContext)
237 static_cast<UbusServer *>(aContext)->HandleActiveScanResultDetail(aResult);
240 void UbusServer::OutputBytes(const uint8_t *aBytes, uint8_t aLength, char *aOutput)
242 char byte2char[5] = "";
243 for (int i = 0; i < aLength; i++)
245 sprintf(byte2char, "%02x", aBytes[i]);
246 strcat(aOutput, byte2char);
250 void UbusServer::AppendResult(otError aError, struct ubus_context *aContext, struct ubus_request_data *aRequest)
252 blobmsg_add_u16(&mBuf, "Error", aError);
253 ubus_send_reply(aContext, aRequest, mBuf.head);
256 void UbusServer::HandleActiveScanResultDetail(otActiveScanResult *aResult)
258 void *jsonList = nullptr;
260 char panidstring[PANID_LENGTH];
261 char xpanidstring[XPANID_LENGTH] = "";
263 if (aResult == nullptr)
265 blobmsg_close_array(&mBuf, sJsonUri);
266 mIfFinishScan = true;
270 jsonList = blobmsg_open_table(&mBuf, nullptr);
272 blobmsg_add_u32(&mBuf, "IsJoinable", aResult->mIsJoinable);
274 blobmsg_add_string(&mBuf, "NetworkName", aResult->mNetworkName.m8);
276 OutputBytes(aResult->mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE, xpanidstring);
277 blobmsg_add_string(&mBuf, "ExtendedPanId", xpanidstring);
279 sprintf(panidstring, "0x%04x", aResult->mPanId);
280 blobmsg_add_string(&mBuf, "PanId", panidstring);
282 blobmsg_add_u32(&mBuf, "Channel", aResult->mChannel);
284 blobmsg_add_u32(&mBuf, "Rssi", aResult->mRssi);
286 blobmsg_add_u32(&mBuf, "Lqi", aResult->mLqi);
288 blobmsg_close_table(&mBuf, jsonList);
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)
300 return GetInstance().UbusScanHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
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)
309 OT_UNUSED_VARIABLE(aObj);
310 OT_UNUSED_VARIABLE(aMethod);
311 OT_UNUSED_VARIABLE(aMsg);
313 otError error = OT_ERROR_NONE;
317 blob_buf_init(&mBuf, 0);
318 sJsonUri = blobmsg_open_array(&mBuf, "scan_list");
321 sUbusServerInstance->ProcessScan();
324 retval = write(sUbusEfd, &eventNum, sizeof(uint64_t));
325 if (retval != sizeof(uint64_t))
327 error = OT_ERROR_FAILED;
331 while (!mIfFinishScan)
337 AppendResult(error, aContext, aRequest);
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)
347 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "channel");
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)
356 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "channel");
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)
365 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "joinernum");
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)
374 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkname");
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)
383 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkname");
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)
392 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "state");
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)
401 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "rloc16");
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)
410 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "panid");
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)
419 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "panid");
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)
428 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "extpanid");
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)
437 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "extpanid");
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)
446 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "pskc");
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)
455 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "pskc");
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)
464 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "masterkey");
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)
473 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "masterkey");
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)
482 return GetInstance().UbusThreadHandler(aContext, aObj, aRequest, aMethod, aMsg, "start");
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)
491 return GetInstance().UbusThreadHandler(aContext, aObj, aRequest, aMethod, aMsg, "stop");
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)
500 return GetInstance().UbusParentHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
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)
509 return GetInstance().UbusNeighborHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
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)
518 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "mode");
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)
527 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "mode");
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)
536 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "partitionid");
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)
545 return GetInstance().UbusLeaveHandlerDetail(aContext, aObj, aRequest, aMethod, aMsg);
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)
554 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "leaderdata");
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)
563 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "networkdata");
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)
572 return GetInstance().UbusCommissioner(aContext, aObj, aRequest, aMethod, aMsg, "start");
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)
581 return GetInstance().UbusCommissioner(aContext, aObj, aRequest, aMethod, aMsg, "joinerremove");
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)
590 return GetInstance().UbusMgmtset(aContext, aObj, aRequest, aMethod, aMsg);
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)
599 return GetInstance().UbusCommissioner(aContext, aObj, aRequest, aMethod, aMsg, "joineradd");
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)
608 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilteraddr");
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)
617 return GetInstance().UbusGetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilterstate");
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)
626 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilteradd");
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)
635 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilterremove");
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)
644 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfiltersetstate");
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)
653 return GetInstance().UbusSetInformation(aContext, aObj, aRequest, aMethod, aMsg, "macfilterclear");
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)
662 OT_UNUSED_VARIABLE(aObj);
663 OT_UNUSED_VARIABLE(aMethod);
664 OT_UNUSED_VARIABLE(aMsg);
666 otError error = OT_ERROR_NONE;
670 sNcpThreadMutex->lock();
671 otInstanceFactoryReset(mController->GetInstance());
674 retval = write(sUbusEfd, &eventNum, sizeof(uint64_t));
675 if (retval != sizeof(uint64_t))
677 error = OT_ERROR_FAILED;
681 blob_buf_init(&mBuf, 0);
684 sNcpThreadMutex->unlock();
685 AppendResult(error, aContext, aRequest);
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)
695 OT_UNUSED_VARIABLE(aObj);
696 OT_UNUSED_VARIABLE(aMethod);
697 OT_UNUSED_VARIABLE(aMsg);
699 otError error = OT_ERROR_NONE;
701 blob_buf_init(&mBuf, 0);
703 if (!strcmp(aAction, "start"))
705 sNcpThreadMutex->lock();
706 SuccessOrExit(error = otIp6SetEnabled(mController->GetInstance(), true));
707 SuccessOrExit(error = otThreadSetEnabled(mController->GetInstance(), true));
709 else if (!strcmp(aAction, "stop"))
711 sNcpThreadMutex->lock();
712 SuccessOrExit(error = otThreadSetEnabled(mController->GetInstance(), false));
713 SuccessOrExit(error = otIp6SetEnabled(mController->GetInstance(), false));
717 sNcpThreadMutex->unlock();
718 AppendResult(error, aContext, aRequest);
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)
728 OT_UNUSED_VARIABLE(aObj);
729 OT_UNUSED_VARIABLE(aMethod);
730 OT_UNUSED_VARIABLE(aMsg);
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;
739 blob_buf_init(&mBuf, 0);
741 sNcpThreadMutex->lock();
742 SuccessOrExit(error = otThreadGetParentInfo(mController->GetInstance(), &parentInfo));
744 jsonArray = blobmsg_open_array(&mBuf, "parent_list");
745 jsonList = blobmsg_open_table(&mBuf, "parent");
746 blobmsg_add_string(&mBuf, "Role", "R");
748 sprintf(transfer, "0x%04x", parentInfo.mRloc16);
749 blobmsg_add_string(&mBuf, "Rloc16", transfer);
751 sprintf(transfer, "%3d", parentInfo.mAge);
752 blobmsg_add_string(&mBuf, "Age", transfer);
754 OutputBytes(parentInfo.mExtAddress.m8, sizeof(parentInfo.mExtAddress.m8), extAddress);
755 blobmsg_add_string(&mBuf, "ExtAddress", extAddress);
757 blobmsg_add_u16(&mBuf, "LinkQualityIn", parentInfo.mLinkQualityIn);
759 blobmsg_close_table(&mBuf, jsonList);
760 blobmsg_close_array(&mBuf, jsonArray);
763 sNcpThreadMutex->unlock();
764 AppendResult(error, aContext, aRequest);
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)
774 OT_UNUSED_VARIABLE(aObj);
775 OT_UNUSED_VARIABLE(aMethod);
776 OT_UNUSED_VARIABLE(aMsg);
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;
784 char extAddress[XPANID_LENGTH] = "";
786 blob_buf_init(&mBuf, 0);
788 sJsonUri = blobmsg_open_array(&mBuf, "neighbor_list");
790 sNcpThreadMutex->lock();
791 while (otThreadGetNextNeighborInfo(mController->GetInstance(), &iterator, &neighborInfo) == OT_ERROR_NONE)
793 jsonList = blobmsg_open_table(&mBuf, nullptr);
795 blobmsg_add_string(&mBuf, "Role", neighborInfo.mIsChild ? "C" : "R");
797 sprintf(transfer, "0x%04x", neighborInfo.mRloc16);
798 blobmsg_add_string(&mBuf, "Rloc16", transfer);
800 sprintf(transfer, "%3d", neighborInfo.mAge);
801 blobmsg_add_string(&mBuf, "Age", transfer);
803 sprintf(transfer, "%8d", neighborInfo.mAverageRssi);
804 blobmsg_add_string(&mBuf, "AvgRssi", transfer);
806 sprintf(transfer, "%9d", neighborInfo.mLastRssi);
807 blobmsg_add_string(&mBuf, "LastRssi", transfer);
809 if (neighborInfo.mRxOnWhenIdle)
814 if (neighborInfo.mFullThreadDevice)
819 if (neighborInfo.mFullNetworkData)
823 blobmsg_add_string(&mBuf, "Mode", mode);
825 OutputBytes(neighborInfo.mExtAddress.m8, sizeof(neighborInfo.mExtAddress.m8), extAddress);
826 blobmsg_add_string(&mBuf, "ExtAddress", extAddress);
828 blobmsg_add_u16(&mBuf, "LinkQualityIn", neighborInfo.mLinkQualityIn);
830 blobmsg_close_table(&mBuf, jsonList);
832 memset(mode, 0, sizeof(mode));
833 memset(extAddress, 0, sizeof(extAddress));
836 blobmsg_close_array(&mBuf, sJsonUri);
838 sNcpThreadMutex->unlock();
840 AppendResult(error, aContext, aRequest);
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)
850 OT_UNUSED_VARIABLE(aObj);
851 OT_UNUSED_VARIABLE(aMethod);
852 OT_UNUSED_VARIABLE(aMsg);
854 otError error = OT_ERROR_NONE;
855 struct blob_attr * tb[MGMTSET_MAX];
856 otOperationalDataset dataset;
861 SuccessOrExit(error = otDatasetGetActive(mController->GetInstance(), &dataset));
863 blobmsg_parse(mgmtsetPolicy, MGMTSET_MAX, tb, blob_data(aMsg), blob_len(aMsg));
864 if (tb[MASTERKEY] != nullptr)
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);
872 if (tb[NETWORKNAME] != nullptr)
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));
882 if (tb[EXTPANID] != nullptr)
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);
889 if (tb[PANID] != nullptr)
891 dataset.mComponents.mIsPanIdPresent = true;
892 SuccessOrExit(error = ParseLong(blobmsg_get_string(tb[PANID]), value));
893 dataset.mPanId = static_cast<otPanId>(value);
895 if (tb[CHANNEL] != nullptr)
897 dataset.mComponents.mIsChannelPresent = true;
898 SuccessOrExit(error = ParseLong(blobmsg_get_string(tb[CHANNEL]), value));
899 dataset.mChannel = static_cast<uint16_t>(value);
901 if (tb[PSKC] != nullptr)
903 dataset.mComponents.mIsPskcPresent = true;
904 VerifyOrExit((length = Hex2Bin(blobmsg_get_string(tb[PSKC]), dataset.mPskc.m8, sizeof(dataset.mPskc.m8))) ==
906 error = OT_ERROR_PARSE);
909 dataset.mActiveTimestamp++;
910 if (otCommissionerGetState(mController->GetInstance()) == OT_COMMISSIONER_STATE_DISABLED)
912 otCommissionerStop(mController->GetInstance());
915 error = otDatasetSendMgmtActiveSet(mController->GetInstance(), &dataset, tlvs, static_cast<uint8_t>(length)));
917 AppendResult(error, aContext, aRequest);
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)
928 OT_UNUSED_VARIABLE(aObj);
929 OT_UNUSED_VARIABLE(aMethod);
930 OT_UNUSED_VARIABLE(aMsg);
932 otError error = OT_ERROR_NONE;
934 sNcpThreadMutex->lock();
936 if (!strcmp(aAction, "start"))
938 if (otCommissionerGetState(mController->GetInstance()) == OT_COMMISSIONER_STATE_DISABLED)
940 error = otCommissionerStart(mController->GetInstance(), &UbusServer::HandleStateChanged,
941 &UbusServer::HandleJoinerEvent, this);
944 else if (!strcmp(aAction, "joineradd"))
946 struct blob_attr * tb[ADD_JOINER_MAX];
948 const otExtAddress *addrPtr = nullptr;
949 char * pskd = nullptr;
951 blobmsg_parse(addJoinerPolicy, ADD_JOINER_MAX, tb, blob_data(aMsg), blob_len(aMsg));
952 if (tb[PSKD] != nullptr)
954 pskd = blobmsg_get_string(tb[PSKD]);
956 if (tb[EUI64] != nullptr)
958 if (!strcmp(blobmsg_get_string(tb[EUI64]), "*"))
961 memset(&addr, 0, sizeof(addr));
965 VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[EUI64]), addr.m8, sizeof(addr)) == sizeof(addr),
966 error = OT_ERROR_PARSE);
971 unsigned long timeout = kDefaultJoinerTimeout;
973 error = otCommissionerAddJoiner(mController->GetInstance(), addrPtr, pskd, static_cast<uint32_t>(timeout)));
975 else if (!strcmp(aAction, "joinerremove"))
977 struct blob_attr * tb[SET_NETWORK_MAX];
979 const otExtAddress *addrPtr = nullptr;
981 blobmsg_parse(removeJoinerPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
982 if (tb[SETNETWORK] != nullptr)
984 if (strcmp(blobmsg_get_string(tb[SETNETWORK]), "*") == 0)
990 VerifyOrExit(Hex2Bin(blobmsg_get_string(tb[SETNETWORK]), addr.m8, sizeof(addr)) == sizeof(addr),
991 error = OT_ERROR_PARSE);
996 SuccessOrExit(error = otCommissionerRemoveJoiner(mController->GetInstance(), addrPtr));
1000 sNcpThreadMutex->unlock();
1001 blob_buf_init(&mBuf, 0);
1002 AppendResult(error, aContext, aRequest);
1006 void UbusServer::HandleStateChanged(otCommissionerState aState, void *aContext)
1008 static_cast<UbusServer *>(aContext)->HandleStateChanged(aState);
1011 void UbusServer::HandleStateChanged(otCommissionerState aState)
1015 case OT_COMMISSIONER_STATE_DISABLED:
1016 otbrLog(OTBR_LOG_INFO, "commissioner state disabled");
1018 case OT_COMMISSIONER_STATE_ACTIVE:
1019 otbrLog(OTBR_LOG_INFO, "commissioner state active");
1021 case OT_COMMISSIONER_STATE_PETITION:
1022 otbrLog(OTBR_LOG_INFO, "commissioner state petition");
1027 void UbusServer::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
1028 const otJoinerInfo * aJoinerInfo,
1029 const otExtAddress * aJoinerId,
1032 static_cast<UbusServer *>(aContext)->HandleJoinerEvent(aEvent, aJoinerInfo, aJoinerId);
1035 void UbusServer::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
1036 const otJoinerInfo * aJoinerInfo,
1037 const otExtAddress * aJoinerId)
1039 OT_UNUSED_VARIABLE(aJoinerInfo);
1040 OT_UNUSED_VARIABLE(aJoinerId);
1044 case OT_COMMISSIONER_JOINER_START:
1045 otbrLog(OTBR_LOG_INFO, "joiner start");
1047 case OT_COMMISSIONER_JOINER_CONNECTED:
1048 otbrLog(OTBR_LOG_INFO, "joiner connected");
1050 case OT_COMMISSIONER_JOINER_FINALIZE:
1051 otbrLog(OTBR_LOG_INFO, "joiner finalize");
1053 case OT_COMMISSIONER_JOINER_END:
1054 otbrLog(OTBR_LOG_INFO, "joiner end");
1056 case OT_COMMISSIONER_JOINER_REMOVED:
1057 otbrLog(OTBR_LOG_INFO, "joiner remove");
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)
1069 OT_UNUSED_VARIABLE(aObj);
1070 OT_UNUSED_VARIABLE(aMethod);
1071 OT_UNUSED_VARIABLE(aMsg);
1073 otError error = OT_ERROR_NONE;
1075 blob_buf_init(&mBuf, 0);
1077 sNcpThreadMutex->lock();
1078 if (!strcmp(aAction, "networkname"))
1079 blobmsg_add_string(&mBuf, "NetworkName", otThreadGetNetworkName(mController->GetInstance()));
1080 else if (!strcmp(aAction, "state"))
1083 GetState(mController->GetInstance(), state);
1084 blobmsg_add_string(&mBuf, "State", state);
1086 else if (!strcmp(aAction, "channel"))
1087 blobmsg_add_u32(&mBuf, "Channel", otLinkGetChannel(mController->GetInstance()));
1088 else if (!strcmp(aAction, "panid"))
1090 char panIdString[PANID_LENGTH];
1091 sprintf(panIdString, "0x%04x", otLinkGetPanId(mController->GetInstance()));
1092 blobmsg_add_string(&mBuf, "PanId", panIdString);
1094 else if (!strcmp(aAction, "rloc16"))
1096 char rloc[PANID_LENGTH];
1097 sprintf(rloc, "0x%04x", otThreadGetRloc16(mController->GetInstance()));
1098 blobmsg_add_string(&mBuf, "rloc16", rloc);
1100 else if (!strcmp(aAction, "masterkey"))
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);
1107 else if (!strcmp(aAction, "pskc"))
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);
1114 else if (!strcmp(aAction, "extpanid"))
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);
1122 else if (!strcmp(aAction, "mode"))
1124 otLinkModeConfig linkMode;
1127 memset(&linkMode, 0, sizeof(otLinkModeConfig));
1129 linkMode = otThreadGetLinkMode(mController->GetInstance());
1131 if (linkMode.mRxOnWhenIdle)
1136 if (linkMode.mDeviceType)
1141 if (linkMode.mNetworkData)
1145 blobmsg_add_string(&mBuf, "Mode", mode);
1147 else if (!strcmp(aAction, "partitionid"))
1149 blobmsg_add_u32(&mBuf, "Partitionid", otThreadGetPartitionId(mController->GetInstance()));
1151 else if (!strcmp(aAction, "leaderdata"))
1153 otLeaderData leaderData;
1155 SuccessOrExit(error = otThreadGetLeaderData(mController->GetInstance(), &leaderData));
1157 sJsonUri = blobmsg_open_table(&mBuf, "leaderdata");
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);
1165 blobmsg_close_table(&mBuf, sJsonUri);
1167 else if (!strcmp(aAction, "networkdata"))
1169 ubus_send_reply(aContext, aRequest, mNetworkdataBuf.head);
1170 if (time(nullptr) - mSecond > 10)
1172 struct otIp6Address address;
1173 uint8_t tlvTypes[OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES];
1175 char multicastAddr[10] = "ff03::2";
1177 blob_buf_init(&mNetworkdataBuf, 0);
1179 SuccessOrExit(error = otIp6AddressFromString(multicastAddr, &address));
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);
1185 otThreadSendDiagnosticGet(mController->GetInstance(), &address, tlvTypes, count,
1186 &UbusServer::HandleDiagnosticGetResponse, this);
1187 mSecond = time(nullptr);
1191 else if (!strcmp(aAction, "joinernum"))
1193 void * jsonTable = nullptr;
1194 void * jsonArray = nullptr;
1195 otJoinerInfo joinerInfo;
1196 uint16_t iterator = 0;
1198 char eui64[EXTPANID] = "";
1200 blob_buf_init(&mBuf, 0);
1202 jsonArray = blobmsg_open_array(&mBuf, "joinerList");
1203 while (otCommissionerGetNextJoinerInfo(mController->GetInstance(), &iterator, &joinerInfo) == OT_ERROR_NONE)
1205 memset(eui64, 0, sizeof(eui64));
1207 jsonTable = blobmsg_open_table(&mBuf, nullptr);
1209 blobmsg_add_string(&mBuf, "pskd", joinerInfo.mPskd.m8);
1211 switch (joinerInfo.mType)
1213 case OT_JOINER_INFO_TYPE_ANY:
1214 blobmsg_add_u16(&mBuf, "isAny", 1);
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);
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);
1228 blobmsg_close_table(&mBuf, jsonTable);
1232 blobmsg_close_array(&mBuf, jsonArray);
1234 blobmsg_add_u32(&mBuf, "joinernum", joinerNum);
1236 else if (!strcmp(aAction, "macfilterstate"))
1238 otMacFilterAddressMode mode = otLinkFilterGetAddressMode(mController->GetInstance());
1240 blob_buf_init(&mBuf, 0);
1242 if (mode == OT_MAC_FILTER_ADDRESS_MODE_DISABLED)
1244 blobmsg_add_string(&mBuf, "state", "disable");
1246 else if (mode == OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST)
1248 blobmsg_add_string(&mBuf, "state", "allowlist");
1250 else if (mode == OT_MAC_FILTER_ADDRESS_MODE_DENYLIST)
1252 blobmsg_add_string(&mBuf, "state", "denylist");
1256 blobmsg_add_string(&mBuf, "state", "error");
1259 else if (!strcmp(aAction, "macfilteraddr"))
1261 otMacFilterEntry entry;
1262 otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
1264 blob_buf_init(&mBuf, 0);
1266 sJsonUri = blobmsg_open_array(&mBuf, "addrlist");
1268 while (otLinkFilterGetNextAddress(mController->GetInstance(), &iterator, &entry) == OT_ERROR_NONE)
1270 char extAddress[XPANID_LENGTH] = "";
1271 OutputBytes(entry.mExtAddress.m8, sizeof(entry.mExtAddress.m8), extAddress);
1272 blobmsg_add_string(&mBuf, "addr", extAddress);
1275 blobmsg_close_array(&mBuf, sJsonUri);
1279 perror("invalid argument in get information ubus\n");
1282 AppendResult(error, aContext, aRequest);
1284 sNcpThreadMutex->unlock();
1288 void UbusServer::HandleDiagnosticGetResponse(otError aError,
1289 otMessage * aMessage,
1290 const otMessageInfo *aMessageInfo,
1293 static_cast<UbusServer *>(aContext)->HandleDiagnosticGetResponse(aError, aMessage, aMessageInfo);
1296 static bool IsRoutingLocator(const otIp6Address *aAddress)
1300 kAloc16Mask = 0xfc, ///< The mask for Aloc16.
1301 kRloc16ReservedBitMask = 0x02, ///< The mask for the reserved bit of Rloc16.
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);
1308 void UbusServer::HandleDiagnosticGetResponse(otError aError, otMessage *aMessage, const otMessageInfo *aMessageInfo)
1311 uint16_t sockRloc16 = 0;
1312 void * jsonArray = nullptr;
1313 void * jsonItem = nullptr;
1315 otNetworkDiagTlv diagTlv;
1316 otNetworkDiagIterator iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT;
1318 SuccessOrExit(aError);
1320 char networkdata[20];
1321 sprintf(networkdata, "networkdata%d", sBufNum);
1322 sJsonUri = blobmsg_open_table(&mNetworkdataBuf, networkdata);
1325 if (IsRoutingLocator(&aMessageInfo->mSockAddr))
1327 sockRloc16 = ntohs(aMessageInfo->mPeerAddr.mFields.m16[7]);
1328 sprintf(xrloc, "0x%04x", sockRloc16);
1329 blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
1332 while (otThreadGetNextDiagnosticTlv(aMessage, &iterator, &diagTlv) == OT_ERROR_NONE)
1334 switch (diagTlv.mType)
1336 case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE:
1338 const otNetworkDiagRoute &route = diagTlv.mData.mRoute;
1340 jsonArray = blobmsg_open_array(&mNetworkdataBuf, "routedata");
1342 for (uint16_t i = 0; i < route.mRouteCount; ++i)
1345 in = route.mRouteData[i].mLinkQualityIn;
1346 out = route.mRouteData[i].mLinkQualityOut;
1347 if (in != 0 && out != 0)
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);
1357 blobmsg_close_array(&mNetworkdataBuf, jsonArray);
1361 case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE:
1363 jsonArray = blobmsg_open_array(&mNetworkdataBuf, "childdata");
1364 for (uint16_t i = 0; i < diagTlv.mData.mChildTable.mCount; ++i)
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.
1372 const otNetworkDiagChildEntry &entry = diagTlv.mData.mChildTable.mTable[i];
1376 jsonItem = blobmsg_open_table(&mNetworkdataBuf, "child");
1377 sprintf(xrloc, "0x%04x", (sockRloc16 | entry.mChildId));
1378 blobmsg_add_string(&mNetworkdataBuf, "rloc", xrloc);
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);
1386 blobmsg_close_array(&mNetworkdataBuf, jsonArray);
1391 // Ignore other network diagnostics data.
1396 blobmsg_close_table(&mNetworkdataBuf, sJsonUri);
1399 if (aError != OT_ERROR_NONE)
1401 otbrLog(OTBR_LOG_WARNING, "failed to receive diagnostic response: %s", otThreadErrorToString(aError));
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)
1412 OT_UNUSED_VARIABLE(aObj);
1413 OT_UNUSED_VARIABLE(aMethod);
1414 OT_UNUSED_VARIABLE(aMsg);
1416 otError error = OT_ERROR_NONE;
1418 blob_buf_init(&mBuf, 0);
1420 sNcpThreadMutex->lock();
1421 if (!strcmp(aAction, "networkname"))
1423 struct blob_attr *tb[SET_NETWORK_MAX];
1425 blobmsg_parse(setNetworknamePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1426 if (tb[SETNETWORK] != nullptr)
1428 char *newName = blobmsg_get_string(tb[SETNETWORK]);
1429 SuccessOrExit(error = otThreadSetNetworkName(mController->GetInstance(), newName));
1432 else if (!strcmp(aAction, "channel"))
1434 struct blob_attr *tb[SET_NETWORK_MAX];
1436 blobmsg_parse(setChannelPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1437 if (tb[SETNETWORK] != nullptr)
1439 uint32_t channel = blobmsg_get_u32(tb[SETNETWORK]);
1440 SuccessOrExit(error = otLinkSetChannel(mController->GetInstance(), static_cast<uint8_t>(channel)));
1443 else if (!strcmp(aAction, "panid"))
1445 struct blob_attr *tb[SET_NETWORK_MAX];
1447 blobmsg_parse(setPanIdPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1448 if (tb[SETNETWORK] != nullptr)
1451 char *panid = blobmsg_get_string(tb[SETNETWORK]);
1452 SuccessOrExit(error = ParseLong(panid, value));
1453 error = otLinkSetPanId(mController->GetInstance(), static_cast<otPanId>(value));
1456 else if (!strcmp(aAction, "masterkey"))
1458 struct blob_attr *tb[SET_NETWORK_MAX];
1460 blobmsg_parse(setMasterkeyPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1461 if (tb[SETNETWORK] != nullptr)
1464 char * masterkey = blobmsg_get_string(tb[SETNETWORK]);
1466 VerifyOrExit(Hex2Bin(masterkey, key.m8, sizeof(key.m8)) == OT_MASTER_KEY_SIZE, error = OT_ERROR_PARSE);
1467 SuccessOrExit(error = otThreadSetMasterKey(mController->GetInstance(), &key));
1470 else if (!strcmp(aAction, "pskc"))
1472 struct blob_attr *tb[SET_NETWORK_MAX];
1474 blobmsg_parse(setPskcPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1475 if (tb[SETNETWORK] != nullptr)
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));
1484 else if (!strcmp(aAction, "extpanid"))
1486 struct blob_attr *tb[SET_NETWORK_MAX];
1488 blobmsg_parse(setExtPanIdPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1489 if (tb[SETNETWORK] != nullptr)
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);
1497 else if (!strcmp(aAction, "mode"))
1499 otLinkModeConfig linkMode;
1500 struct blob_attr *tb[SET_NETWORK_MAX];
1502 blobmsg_parse(setModePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1503 if (tb[SETNETWORK] != nullptr)
1505 char *inputMode = blobmsg_get_string(tb[SETNETWORK]);
1506 for (char *ch = inputMode; *ch != '\0'; ch++)
1511 linkMode.mRxOnWhenIdle = 1;
1515 linkMode.mDeviceType = 1;
1519 linkMode.mNetworkData = 1;
1523 ExitNow(error = OT_ERROR_PARSE);
1527 SuccessOrExit(error = otThreadSetLinkMode(mController->GetInstance(), linkMode));
1530 else if (!strcmp(aAction, "macfilteradd"))
1532 struct blob_attr *tb[SET_NETWORK_MAX];
1533 otExtAddress extAddr;
1535 blobmsg_parse(macfilterAddPolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1536 if (tb[SETNETWORK] != nullptr)
1538 char *addr = blobmsg_get_string(tb[SETNETWORK]);
1540 VerifyOrExit(Hex2Bin(addr, extAddr.m8, OT_EXT_ADDRESS_SIZE) == OT_EXT_ADDRESS_SIZE, error = OT_ERROR_PARSE);
1542 error = otLinkFilterAddAddress(mController->GetInstance(), &extAddr);
1544 VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY);
1547 else if (!strcmp(aAction, "macfilterremove"))
1549 struct blob_attr *tb[SET_NETWORK_MAX];
1550 otExtAddress extAddr;
1552 blobmsg_parse(macfilterRemovePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1553 if (tb[SETNETWORK] != nullptr)
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);
1558 otLinkFilterRemoveAddress(mController->GetInstance(), &extAddr);
1561 else if (!strcmp(aAction, "macfiltersetstate"))
1563 struct blob_attr *tb[SET_NETWORK_MAX];
1565 blobmsg_parse(macfilterSetStatePolicy, SET_NETWORK_MAX, tb, blob_data(aMsg), blob_len(aMsg));
1566 if (tb[SETNETWORK] != nullptr)
1568 char *state = blobmsg_get_string(tb[SETNETWORK]);
1570 if (strcmp(state, "disable") == 0)
1572 otLinkFilterSetAddressMode(mController->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_DISABLED);
1574 else if (strcmp(state, "allowlist") == 0)
1576 otLinkFilterSetAddressMode(mController->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST);
1578 else if (strcmp(state, "denylist") == 0)
1580 otLinkFilterSetAddressMode(mController->GetInstance(), OT_MAC_FILTER_ADDRESS_MODE_DENYLIST);
1584 else if (!strcmp(aAction, "macfilterclear"))
1586 otLinkFilterClearAddresses(mController->GetInstance());
1590 perror("invalid argument in get information ubus\n");
1594 sNcpThreadMutex->unlock();
1595 AppendResult(error, aContext, aRequest);
1599 void UbusServer::GetState(otInstance *aInstance, char *aState)
1601 switch (otThreadGetDeviceRole(aInstance))
1603 case OT_DEVICE_ROLE_DISABLED:
1604 strcpy(aState, "disabled");
1607 case OT_DEVICE_ROLE_DETACHED:
1608 strcpy(aState, "detached");
1611 case OT_DEVICE_ROLE_CHILD:
1612 strcpy(aState, "child");
1615 case OT_DEVICE_ROLE_ROUTER:
1616 strcpy(aState, "router");
1619 case OT_DEVICE_ROLE_LEADER:
1620 strcpy(aState, "leader");
1623 strcpy(aState, "invalid aState");
1628 void UbusServer::UbusAddFd()
1630 // ubus library function
1631 ubus_add_uloop(mContext);
1634 fcntl(mContext->sock.fd, F_SETFD, fcntl(mContext->sock.fd, F_GETFD) | FD_CLOEXEC);
1638 void UbusServer::UbusReconnTimer(struct uloop_timeout *aTimeout)
1640 GetInstance().UbusReconnTimerDetail(aTimeout);
1643 void UbusServer::UbusReconnTimerDetail(struct uloop_timeout *aTimeout)
1645 OT_UNUSED_VARIABLE(aTimeout);
1647 static struct uloop_timeout retry = {
1650 cb : UbusReconnTimer,
1655 if (ubus_reconnect(mContext, mSockPath) != 0)
1657 uloop_timeout_set(&retry, time * 1000);
1664 void UbusServer::UbusConnectionLost(struct ubus_context *aContext)
1666 OT_UNUSED_VARIABLE(aContext);
1668 UbusReconnTimer(nullptr);
1671 int UbusServer::DisplayUbusInit(const char *aPath)
1674 signal(SIGPIPE, SIG_IGN);
1678 mContext = ubus_connect(aPath);
1681 otbrLog(OTBR_LOG_ERR, "ubus connect failed");
1685 otbrLog(OTBR_LOG_INFO, "connected as %08x\n", mContext->local_id);
1686 mContext->connection_lost = UbusConnectionLost;
1688 /* file description */
1692 if (ubus_add_object(mContext, &otbr) != 0)
1694 otbrLog(OTBR_LOG_ERR, "ubus add obj failed");
1701 void UbusServer::DisplayUbusDone(void)
1705 ubus_free(mContext);
1710 void UbusServer::InstallUbusObject(void)
1712 char *path = nullptr;
1714 if (-1 == DisplayUbusInit(path))
1716 otbrLog(OTBR_LOG_ERR, "ubus connect failed");
1720 otbrLog(OTBR_LOG_INFO, "uloop run");
1728 otError UbusServer::ParseLong(char *aString, long &aLong)
1731 aLong = strtol(aString, &endptr, 0);
1732 return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
1735 int UbusServer::Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength)
1737 size_t hexLength = strlen(aHex);
1738 const char *hexEnd = aHex + hexLength;
1739 uint8_t * cur = aBin;
1740 uint8_t numChars = hexLength & 1;
1744 VerifyOrExit((hexLength + 1) / 2 <= aBinLength, rval = -1);
1746 while (aHex < hexEnd)
1748 if ('A' <= *aHex && *aHex <= 'F')
1750 byte |= 10 + (*aHex - 'A');
1752 else if ('a' <= *aHex && *aHex <= 'f')
1754 byte |= 10 + (*aHex - 'a');
1756 else if ('0' <= *aHex && *aHex <= '9')
1758 byte |= *aHex - '0';
1780 rval = static_cast<int>(cur - aBin);
1789 void UbusServerInit(otbr::Ncp::ControllerOpenThread *aController, std::mutex *aNcpThreadMutex)
1791 otbr::ubus::sNcpThreadMutex = aNcpThreadMutex;
1792 otbr::ubus::sUbusEfd = eventfd(0, 0);
1794 otbr::ubus::UbusServer::Initialize(aController);
1796 if (otbr::ubus::sUbusEfd == -1)
1798 perror("Failed to create eventfd for ubus");
1803 void UbusServerRun(void)
1805 otbr::ubus::UbusServer::GetInstance().InstallUbusObject();
1808 void UbusUpdateFdSet(fd_set &aReadFdSet, int &aMaxFd)
1810 VerifyOrExit(otbr::ubus::sUbusEfd != -1);
1812 FD_SET(otbr::ubus::sUbusEfd, &aReadFdSet);
1814 if (aMaxFd < otbr::ubus::sUbusEfd)
1816 aMaxFd = otbr::ubus::sUbusEfd;
1823 void UbusProcess(const fd_set &aReadFdSet)
1828 VerifyOrExit(otbr::ubus::sUbusEfd != -1);
1830 if (FD_ISSET(otbr::ubus::sUbusEfd, &aReadFdSet))
1832 retval = read(otbr::ubus::sUbusEfd, &num, sizeof(uint64_t));
1833 if (retval != sizeof(uint64_t))
1835 perror("read ubus eventfd failed\n");