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