1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker * Copyright (c) 2017, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker * All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker *
5*4a64e381SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker *
16*4a64e381SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker */
28*4a64e381SAndroid Build Coastguard Worker
29*4a64e381SAndroid Build Coastguard Worker /**
30*4a64e381SAndroid Build Coastguard Worker * @file
31*4a64e381SAndroid Build Coastguard Worker * This file implements the wpan controller service
32*4a64e381SAndroid Build Coastguard Worker */
33*4a64e381SAndroid Build Coastguard Worker
34*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "WEB"
35*4a64e381SAndroid Build Coastguard Worker
36*4a64e381SAndroid Build Coastguard Worker #include "web/web-service/wpan_service.hpp"
37*4a64e381SAndroid Build Coastguard Worker
38*4a64e381SAndroid Build Coastguard Worker #include <sstream>
39*4a64e381SAndroid Build Coastguard Worker
40*4a64e381SAndroid Build Coastguard Worker #include <inttypes.h>
41*4a64e381SAndroid Build Coastguard Worker #include <stdio.h>
42*4a64e381SAndroid Build Coastguard Worker #include <unistd.h>
43*4a64e381SAndroid Build Coastguard Worker
44*4a64e381SAndroid Build Coastguard Worker #include "common/byteswap.hpp"
45*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
46*4a64e381SAndroid Build Coastguard Worker
47*4a64e381SAndroid Build Coastguard Worker namespace otbr {
48*4a64e381SAndroid Build Coastguard Worker namespace Web {
49*4a64e381SAndroid Build Coastguard Worker
50*4a64e381SAndroid Build Coastguard Worker #define WPAN_RESPONSE_SUCCESS "successful"
51*4a64e381SAndroid Build Coastguard Worker #define WPAN_RESPONSE_FAILURE "failed"
52*4a64e381SAndroid Build Coastguard Worker #define CREDENTIAL_TYPE_NETWORK_KEY "networkKeyType"
53*4a64e381SAndroid Build Coastguard Worker #define CREDENTIAL_TYPE_PSKD "pskdType"
54*4a64e381SAndroid Build Coastguard Worker
HandleGetQRCodeRequest()55*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleGetQRCodeRequest()
56*4a64e381SAndroid Build Coastguard Worker {
57*4a64e381SAndroid Build Coastguard Worker Json::Value root, networkInfo;
58*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
59*4a64e381SAndroid Build Coastguard Worker std::string response;
60*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
61*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
62*4a64e381SAndroid Build Coastguard Worker char *rval;
63*4a64e381SAndroid Build Coastguard Worker
64*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_SetFailed);
65*4a64e381SAndroid Build Coastguard Worker
66*4a64e381SAndroid Build Coastguard Worker // eui64 is the only required information to generate the QR code.
67*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("eui64")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
68*4a64e381SAndroid Build Coastguard Worker
69*4a64e381SAndroid Build Coastguard Worker exit:
70*4a64e381SAndroid Build Coastguard Worker
71*4a64e381SAndroid Build Coastguard Worker root.clear();
72*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_SUCCESS;
73*4a64e381SAndroid Build Coastguard Worker
74*4a64e381SAndroid Build Coastguard Worker if (ret == kWpanStatus_Ok)
75*4a64e381SAndroid Build Coastguard Worker {
76*4a64e381SAndroid Build Coastguard Worker root["eui64"] = rval;
77*4a64e381SAndroid Build Coastguard Worker }
78*4a64e381SAndroid Build Coastguard Worker else
79*4a64e381SAndroid Build Coastguard Worker {
80*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
81*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Wpan service error: %d", ret);
82*4a64e381SAndroid Build Coastguard Worker }
83*4a64e381SAndroid Build Coastguard Worker
84*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
85*4a64e381SAndroid Build Coastguard Worker return response;
86*4a64e381SAndroid Build Coastguard Worker }
87*4a64e381SAndroid Build Coastguard Worker
HandleJoinNetworkRequest(const std::string & aJoinRequest)88*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleJoinNetworkRequest(const std::string &aJoinRequest)
89*4a64e381SAndroid Build Coastguard Worker {
90*4a64e381SAndroid Build Coastguard Worker Json::Value root;
91*4a64e381SAndroid Build Coastguard Worker Json::Reader reader;
92*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
93*4a64e381SAndroid Build Coastguard Worker std::string response;
94*4a64e381SAndroid Build Coastguard Worker int index;
95*4a64e381SAndroid Build Coastguard Worker std::string credentialType;
96*4a64e381SAndroid Build Coastguard Worker std::string networkKey;
97*4a64e381SAndroid Build Coastguard Worker std::string pskd;
98*4a64e381SAndroid Build Coastguard Worker std::string prefix;
99*4a64e381SAndroid Build Coastguard Worker bool defaultRoute;
100*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
101*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
102*4a64e381SAndroid Build Coastguard Worker char *rval;
103*4a64e381SAndroid Build Coastguard Worker
104*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_SetFailed);
105*4a64e381SAndroid Build Coastguard Worker
106*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(reader.parse(aJoinRequest.c_str(), root) == true, ret = kWpanStatus_ParseRequestFailed);
107*4a64e381SAndroid Build Coastguard Worker index = root["index"].asUInt();
108*4a64e381SAndroid Build Coastguard Worker credentialType = root["credentialType"].asString();
109*4a64e381SAndroid Build Coastguard Worker networkKey = root["networkKey"].asString();
110*4a64e381SAndroid Build Coastguard Worker pskd = root["pskd"].asString();
111*4a64e381SAndroid Build Coastguard Worker prefix = root["prefix"].asString();
112*4a64e381SAndroid Build Coastguard Worker defaultRoute = root["defaultRoute"].asBool();
113*4a64e381SAndroid Build Coastguard Worker
114*4a64e381SAndroid Build Coastguard Worker if (prefix.find('/') == std::string::npos)
115*4a64e381SAndroid Build Coastguard Worker {
116*4a64e381SAndroid Build Coastguard Worker prefix += "/64";
117*4a64e381SAndroid Build Coastguard Worker }
118*4a64e381SAndroid Build Coastguard Worker
119*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.FactoryReset(), ret = kWpanStatus_LeaveFailed);
120*4a64e381SAndroid Build Coastguard Worker
121*4a64e381SAndroid Build Coastguard Worker if (credentialType == CREDENTIAL_TYPE_NETWORK_KEY)
122*4a64e381SAndroid Build Coastguard Worker {
123*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((ret = joinActiveDataset(client, networkKey, mNetworks[index].mChannel,
124*4a64e381SAndroid Build Coastguard Worker mNetworks[index].mPanId)) == kWpanStatus_Ok);
125*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("ifconfig up") != nullptr, ret = kWpanStatus_JoinFailed);
126*4a64e381SAndroid Build Coastguard Worker }
127*4a64e381SAndroid Build Coastguard Worker else if (credentialType == CREDENTIAL_TYPE_PSKD)
128*4a64e381SAndroid Build Coastguard Worker {
129*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("ifconfig up") != nullptr, ret = kWpanStatus_JoinFailed);
130*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("joiner start %s", pskd.c_str()) != nullptr, ret = kWpanStatus_JoinFailed);
131*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Read("Join ", 5000)) != nullptr, ret = kWpanStatus_JoinFailed);
132*4a64e381SAndroid Build Coastguard Worker if (strstr(rval, "Join success"))
133*4a64e381SAndroid Build Coastguard Worker {
134*4a64e381SAndroid Build Coastguard Worker ExitNow();
135*4a64e381SAndroid Build Coastguard Worker }
136*4a64e381SAndroid Build Coastguard Worker else if (strstr(rval, "Join failed [NotFound]"))
137*4a64e381SAndroid Build Coastguard Worker {
138*4a64e381SAndroid Build Coastguard Worker ExitNow(ret = kWpanStatus_JoinFailed_NotFound);
139*4a64e381SAndroid Build Coastguard Worker }
140*4a64e381SAndroid Build Coastguard Worker else if (strstr(rval, "Join failed [Security]"))
141*4a64e381SAndroid Build Coastguard Worker {
142*4a64e381SAndroid Build Coastguard Worker ExitNow(ret = kWpanStatus_JoinFailed_Security);
143*4a64e381SAndroid Build Coastguard Worker }
144*4a64e381SAndroid Build Coastguard Worker else
145*4a64e381SAndroid Build Coastguard Worker {
146*4a64e381SAndroid Build Coastguard Worker ExitNow(ret = kWpanStatus_JoinFailed);
147*4a64e381SAndroid Build Coastguard Worker }
148*4a64e381SAndroid Build Coastguard Worker }
149*4a64e381SAndroid Build Coastguard Worker else
150*4a64e381SAndroid Build Coastguard Worker {
151*4a64e381SAndroid Build Coastguard Worker ExitNow(ret = kWpanStatus_JoinFailed);
152*4a64e381SAndroid Build Coastguard Worker }
153*4a64e381SAndroid Build Coastguard Worker
154*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("thread start") != nullptr, ret = kWpanStatus_JoinFailed);
155*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("prefix add %s paso%s", prefix.c_str(), (defaultRoute ? "r" : "")) != nullptr,
156*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_SetFailed);
157*4a64e381SAndroid Build Coastguard Worker
158*4a64e381SAndroid Build Coastguard Worker exit:
159*4a64e381SAndroid Build Coastguard Worker
160*4a64e381SAndroid Build Coastguard Worker root.clear();
161*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_SUCCESS;
162*4a64e381SAndroid Build Coastguard Worker
163*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
164*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
165*4a64e381SAndroid Build Coastguard Worker {
166*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Wpan service error: %d", ret);
167*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
168*4a64e381SAndroid Build Coastguard Worker }
169*4a64e381SAndroid Build Coastguard Worker
170*4a64e381SAndroid Build Coastguard Worker root["message"] = "";
171*4a64e381SAndroid Build Coastguard Worker if (ret == kWpanStatus_JoinFailed_NotFound)
172*4a64e381SAndroid Build Coastguard Worker {
173*4a64e381SAndroid Build Coastguard Worker root["message"] = "Please make sure this joiner has been added by an active commissioner.";
174*4a64e381SAndroid Build Coastguard Worker }
175*4a64e381SAndroid Build Coastguard Worker else if (ret == kWpanStatus_JoinFailed_Security)
176*4a64e381SAndroid Build Coastguard Worker {
177*4a64e381SAndroid Build Coastguard Worker root["message"] = "Please make sure the provided PSKd matches the one given to the commissioner.";
178*4a64e381SAndroid Build Coastguard Worker }
179*4a64e381SAndroid Build Coastguard Worker
180*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
181*4a64e381SAndroid Build Coastguard Worker return response;
182*4a64e381SAndroid Build Coastguard Worker }
183*4a64e381SAndroid Build Coastguard Worker
HandleFormNetworkRequest(const std::string & aFormRequest)184*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleFormNetworkRequest(const std::string &aFormRequest)
185*4a64e381SAndroid Build Coastguard Worker {
186*4a64e381SAndroid Build Coastguard Worker Json::Value root;
187*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
188*4a64e381SAndroid Build Coastguard Worker Json::Reader reader;
189*4a64e381SAndroid Build Coastguard Worker std::string response;
190*4a64e381SAndroid Build Coastguard Worker otbr::Psk::Pskc psk;
191*4a64e381SAndroid Build Coastguard Worker char pskcStr[OT_PSKC_MAX_LENGTH * 2 + 1];
192*4a64e381SAndroid Build Coastguard Worker uint8_t extPanIdBytes[OT_EXTENDED_PANID_LENGTH];
193*4a64e381SAndroid Build Coastguard Worker std::string networkKey;
194*4a64e381SAndroid Build Coastguard Worker std::string prefix;
195*4a64e381SAndroid Build Coastguard Worker uint16_t channel;
196*4a64e381SAndroid Build Coastguard Worker std::string networkName;
197*4a64e381SAndroid Build Coastguard Worker std::string passphrase;
198*4a64e381SAndroid Build Coastguard Worker uint16_t panId;
199*4a64e381SAndroid Build Coastguard Worker uint64_t extPanId;
200*4a64e381SAndroid Build Coastguard Worker bool defaultRoute;
201*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
202*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
203*4a64e381SAndroid Build Coastguard Worker
204*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_SetFailed);
205*4a64e381SAndroid Build Coastguard Worker
206*4a64e381SAndroid Build Coastguard Worker pskcStr[OT_PSKC_MAX_LENGTH * 2] = '\0'; // for manipulating with strlen
207*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(reader.parse(aFormRequest.c_str(), root) == true, ret = kWpanStatus_ParseRequestFailed);
208*4a64e381SAndroid Build Coastguard Worker networkKey = root["networkKey"].asString();
209*4a64e381SAndroid Build Coastguard Worker prefix = root["prefix"].asString();
210*4a64e381SAndroid Build Coastguard Worker channel = root["channel"].asUInt();
211*4a64e381SAndroid Build Coastguard Worker networkName = root["networkName"].asString();
212*4a64e381SAndroid Build Coastguard Worker passphrase = root["passphrase"].asString();
213*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(sscanf(root["panId"].asString().c_str(), "%hx", &panId) == 1, ret = kWpanStatus_ParseRequestFailed);
214*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(sscanf(root["extPanId"].asString().c_str(), "%" PRIx64, &extPanId) == 1,
215*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_ParseRequestFailed);
216*4a64e381SAndroid Build Coastguard Worker defaultRoute = root["defaultRoute"].asBool();
217*4a64e381SAndroid Build Coastguard Worker
218*4a64e381SAndroid Build Coastguard Worker otbr::Utils::Hex2Bytes(root["extPanId"].asString().c_str(), extPanIdBytes, OT_EXTENDED_PANID_LENGTH);
219*4a64e381SAndroid Build Coastguard Worker otbr::Utils::Bytes2Hex(psk.ComputePskc(extPanIdBytes, networkName.c_str(), passphrase.c_str()), OT_PSKC_MAX_LENGTH,
220*4a64e381SAndroid Build Coastguard Worker pskcStr);
221*4a64e381SAndroid Build Coastguard Worker
222*4a64e381SAndroid Build Coastguard Worker if (prefix.find('/') == std::string::npos)
223*4a64e381SAndroid Build Coastguard Worker {
224*4a64e381SAndroid Build Coastguard Worker prefix += "/64";
225*4a64e381SAndroid Build Coastguard Worker }
226*4a64e381SAndroid Build Coastguard Worker
227*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.FactoryReset(), ret = kWpanStatus_LeaveFailed);
228*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((ret = formActiveDataset(client, networkKey, networkName, pskcStr, channel, extPanId, panId)) ==
229*4a64e381SAndroid Build Coastguard Worker kWpanStatus_Ok);
230*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("ifconfig up") != nullptr, ret = kWpanStatus_FormFailed);
231*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("thread start") != nullptr, ret = kWpanStatus_FormFailed);
232*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("prefix add %s paso%s", prefix.c_str(), (defaultRoute ? "r" : "")) != nullptr,
233*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_SetFailed);
234*4a64e381SAndroid Build Coastguard Worker exit:
235*4a64e381SAndroid Build Coastguard Worker
236*4a64e381SAndroid Build Coastguard Worker root.clear();
237*4a64e381SAndroid Build Coastguard Worker
238*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_SUCCESS;
239*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
240*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
241*4a64e381SAndroid Build Coastguard Worker {
242*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Wpan service error: %d", ret);
243*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
244*4a64e381SAndroid Build Coastguard Worker }
245*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
246*4a64e381SAndroid Build Coastguard Worker return response;
247*4a64e381SAndroid Build Coastguard Worker }
248*4a64e381SAndroid Build Coastguard Worker
HandleAddPrefixRequest(const std::string & aAddPrefixRequest)249*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleAddPrefixRequest(const std::string &aAddPrefixRequest)
250*4a64e381SAndroid Build Coastguard Worker {
251*4a64e381SAndroid Build Coastguard Worker Json::Value root;
252*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
253*4a64e381SAndroid Build Coastguard Worker Json::Reader reader;
254*4a64e381SAndroid Build Coastguard Worker std::string response;
255*4a64e381SAndroid Build Coastguard Worker std::string prefix;
256*4a64e381SAndroid Build Coastguard Worker bool defaultRoute;
257*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
258*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
259*4a64e381SAndroid Build Coastguard Worker
260*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_SetFailed);
261*4a64e381SAndroid Build Coastguard Worker
262*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(reader.parse(aAddPrefixRequest.c_str(), root) == true, ret = kWpanStatus_ParseRequestFailed);
263*4a64e381SAndroid Build Coastguard Worker prefix = root["prefix"].asString();
264*4a64e381SAndroid Build Coastguard Worker defaultRoute = root["defaultRoute"].asBool();
265*4a64e381SAndroid Build Coastguard Worker
266*4a64e381SAndroid Build Coastguard Worker if (prefix.find('/') == std::string::npos)
267*4a64e381SAndroid Build Coastguard Worker {
268*4a64e381SAndroid Build Coastguard Worker prefix += "/64";
269*4a64e381SAndroid Build Coastguard Worker }
270*4a64e381SAndroid Build Coastguard Worker
271*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("prefix add %s paso%s", prefix.c_str(), (defaultRoute ? "r" : "")) != nullptr,
272*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_SetGatewayFailed);
273*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("netdata register") != nullptr, ret = kWpanStatus_SetGatewayFailed);
274*4a64e381SAndroid Build Coastguard Worker exit:
275*4a64e381SAndroid Build Coastguard Worker
276*4a64e381SAndroid Build Coastguard Worker root.clear();
277*4a64e381SAndroid Build Coastguard Worker
278*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_SUCCESS;
279*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
280*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
281*4a64e381SAndroid Build Coastguard Worker {
282*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Wpan service error: %d", ret);
283*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
284*4a64e381SAndroid Build Coastguard Worker }
285*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
286*4a64e381SAndroid Build Coastguard Worker return response;
287*4a64e381SAndroid Build Coastguard Worker }
288*4a64e381SAndroid Build Coastguard Worker
HandleDeletePrefixRequest(const std::string & aDeleteRequest)289*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleDeletePrefixRequest(const std::string &aDeleteRequest)
290*4a64e381SAndroid Build Coastguard Worker {
291*4a64e381SAndroid Build Coastguard Worker Json::Value root;
292*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
293*4a64e381SAndroid Build Coastguard Worker Json::Reader reader;
294*4a64e381SAndroid Build Coastguard Worker std::string response;
295*4a64e381SAndroid Build Coastguard Worker std::string prefix;
296*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
297*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
298*4a64e381SAndroid Build Coastguard Worker
299*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_SetFailed);
300*4a64e381SAndroid Build Coastguard Worker
301*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(reader.parse(aDeleteRequest.c_str(), root) == true, ret = kWpanStatus_ParseRequestFailed);
302*4a64e381SAndroid Build Coastguard Worker prefix = root["prefix"].asString();
303*4a64e381SAndroid Build Coastguard Worker
304*4a64e381SAndroid Build Coastguard Worker if (prefix.find('/') == std::string::npos)
305*4a64e381SAndroid Build Coastguard Worker {
306*4a64e381SAndroid Build Coastguard Worker prefix += "/64";
307*4a64e381SAndroid Build Coastguard Worker }
308*4a64e381SAndroid Build Coastguard Worker
309*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("prefix remove %s", prefix.c_str()) != nullptr, ret = kWpanStatus_SetGatewayFailed);
310*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("netdata register") != nullptr, ret = kWpanStatus_SetGatewayFailed);
311*4a64e381SAndroid Build Coastguard Worker exit:
312*4a64e381SAndroid Build Coastguard Worker
313*4a64e381SAndroid Build Coastguard Worker root.clear();
314*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_SUCCESS;
315*4a64e381SAndroid Build Coastguard Worker
316*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
317*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
318*4a64e381SAndroid Build Coastguard Worker {
319*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Wpan service error: %d", ret);
320*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
321*4a64e381SAndroid Build Coastguard Worker }
322*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
323*4a64e381SAndroid Build Coastguard Worker return response;
324*4a64e381SAndroid Build Coastguard Worker }
325*4a64e381SAndroid Build Coastguard Worker
HandleStatusRequest()326*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleStatusRequest()
327*4a64e381SAndroid Build Coastguard Worker {
328*4a64e381SAndroid Build Coastguard Worker Json::Value root, networkInfo;
329*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
330*4a64e381SAndroid Build Coastguard Worker std::string response, networkName, extPanId, propertyValue;
331*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
332*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
333*4a64e381SAndroid Build Coastguard Worker char *rval;
334*4a64e381SAndroid Build Coastguard Worker
335*4a64e381SAndroid Build Coastguard Worker networkInfo["WPAN service"] = "uninitialized";
336*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_SetFailed);
337*4a64e381SAndroid Build Coastguard Worker
338*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("state")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
339*4a64e381SAndroid Build Coastguard Worker networkInfo["RCP:State"] = rval;
340*4a64e381SAndroid Build Coastguard Worker
341*4a64e381SAndroid Build Coastguard Worker if (!strcmp(rval, "disabled"))
342*4a64e381SAndroid Build Coastguard Worker {
343*4a64e381SAndroid Build Coastguard Worker networkInfo["WPAN service"] = "offline";
344*4a64e381SAndroid Build Coastguard Worker ExitNow();
345*4a64e381SAndroid Build Coastguard Worker }
346*4a64e381SAndroid Build Coastguard Worker else if (!strcmp(rval, "detached"))
347*4a64e381SAndroid Build Coastguard Worker {
348*4a64e381SAndroid Build Coastguard Worker networkInfo["WPAN service"] = "associating";
349*4a64e381SAndroid Build Coastguard Worker ExitNow();
350*4a64e381SAndroid Build Coastguard Worker }
351*4a64e381SAndroid Build Coastguard Worker else
352*4a64e381SAndroid Build Coastguard Worker {
353*4a64e381SAndroid Build Coastguard Worker networkInfo["WPAN service"] = "associated";
354*4a64e381SAndroid Build Coastguard Worker }
355*4a64e381SAndroid Build Coastguard Worker
356*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("version")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
357*4a64e381SAndroid Build Coastguard Worker networkInfo["OpenThread:Version"] = rval;
358*4a64e381SAndroid Build Coastguard Worker
359*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("version api")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
360*4a64e381SAndroid Build Coastguard Worker networkInfo["OpenThread:Version API"] = rval;
361*4a64e381SAndroid Build Coastguard Worker
362*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("rcp version")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
363*4a64e381SAndroid Build Coastguard Worker networkInfo["RCP:Version"] = rval;
364*4a64e381SAndroid Build Coastguard Worker
365*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("eui64")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
366*4a64e381SAndroid Build Coastguard Worker networkInfo["RCP:EUI64"] = rval;
367*4a64e381SAndroid Build Coastguard Worker
368*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("channel")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
369*4a64e381SAndroid Build Coastguard Worker networkInfo["RCP:Channel"] = rval;
370*4a64e381SAndroid Build Coastguard Worker
371*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("txpower")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
372*4a64e381SAndroid Build Coastguard Worker networkInfo["RCP:TxPower"] = rval;
373*4a64e381SAndroid Build Coastguard Worker
374*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("networkname")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
375*4a64e381SAndroid Build Coastguard Worker networkInfo["Network:Name"] = rval;
376*4a64e381SAndroid Build Coastguard Worker
377*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("extpanid")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
378*4a64e381SAndroid Build Coastguard Worker networkInfo["Network:XPANID"] = rval;
379*4a64e381SAndroid Build Coastguard Worker
380*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("panid")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
381*4a64e381SAndroid Build Coastguard Worker networkInfo["Network:PANID"] = rval;
382*4a64e381SAndroid Build Coastguard Worker
383*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("partitionid")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
384*4a64e381SAndroid Build Coastguard Worker networkInfo["Network:PartitionID"] = rval;
385*4a64e381SAndroid Build Coastguard Worker
386*4a64e381SAndroid Build Coastguard Worker {
387*4a64e381SAndroid Build Coastguard Worker static const char kMeshLocalPrefixLocator[] = "Mesh Local Prefix: ";
388*4a64e381SAndroid Build Coastguard Worker static const char kMeshLocalAddressTokenLocator[] = "0:ff:fe00:";
389*4a64e381SAndroid Build Coastguard Worker static const char localAddressToken[] = "fd";
390*4a64e381SAndroid Build Coastguard Worker static const char linkLocalAddressToken[] = "fe80";
391*4a64e381SAndroid Build Coastguard Worker std::string meshLocalPrefix = "";
392*4a64e381SAndroid Build Coastguard Worker
393*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("dataset active")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
394*4a64e381SAndroid Build Coastguard Worker rval = strstr(rval, kMeshLocalPrefixLocator);
395*4a64e381SAndroid Build Coastguard Worker if (rval != nullptr)
396*4a64e381SAndroid Build Coastguard Worker {
397*4a64e381SAndroid Build Coastguard Worker rval += sizeof(kMeshLocalPrefixLocator) - 1;
398*4a64e381SAndroid Build Coastguard Worker *strstr(rval, "\r\n") = '\0';
399*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:MeshLocalPrefix"] = rval;
400*4a64e381SAndroid Build Coastguard Worker
401*4a64e381SAndroid Build Coastguard Worker meshLocalPrefix = rval;
402*4a64e381SAndroid Build Coastguard Worker meshLocalPrefix.resize(meshLocalPrefix.find(":/"));
403*4a64e381SAndroid Build Coastguard Worker }
404*4a64e381SAndroid Build Coastguard Worker
405*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("ipaddr")) != nullptr, ret = kWpanStatus_GetPropertyFailed);
406*4a64e381SAndroid Build Coastguard Worker
407*4a64e381SAndroid Build Coastguard Worker for (rval = strtok(rval, "\r\n"); rval != nullptr; rval = strtok(nullptr, "\r\n"))
408*4a64e381SAndroid Build Coastguard Worker {
409*4a64e381SAndroid Build Coastguard Worker char *meshLocalAddressToken = nullptr;
410*4a64e381SAndroid Build Coastguard Worker
411*4a64e381SAndroid Build Coastguard Worker if (strstr(rval, "> ") != nullptr)
412*4a64e381SAndroid Build Coastguard Worker {
413*4a64e381SAndroid Build Coastguard Worker rval += 2;
414*4a64e381SAndroid Build Coastguard Worker }
415*4a64e381SAndroid Build Coastguard Worker
416*4a64e381SAndroid Build Coastguard Worker if (strstr(rval, linkLocalAddressToken) == rval)
417*4a64e381SAndroid Build Coastguard Worker {
418*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:LinkLocalAddress"] = rval;
419*4a64e381SAndroid Build Coastguard Worker continue;
420*4a64e381SAndroid Build Coastguard Worker }
421*4a64e381SAndroid Build Coastguard Worker
422*4a64e381SAndroid Build Coastguard Worker meshLocalAddressToken = strstr(rval, kMeshLocalAddressTokenLocator);
423*4a64e381SAndroid Build Coastguard Worker
424*4a64e381SAndroid Build Coastguard Worker if (meshLocalAddressToken == nullptr)
425*4a64e381SAndroid Build Coastguard Worker {
426*4a64e381SAndroid Build Coastguard Worker if ((meshLocalPrefix.size() > 0) && (strstr(rval, meshLocalPrefix.c_str()) == rval))
427*4a64e381SAndroid Build Coastguard Worker {
428*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:MeshLocalAddress"] = rval;
429*4a64e381SAndroid Build Coastguard Worker continue;
430*4a64e381SAndroid Build Coastguard Worker }
431*4a64e381SAndroid Build Coastguard Worker
432*4a64e381SAndroid Build Coastguard Worker if (strstr(rval, localAddressToken) != rval)
433*4a64e381SAndroid Build Coastguard Worker {
434*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:GlobalAddress"] = rval;
435*4a64e381SAndroid Build Coastguard Worker }
436*4a64e381SAndroid Build Coastguard Worker else
437*4a64e381SAndroid Build Coastguard Worker {
438*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:LocalAddress"] = rval;
439*4a64e381SAndroid Build Coastguard Worker }
440*4a64e381SAndroid Build Coastguard Worker }
441*4a64e381SAndroid Build Coastguard Worker else
442*4a64e381SAndroid Build Coastguard Worker {
443*4a64e381SAndroid Build Coastguard Worker *meshLocalAddressToken = '\0';
444*4a64e381SAndroid Build Coastguard Worker meshLocalPrefix = rval;
445*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:MeshLocalPrefix"] = rval;
446*4a64e381SAndroid Build Coastguard Worker std::string la = networkInfo.get("IPv6:LocalAddress", "unknown").asString();
447*4a64e381SAndroid Build Coastguard Worker if (strstr(rval, la.c_str()) != nullptr)
448*4a64e381SAndroid Build Coastguard Worker {
449*4a64e381SAndroid Build Coastguard Worker networkInfo["IPv6:MeshLocalAddress"] = networkInfo.get("IPv6:LocalAddress", "notfound").asString();
450*4a64e381SAndroid Build Coastguard Worker networkInfo.removeMember("IPv6:LocalAddress");
451*4a64e381SAndroid Build Coastguard Worker }
452*4a64e381SAndroid Build Coastguard Worker }
453*4a64e381SAndroid Build Coastguard Worker }
454*4a64e381SAndroid Build Coastguard Worker }
455*4a64e381SAndroid Build Coastguard Worker
456*4a64e381SAndroid Build Coastguard Worker exit:
457*4a64e381SAndroid Build Coastguard Worker root["result"] = networkInfo;
458*4a64e381SAndroid Build Coastguard Worker
459*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
460*4a64e381SAndroid Build Coastguard Worker {
461*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
462*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Wpan service error: %d", ret);
463*4a64e381SAndroid Build Coastguard Worker }
464*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
465*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
466*4a64e381SAndroid Build Coastguard Worker return response;
467*4a64e381SAndroid Build Coastguard Worker }
468*4a64e381SAndroid Build Coastguard Worker
HandleAvailableNetworkRequest()469*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleAvailableNetworkRequest()
470*4a64e381SAndroid Build Coastguard Worker {
471*4a64e381SAndroid Build Coastguard Worker Json::Value root, networks, networkInfo;
472*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
473*4a64e381SAndroid Build Coastguard Worker std::string response;
474*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
475*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
476*4a64e381SAndroid Build Coastguard Worker
477*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_ScanFailed);
478*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((mNetworksCount = client.Scan(mNetworks, sizeof(mNetworks) / sizeof(mNetworks[0]))) > 0,
479*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_NetworkNotFound);
480*4a64e381SAndroid Build Coastguard Worker
481*4a64e381SAndroid Build Coastguard Worker for (int i = 0; i < mNetworksCount; i++)
482*4a64e381SAndroid Build Coastguard Worker {
483*4a64e381SAndroid Build Coastguard Worker char panId[OT_PANID_LENGTH * 2 + 3], hardwareAddress[OT_HARDWARE_ADDRESS_LENGTH * 2 + 1];
484*4a64e381SAndroid Build Coastguard Worker otbr::Utils::Bytes2Hex(mNetworks[i].mHardwareAddress, OT_HARDWARE_ADDRESS_LENGTH, hardwareAddress);
485*4a64e381SAndroid Build Coastguard Worker snprintf(panId, sizeof(panId), "0x%X", mNetworks[i].mPanId);
486*4a64e381SAndroid Build Coastguard Worker networkInfo[i]["pi"] = panId;
487*4a64e381SAndroid Build Coastguard Worker networkInfo[i]["ch"] = mNetworks[i].mChannel;
488*4a64e381SAndroid Build Coastguard Worker networkInfo[i]["ha"] = hardwareAddress;
489*4a64e381SAndroid Build Coastguard Worker }
490*4a64e381SAndroid Build Coastguard Worker
491*4a64e381SAndroid Build Coastguard Worker root["result"] = networkInfo;
492*4a64e381SAndroid Build Coastguard Worker
493*4a64e381SAndroid Build Coastguard Worker exit:
494*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
495*4a64e381SAndroid Build Coastguard Worker {
496*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
497*4a64e381SAndroid Build Coastguard Worker otbrLogErr("Error is %d", ret);
498*4a64e381SAndroid Build Coastguard Worker }
499*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
500*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
501*4a64e381SAndroid Build Coastguard Worker return response;
502*4a64e381SAndroid Build Coastguard Worker }
503*4a64e381SAndroid Build Coastguard Worker
GetWpanServiceStatus(std::string & aNetworkName,std::string & aExtPanId) const504*4a64e381SAndroid Build Coastguard Worker int WpanService::GetWpanServiceStatus(std::string &aNetworkName, std::string &aExtPanId) const
505*4a64e381SAndroid Build Coastguard Worker {
506*4a64e381SAndroid Build Coastguard Worker int status = kWpanStatus_Ok;
507*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
508*4a64e381SAndroid Build Coastguard Worker const char *rval;
509*4a64e381SAndroid Build Coastguard Worker
510*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), status = kWpanStatus_Uninitialized);
511*4a64e381SAndroid Build Coastguard Worker rval = client.Execute("state");
512*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(rval != nullptr, status = kWpanStatus_Down);
513*4a64e381SAndroid Build Coastguard Worker if (!strcmp(rval, "disabled"))
514*4a64e381SAndroid Build Coastguard Worker {
515*4a64e381SAndroid Build Coastguard Worker status = kWpanStatus_Offline;
516*4a64e381SAndroid Build Coastguard Worker }
517*4a64e381SAndroid Build Coastguard Worker else if (!strcmp(rval, "detached"))
518*4a64e381SAndroid Build Coastguard Worker {
519*4a64e381SAndroid Build Coastguard Worker status = kWpanStatus_Associating;
520*4a64e381SAndroid Build Coastguard Worker }
521*4a64e381SAndroid Build Coastguard Worker else
522*4a64e381SAndroid Build Coastguard Worker {
523*4a64e381SAndroid Build Coastguard Worker rval = client.Execute("networkname");
524*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(rval != nullptr, status = kWpanStatus_Down);
525*4a64e381SAndroid Build Coastguard Worker aNetworkName = rval;
526*4a64e381SAndroid Build Coastguard Worker
527*4a64e381SAndroid Build Coastguard Worker rval = client.Execute("extpanid");
528*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(rval != nullptr, status = kWpanStatus_Down);
529*4a64e381SAndroid Build Coastguard Worker aExtPanId = rval;
530*4a64e381SAndroid Build Coastguard Worker }
531*4a64e381SAndroid Build Coastguard Worker
532*4a64e381SAndroid Build Coastguard Worker exit:
533*4a64e381SAndroid Build Coastguard Worker
534*4a64e381SAndroid Build Coastguard Worker return status;
535*4a64e381SAndroid Build Coastguard Worker }
536*4a64e381SAndroid Build Coastguard Worker
HandleCommission(const std::string & aCommissionRequest)537*4a64e381SAndroid Build Coastguard Worker std::string WpanService::HandleCommission(const std::string &aCommissionRequest)
538*4a64e381SAndroid Build Coastguard Worker {
539*4a64e381SAndroid Build Coastguard Worker Json::Value root;
540*4a64e381SAndroid Build Coastguard Worker Json::Reader reader;
541*4a64e381SAndroid Build Coastguard Worker Json::FastWriter jsonWriter;
542*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
543*4a64e381SAndroid Build Coastguard Worker std::string pskd;
544*4a64e381SAndroid Build Coastguard Worker std::string response;
545*4a64e381SAndroid Build Coastguard Worker const char *rval;
546*4a64e381SAndroid Build Coastguard Worker
547*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(reader.parse(aCommissionRequest.c_str(), root) == true, ret = kWpanStatus_ParseRequestFailed);
548*4a64e381SAndroid Build Coastguard Worker pskd = root["pskd"].asString();
549*4a64e381SAndroid Build Coastguard Worker
550*4a64e381SAndroid Build Coastguard Worker {
551*4a64e381SAndroid Build Coastguard Worker otbr::Web::OpenThreadClient client(mIfName);
552*4a64e381SAndroid Build Coastguard Worker
553*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Connect(), ret = kWpanStatus_Uninitialized);
554*4a64e381SAndroid Build Coastguard Worker
555*4a64e381SAndroid Build Coastguard Worker for (int i = 0; i < 5; i++)
556*4a64e381SAndroid Build Coastguard Worker {
557*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("commissioner state")) != nullptr, ret = kWpanStatus_Down);
558*4a64e381SAndroid Build Coastguard Worker
559*4a64e381SAndroid Build Coastguard Worker if (strcmp(rval, "disabled") == 0)
560*4a64e381SAndroid Build Coastguard Worker {
561*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((rval = client.Execute("commissioner start")) != nullptr, ret = kWpanStatus_Down);
562*4a64e381SAndroid Build Coastguard Worker }
563*4a64e381SAndroid Build Coastguard Worker else if (strcmp(rval, "active") == 0)
564*4a64e381SAndroid Build Coastguard Worker {
565*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(client.Execute("commissioner joiner add * %s", pskd.c_str()) != nullptr,
566*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_Down);
567*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
568*4a64e381SAndroid Build Coastguard Worker ExitNow();
569*4a64e381SAndroid Build Coastguard Worker }
570*4a64e381SAndroid Build Coastguard Worker
571*4a64e381SAndroid Build Coastguard Worker sleep(1);
572*4a64e381SAndroid Build Coastguard Worker }
573*4a64e381SAndroid Build Coastguard Worker
574*4a64e381SAndroid Build Coastguard Worker client.Execute("commissioner stop");
575*4a64e381SAndroid Build Coastguard Worker }
576*4a64e381SAndroid Build Coastguard Worker
577*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_SetFailed;
578*4a64e381SAndroid Build Coastguard Worker
579*4a64e381SAndroid Build Coastguard Worker exit:
580*4a64e381SAndroid Build Coastguard Worker
581*4a64e381SAndroid Build Coastguard Worker root.clear();
582*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_SUCCESS;
583*4a64e381SAndroid Build Coastguard Worker root["error"] = ret;
584*4a64e381SAndroid Build Coastguard Worker
585*4a64e381SAndroid Build Coastguard Worker if (ret != kWpanStatus_Ok)
586*4a64e381SAndroid Build Coastguard Worker {
587*4a64e381SAndroid Build Coastguard Worker root["result"] = WPAN_RESPONSE_FAILURE;
588*4a64e381SAndroid Build Coastguard Worker otbrLogErr("error: %d", ret);
589*4a64e381SAndroid Build Coastguard Worker }
590*4a64e381SAndroid Build Coastguard Worker response = jsonWriter.write(root);
591*4a64e381SAndroid Build Coastguard Worker
592*4a64e381SAndroid Build Coastguard Worker return response;
593*4a64e381SAndroid Build Coastguard Worker }
594*4a64e381SAndroid Build Coastguard Worker
joinActiveDataset(otbr::Web::OpenThreadClient & aClient,const std::string & aNetworkKey,uint16_t aChannel,uint16_t aPanId)595*4a64e381SAndroid Build Coastguard Worker int WpanService::joinActiveDataset(otbr::Web::OpenThreadClient &aClient,
596*4a64e381SAndroid Build Coastguard Worker const std::string &aNetworkKey,
597*4a64e381SAndroid Build Coastguard Worker uint16_t aChannel,
598*4a64e381SAndroid Build Coastguard Worker uint16_t aPanId)
599*4a64e381SAndroid Build Coastguard Worker {
600*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
601*4a64e381SAndroid Build Coastguard Worker
602*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset clear") != nullptr, ret = kWpanStatus_SetFailed);
603*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset networkkey %s", aNetworkKey.c_str()) != nullptr, ret = kWpanStatus_SetFailed);
604*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset channel %u", aChannel) != nullptr, ret = kWpanStatus_SetFailed);
605*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset panid %u", aPanId) != nullptr, ret = kWpanStatus_SetFailed);
606*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset commit active") != nullptr, ret = kWpanStatus_SetFailed);
607*4a64e381SAndroid Build Coastguard Worker
608*4a64e381SAndroid Build Coastguard Worker exit:
609*4a64e381SAndroid Build Coastguard Worker return ret;
610*4a64e381SAndroid Build Coastguard Worker }
611*4a64e381SAndroid Build Coastguard Worker
formActiveDataset(otbr::Web::OpenThreadClient & aClient,const std::string & aNetworkKey,const std::string & aNetworkName,const std::string & aPskc,uint16_t aChannel,uint64_t aExtPanId,uint16_t aPanId)612*4a64e381SAndroid Build Coastguard Worker int WpanService::formActiveDataset(otbr::Web::OpenThreadClient &aClient,
613*4a64e381SAndroid Build Coastguard Worker const std::string &aNetworkKey,
614*4a64e381SAndroid Build Coastguard Worker const std::string &aNetworkName,
615*4a64e381SAndroid Build Coastguard Worker const std::string &aPskc,
616*4a64e381SAndroid Build Coastguard Worker uint16_t aChannel,
617*4a64e381SAndroid Build Coastguard Worker uint64_t aExtPanId,
618*4a64e381SAndroid Build Coastguard Worker uint16_t aPanId)
619*4a64e381SAndroid Build Coastguard Worker {
620*4a64e381SAndroid Build Coastguard Worker int ret = kWpanStatus_Ok;
621*4a64e381SAndroid Build Coastguard Worker
622*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset init new") != nullptr, ret = kWpanStatus_SetFailed);
623*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset networkkey %s", aNetworkKey.c_str()) != nullptr, ret = kWpanStatus_SetFailed);
624*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset networkname %s", escapeOtCliEscapable(aNetworkName).c_str()) != nullptr,
625*4a64e381SAndroid Build Coastguard Worker ret = kWpanStatus_SetFailed);
626*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset pskc %s", aPskc.c_str()) != nullptr, ret = kWpanStatus_SetFailed);
627*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset channel %u", aChannel) != nullptr, ret = kWpanStatus_SetFailed);
628*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset extpanid %016" PRIx64, aExtPanId) != nullptr, ret = kWpanStatus_SetFailed);
629*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset panid %u", aPanId) != nullptr, ret = kWpanStatus_SetFailed);
630*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aClient.Execute("dataset commit active") != nullptr, ret = kWpanStatus_SetFailed);
631*4a64e381SAndroid Build Coastguard Worker
632*4a64e381SAndroid Build Coastguard Worker exit:
633*4a64e381SAndroid Build Coastguard Worker return ret;
634*4a64e381SAndroid Build Coastguard Worker }
635*4a64e381SAndroid Build Coastguard Worker
escapeOtCliEscapable(const std::string & aArg)636*4a64e381SAndroid Build Coastguard Worker std::string WpanService::escapeOtCliEscapable(const std::string &aArg)
637*4a64e381SAndroid Build Coastguard Worker {
638*4a64e381SAndroid Build Coastguard Worker std::stringbuf strbuf;
639*4a64e381SAndroid Build Coastguard Worker
640*4a64e381SAndroid Build Coastguard Worker for (char c : aArg)
641*4a64e381SAndroid Build Coastguard Worker {
642*4a64e381SAndroid Build Coastguard Worker switch (c)
643*4a64e381SAndroid Build Coastguard Worker {
644*4a64e381SAndroid Build Coastguard Worker case ' ':
645*4a64e381SAndroid Build Coastguard Worker case '\t':
646*4a64e381SAndroid Build Coastguard Worker case '\r':
647*4a64e381SAndroid Build Coastguard Worker case '\n':
648*4a64e381SAndroid Build Coastguard Worker case '\\':
649*4a64e381SAndroid Build Coastguard Worker strbuf.sputc('\\');
650*4a64e381SAndroid Build Coastguard Worker // Fallthrough
651*4a64e381SAndroid Build Coastguard Worker default:
652*4a64e381SAndroid Build Coastguard Worker strbuf.sputc(c);
653*4a64e381SAndroid Build Coastguard Worker }
654*4a64e381SAndroid Build Coastguard Worker }
655*4a64e381SAndroid Build Coastguard Worker
656*4a64e381SAndroid Build Coastguard Worker return strbuf.str();
657*4a64e381SAndroid Build Coastguard Worker }
658*4a64e381SAndroid Build Coastguard Worker
659*4a64e381SAndroid Build Coastguard Worker } // namespace Web
660*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
661