xref: /aosp_15_r20/external/ot-br-posix/src/rest/resource.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *  Copyright (c) 2020, 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 #define OTBR_LOG_TAG "REST"
30*4a64e381SAndroid Build Coastguard Worker 
31*4a64e381SAndroid Build Coastguard Worker #include "rest/resource.hpp"
32*4a64e381SAndroid Build Coastguard Worker 
33*4a64e381SAndroid Build Coastguard Worker #define OT_PSKC_MAX_LENGTH 16
34*4a64e381SAndroid Build Coastguard Worker #define OT_EXTENDED_PANID_LENGTH 8
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_DIAGNOSTICS "/diagnostics"
37*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE "/node"
38*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_BAID "/node/ba-id"
39*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_RLOC "/node/rloc"
40*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_RLOC16 "/node/rloc16"
41*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_EXTADDRESS "/node/ext-address"
42*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_STATE "/node/state"
43*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_NETWORKNAME "/node/network-name"
44*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_LEADERDATA "/node/leader-data"
45*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_NUMOFROUTER "/node/num-of-router"
46*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_EXTPANID "/node/ext-panid"
47*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_DATASET_ACTIVE "/node/dataset/active"
48*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NODE_DATASET_PENDING "/node/dataset/pending"
49*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NETWORK "/networks"
50*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NETWORK_CURRENT "/networks/current"
51*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NETWORK_CURRENT_COMMISSION "/networks/commission"
52*4a64e381SAndroid Build Coastguard Worker #define OT_REST_RESOURCE_PATH_NETWORK_CURRENT_PREFIX "/networks/current/prefix"
53*4a64e381SAndroid Build Coastguard Worker 
54*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_200 "200 OK"
55*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_201 "201 Created"
56*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_204 "204 No Content"
57*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_400 "400 Bad Request"
58*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_404 "404 Not Found"
59*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_405 "405 Method Not Allowed"
60*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_408 "408 Request Timeout"
61*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_409 "409 Conflict"
62*4a64e381SAndroid Build Coastguard Worker #define OT_REST_HTTP_STATUS_500 "500 Internal Server Error"
63*4a64e381SAndroid Build Coastguard Worker 
64*4a64e381SAndroid Build Coastguard Worker using std::chrono::duration_cast;
65*4a64e381SAndroid Build Coastguard Worker using std::chrono::microseconds;
66*4a64e381SAndroid Build Coastguard Worker using std::chrono::steady_clock;
67*4a64e381SAndroid Build Coastguard Worker 
68*4a64e381SAndroid Build Coastguard Worker using std::placeholders::_1;
69*4a64e381SAndroid Build Coastguard Worker using std::placeholders::_2;
70*4a64e381SAndroid Build Coastguard Worker 
71*4a64e381SAndroid Build Coastguard Worker namespace otbr {
72*4a64e381SAndroid Build Coastguard Worker namespace rest {
73*4a64e381SAndroid Build Coastguard Worker 
74*4a64e381SAndroid Build Coastguard Worker // MulticastAddr
75*4a64e381SAndroid Build Coastguard Worker static const char *kMulticastAddrAllRouters = "ff03::2";
76*4a64e381SAndroid Build Coastguard Worker 
77*4a64e381SAndroid Build Coastguard Worker // Default TlvTypes for Diagnostic inforamtion
78*4a64e381SAndroid Build Coastguard Worker static const uint8_t kAllTlvTypes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 17, 19};
79*4a64e381SAndroid Build Coastguard Worker 
80*4a64e381SAndroid Build Coastguard Worker // Timeout (in Microseconds) for deleting outdated diagnostics
81*4a64e381SAndroid Build Coastguard Worker static const uint32_t kDiagResetTimeout = 3000000;
82*4a64e381SAndroid Build Coastguard Worker 
83*4a64e381SAndroid Build Coastguard Worker // Timeout (in Microseconds) for collecting diagnostics
84*4a64e381SAndroid Build Coastguard Worker static const uint32_t kDiagCollectTimeout = 2000000;
85*4a64e381SAndroid Build Coastguard Worker 
GetHttpStatus(HttpStatusCode aErrorCode)86*4a64e381SAndroid Build Coastguard Worker static std::string GetHttpStatus(HttpStatusCode aErrorCode)
87*4a64e381SAndroid Build Coastguard Worker {
88*4a64e381SAndroid Build Coastguard Worker     std::string httpStatus;
89*4a64e381SAndroid Build Coastguard Worker 
90*4a64e381SAndroid Build Coastguard Worker     switch (aErrorCode)
91*4a64e381SAndroid Build Coastguard Worker     {
92*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusOk:
93*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_200;
94*4a64e381SAndroid Build Coastguard Worker         break;
95*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusCreated:
96*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_201;
97*4a64e381SAndroid Build Coastguard Worker         break;
98*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusNoContent:
99*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_204;
100*4a64e381SAndroid Build Coastguard Worker         break;
101*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusBadRequest:
102*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_400;
103*4a64e381SAndroid Build Coastguard Worker         break;
104*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusResourceNotFound:
105*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_404;
106*4a64e381SAndroid Build Coastguard Worker         break;
107*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusMethodNotAllowed:
108*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_405;
109*4a64e381SAndroid Build Coastguard Worker         break;
110*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusRequestTimeout:
111*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_408;
112*4a64e381SAndroid Build Coastguard Worker         break;
113*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusConflict:
114*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_409;
115*4a64e381SAndroid Build Coastguard Worker         break;
116*4a64e381SAndroid Build Coastguard Worker     case HttpStatusCode::kStatusInternalServerError:
117*4a64e381SAndroid Build Coastguard Worker         httpStatus = OT_REST_HTTP_STATUS_500;
118*4a64e381SAndroid Build Coastguard Worker         break;
119*4a64e381SAndroid Build Coastguard Worker     }
120*4a64e381SAndroid Build Coastguard Worker 
121*4a64e381SAndroid Build Coastguard Worker     return httpStatus;
122*4a64e381SAndroid Build Coastguard Worker }
123*4a64e381SAndroid Build Coastguard Worker 
Resource(RcpHost * aHost)124*4a64e381SAndroid Build Coastguard Worker Resource::Resource(RcpHost *aHost)
125*4a64e381SAndroid Build Coastguard Worker     : mInstance(nullptr)
126*4a64e381SAndroid Build Coastguard Worker     , mHost(aHost)
127*4a64e381SAndroid Build Coastguard Worker {
128*4a64e381SAndroid Build Coastguard Worker     // Resource Handler
129*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_DIAGNOSTICS, &Resource::Diagnostic);
130*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE, &Resource::NodeInfo);
131*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_BAID, &Resource::BaId);
132*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_STATE, &Resource::State);
133*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_EXTADDRESS, &Resource::ExtendedAddr);
134*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_NETWORKNAME, &Resource::NetworkName);
135*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_RLOC16, &Resource::Rloc16);
136*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_LEADERDATA, &Resource::LeaderData);
137*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_NUMOFROUTER, &Resource::NumOfRoute);
138*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_EXTPANID, &Resource::ExtendedPanId);
139*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_RLOC, &Resource::Rloc);
140*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_DATASET_ACTIVE, &Resource::DatasetActive);
141*4a64e381SAndroid Build Coastguard Worker     mResourceMap.emplace(OT_REST_RESOURCE_PATH_NODE_DATASET_PENDING, &Resource::DatasetPending);
142*4a64e381SAndroid Build Coastguard Worker 
143*4a64e381SAndroid Build Coastguard Worker     // Resource callback handler
144*4a64e381SAndroid Build Coastguard Worker     mResourceCallbackMap.emplace(OT_REST_RESOURCE_PATH_DIAGNOSTICS, &Resource::HandleDiagnosticCallback);
145*4a64e381SAndroid Build Coastguard Worker }
146*4a64e381SAndroid Build Coastguard Worker 
Init(void)147*4a64e381SAndroid Build Coastguard Worker void Resource::Init(void)
148*4a64e381SAndroid Build Coastguard Worker {
149*4a64e381SAndroid Build Coastguard Worker     mInstance = mHost->GetThreadHelper()->GetInstance();
150*4a64e381SAndroid Build Coastguard Worker }
151*4a64e381SAndroid Build Coastguard Worker 
Handle(Request & aRequest,Response & aResponse) const152*4a64e381SAndroid Build Coastguard Worker void Resource::Handle(Request &aRequest, Response &aResponse) const
153*4a64e381SAndroid Build Coastguard Worker {
154*4a64e381SAndroid Build Coastguard Worker     std::string url = aRequest.GetUrl();
155*4a64e381SAndroid Build Coastguard Worker     auto        it  = mResourceMap.find(url);
156*4a64e381SAndroid Build Coastguard Worker 
157*4a64e381SAndroid Build Coastguard Worker     if (it != mResourceMap.end())
158*4a64e381SAndroid Build Coastguard Worker     {
159*4a64e381SAndroid Build Coastguard Worker         ResourceHandler resourceHandler = it->second;
160*4a64e381SAndroid Build Coastguard Worker         (this->*resourceHandler)(aRequest, aResponse);
161*4a64e381SAndroid Build Coastguard Worker     }
162*4a64e381SAndroid Build Coastguard Worker     else
163*4a64e381SAndroid Build Coastguard Worker     {
164*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusResourceNotFound);
165*4a64e381SAndroid Build Coastguard Worker     }
166*4a64e381SAndroid Build Coastguard Worker }
167*4a64e381SAndroid Build Coastguard Worker 
HandleCallback(Request & aRequest,Response & aResponse)168*4a64e381SAndroid Build Coastguard Worker void Resource::HandleCallback(Request &aRequest, Response &aResponse)
169*4a64e381SAndroid Build Coastguard Worker {
170*4a64e381SAndroid Build Coastguard Worker     std::string url = aRequest.GetUrl();
171*4a64e381SAndroid Build Coastguard Worker     auto        it  = mResourceCallbackMap.find(url);
172*4a64e381SAndroid Build Coastguard Worker 
173*4a64e381SAndroid Build Coastguard Worker     if (it != mResourceCallbackMap.end())
174*4a64e381SAndroid Build Coastguard Worker     {
175*4a64e381SAndroid Build Coastguard Worker         ResourceCallbackHandler resourceHandler = it->second;
176*4a64e381SAndroid Build Coastguard Worker         (this->*resourceHandler)(aRequest, aResponse);
177*4a64e381SAndroid Build Coastguard Worker     }
178*4a64e381SAndroid Build Coastguard Worker }
179*4a64e381SAndroid Build Coastguard Worker 
HandleDiagnosticCallback(const Request & aRequest,Response & aResponse)180*4a64e381SAndroid Build Coastguard Worker void Resource::HandleDiagnosticCallback(const Request &aRequest, Response &aResponse)
181*4a64e381SAndroid Build Coastguard Worker {
182*4a64e381SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aRequest);
183*4a64e381SAndroid Build Coastguard Worker     std::vector<std::vector<otNetworkDiagTlv>> diagContentSet;
184*4a64e381SAndroid Build Coastguard Worker     std::string                                body;
185*4a64e381SAndroid Build Coastguard Worker     std::string                                errorCode;
186*4a64e381SAndroid Build Coastguard Worker 
187*4a64e381SAndroid Build Coastguard Worker     auto duration = duration_cast<microseconds>(steady_clock::now() - aResponse.GetStartTime()).count();
188*4a64e381SAndroid Build Coastguard Worker     if (duration >= kDiagCollectTimeout)
189*4a64e381SAndroid Build Coastguard Worker     {
190*4a64e381SAndroid Build Coastguard Worker         DeleteOutDatedDiagnostic();
191*4a64e381SAndroid Build Coastguard Worker 
192*4a64e381SAndroid Build Coastguard Worker         for (auto it = mDiagSet.begin(); it != mDiagSet.end(); ++it)
193*4a64e381SAndroid Build Coastguard Worker         {
194*4a64e381SAndroid Build Coastguard Worker             diagContentSet.push_back(it->second.mDiagContent);
195*4a64e381SAndroid Build Coastguard Worker         }
196*4a64e381SAndroid Build Coastguard Worker 
197*4a64e381SAndroid Build Coastguard Worker         body      = Json::Diag2JsonString(diagContentSet);
198*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
199*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
200*4a64e381SAndroid Build Coastguard Worker         aResponse.SetBody(body);
201*4a64e381SAndroid Build Coastguard Worker         aResponse.SetComplete();
202*4a64e381SAndroid Build Coastguard Worker     }
203*4a64e381SAndroid Build Coastguard Worker }
204*4a64e381SAndroid Build Coastguard Worker 
ErrorHandler(Response & aResponse,HttpStatusCode aErrorCode) const205*4a64e381SAndroid Build Coastguard Worker void Resource::ErrorHandler(Response &aResponse, HttpStatusCode aErrorCode) const
206*4a64e381SAndroid Build Coastguard Worker {
207*4a64e381SAndroid Build Coastguard Worker     std::string errorMessage = GetHttpStatus(aErrorCode);
208*4a64e381SAndroid Build Coastguard Worker     std::string body         = Json::Error2JsonString(aErrorCode, errorMessage);
209*4a64e381SAndroid Build Coastguard Worker 
210*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorMessage);
211*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
212*4a64e381SAndroid Build Coastguard Worker     aResponse.SetComplete();
213*4a64e381SAndroid Build Coastguard Worker }
214*4a64e381SAndroid Build Coastguard Worker 
GetNodeInfo(Response & aResponse) const215*4a64e381SAndroid Build Coastguard Worker void Resource::GetNodeInfo(Response &aResponse) const
216*4a64e381SAndroid Build Coastguard Worker {
217*4a64e381SAndroid Build Coastguard Worker     otbrError       error = OTBR_ERROR_NONE;
218*4a64e381SAndroid Build Coastguard Worker     struct NodeInfo node  = {};
219*4a64e381SAndroid Build Coastguard Worker     otRouterInfo    routerInfo;
220*4a64e381SAndroid Build Coastguard Worker     uint8_t         maxRouterId;
221*4a64e381SAndroid Build Coastguard Worker     std::string     body;
222*4a64e381SAndroid Build Coastguard Worker     std::string     errorCode;
223*4a64e381SAndroid Build Coastguard Worker 
224*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otBorderAgentGetId(mInstance, &node.mBaId) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
225*4a64e381SAndroid Build Coastguard Worker     (void)otThreadGetLeaderData(mInstance, &node.mLeaderData);
226*4a64e381SAndroid Build Coastguard Worker 
227*4a64e381SAndroid Build Coastguard Worker     node.mNumOfRouter = 0;
228*4a64e381SAndroid Build Coastguard Worker     maxRouterId       = otThreadGetMaxRouterId(mInstance);
229*4a64e381SAndroid Build Coastguard Worker     for (uint8_t i = 0; i <= maxRouterId; ++i)
230*4a64e381SAndroid Build Coastguard Worker     {
231*4a64e381SAndroid Build Coastguard Worker         if (otThreadGetRouterInfo(mInstance, i, &routerInfo) != OT_ERROR_NONE)
232*4a64e381SAndroid Build Coastguard Worker         {
233*4a64e381SAndroid Build Coastguard Worker             continue;
234*4a64e381SAndroid Build Coastguard Worker         }
235*4a64e381SAndroid Build Coastguard Worker         ++node.mNumOfRouter;
236*4a64e381SAndroid Build Coastguard Worker     }
237*4a64e381SAndroid Build Coastguard Worker 
238*4a64e381SAndroid Build Coastguard Worker     node.mRole        = GetDeviceRoleName(otThreadGetDeviceRole(mInstance));
239*4a64e381SAndroid Build Coastguard Worker     node.mExtAddress  = reinterpret_cast<const uint8_t *>(otLinkGetExtendedAddress(mInstance));
240*4a64e381SAndroid Build Coastguard Worker     node.mNetworkName = otThreadGetNetworkName(mInstance);
241*4a64e381SAndroid Build Coastguard Worker     node.mRloc16      = otThreadGetRloc16(mInstance);
242*4a64e381SAndroid Build Coastguard Worker     node.mExtPanId    = reinterpret_cast<const uint8_t *>(otThreadGetExtendedPanId(mInstance));
243*4a64e381SAndroid Build Coastguard Worker     node.mRlocAddress = *otThreadGetRloc(mInstance);
244*4a64e381SAndroid Build Coastguard Worker 
245*4a64e381SAndroid Build Coastguard Worker     body = Json::Node2JsonString(node);
246*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
247*4a64e381SAndroid Build Coastguard Worker 
248*4a64e381SAndroid Build Coastguard Worker exit:
249*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_NONE)
250*4a64e381SAndroid Build Coastguard Worker     {
251*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
252*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
253*4a64e381SAndroid Build Coastguard Worker     }
254*4a64e381SAndroid Build Coastguard Worker     else
255*4a64e381SAndroid Build Coastguard Worker     {
256*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
257*4a64e381SAndroid Build Coastguard Worker     }
258*4a64e381SAndroid Build Coastguard Worker }
259*4a64e381SAndroid Build Coastguard Worker 
DeleteNodeInfo(Response & aResponse) const260*4a64e381SAndroid Build Coastguard Worker void Resource::DeleteNodeInfo(Response &aResponse) const
261*4a64e381SAndroid Build Coastguard Worker {
262*4a64e381SAndroid Build Coastguard Worker     otbrError   error = OTBR_ERROR_NONE;
263*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
264*4a64e381SAndroid Build Coastguard Worker 
265*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(mHost->GetThreadHelper()->Detach() == OT_ERROR_NONE, error = OTBR_ERROR_INVALID_STATE);
266*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otInstanceErasePersistentInfo(mInstance) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
267*4a64e381SAndroid Build Coastguard Worker     mHost->Reset();
268*4a64e381SAndroid Build Coastguard Worker 
269*4a64e381SAndroid Build Coastguard Worker exit:
270*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_NONE)
271*4a64e381SAndroid Build Coastguard Worker     {
272*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
273*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
274*4a64e381SAndroid Build Coastguard Worker     }
275*4a64e381SAndroid Build Coastguard Worker     else if (error == OTBR_ERROR_INVALID_STATE)
276*4a64e381SAndroid Build Coastguard Worker     {
277*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusConflict);
278*4a64e381SAndroid Build Coastguard Worker     }
279*4a64e381SAndroid Build Coastguard Worker     else if (error != OTBR_ERROR_NONE)
280*4a64e381SAndroid Build Coastguard Worker     {
281*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
282*4a64e381SAndroid Build Coastguard Worker     }
283*4a64e381SAndroid Build Coastguard Worker }
284*4a64e381SAndroid Build Coastguard Worker 
NodeInfo(const Request & aRequest,Response & aResponse) const285*4a64e381SAndroid Build Coastguard Worker void Resource::NodeInfo(const Request &aRequest, Response &aResponse) const
286*4a64e381SAndroid Build Coastguard Worker {
287*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
288*4a64e381SAndroid Build Coastguard Worker 
289*4a64e381SAndroid Build Coastguard Worker     switch (aRequest.GetMethod())
290*4a64e381SAndroid Build Coastguard Worker     {
291*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kGet:
292*4a64e381SAndroid Build Coastguard Worker         GetNodeInfo(aResponse);
293*4a64e381SAndroid Build Coastguard Worker         break;
294*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kDelete:
295*4a64e381SAndroid Build Coastguard Worker         DeleteNodeInfo(aResponse);
296*4a64e381SAndroid Build Coastguard Worker         break;
297*4a64e381SAndroid Build Coastguard Worker     default:
298*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
299*4a64e381SAndroid Build Coastguard Worker         break;
300*4a64e381SAndroid Build Coastguard Worker     }
301*4a64e381SAndroid Build Coastguard Worker }
302*4a64e381SAndroid Build Coastguard Worker 
GetDataBaId(Response & aResponse) const303*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataBaId(Response &aResponse) const
304*4a64e381SAndroid Build Coastguard Worker {
305*4a64e381SAndroid Build Coastguard Worker     otbrError       error = OTBR_ERROR_NONE;
306*4a64e381SAndroid Build Coastguard Worker     otBorderAgentId id;
307*4a64e381SAndroid Build Coastguard Worker     std::string     body;
308*4a64e381SAndroid Build Coastguard Worker     std::string     errorCode;
309*4a64e381SAndroid Build Coastguard Worker 
310*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otBorderAgentGetId(mInstance, &id) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
311*4a64e381SAndroid Build Coastguard Worker 
312*4a64e381SAndroid Build Coastguard Worker     body = Json::Bytes2HexJsonString(id.mId, sizeof(id));
313*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
314*4a64e381SAndroid Build Coastguard Worker 
315*4a64e381SAndroid Build Coastguard Worker exit:
316*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_NONE)
317*4a64e381SAndroid Build Coastguard Worker     {
318*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
319*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
320*4a64e381SAndroid Build Coastguard Worker     }
321*4a64e381SAndroid Build Coastguard Worker     else
322*4a64e381SAndroid Build Coastguard Worker     {
323*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
324*4a64e381SAndroid Build Coastguard Worker     }
325*4a64e381SAndroid Build Coastguard Worker }
326*4a64e381SAndroid Build Coastguard Worker 
BaId(const Request & aRequest,Response & aResponse) const327*4a64e381SAndroid Build Coastguard Worker void Resource::BaId(const Request &aRequest, Response &aResponse) const
328*4a64e381SAndroid Build Coastguard Worker {
329*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
330*4a64e381SAndroid Build Coastguard Worker 
331*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
332*4a64e381SAndroid Build Coastguard Worker     {
333*4a64e381SAndroid Build Coastguard Worker         GetDataBaId(aResponse);
334*4a64e381SAndroid Build Coastguard Worker     }
335*4a64e381SAndroid Build Coastguard Worker     else
336*4a64e381SAndroid Build Coastguard Worker     {
337*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
338*4a64e381SAndroid Build Coastguard Worker     }
339*4a64e381SAndroid Build Coastguard Worker }
340*4a64e381SAndroid Build Coastguard Worker 
GetDataExtendedAddr(Response & aResponse) const341*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataExtendedAddr(Response &aResponse) const
342*4a64e381SAndroid Build Coastguard Worker {
343*4a64e381SAndroid Build Coastguard Worker     const uint8_t *extAddress = reinterpret_cast<const uint8_t *>(otLinkGetExtendedAddress(mInstance));
344*4a64e381SAndroid Build Coastguard Worker     std::string    errorCode;
345*4a64e381SAndroid Build Coastguard Worker     std::string    body = Json::Bytes2HexJsonString(extAddress, OT_EXT_ADDRESS_SIZE);
346*4a64e381SAndroid Build Coastguard Worker 
347*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
348*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
349*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
350*4a64e381SAndroid Build Coastguard Worker }
351*4a64e381SAndroid Build Coastguard Worker 
ExtendedAddr(const Request & aRequest,Response & aResponse) const352*4a64e381SAndroid Build Coastguard Worker void Resource::ExtendedAddr(const Request &aRequest, Response &aResponse) const
353*4a64e381SAndroid Build Coastguard Worker {
354*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
355*4a64e381SAndroid Build Coastguard Worker 
356*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
357*4a64e381SAndroid Build Coastguard Worker     {
358*4a64e381SAndroid Build Coastguard Worker         GetDataExtendedAddr(aResponse);
359*4a64e381SAndroid Build Coastguard Worker     }
360*4a64e381SAndroid Build Coastguard Worker     else
361*4a64e381SAndroid Build Coastguard Worker     {
362*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
363*4a64e381SAndroid Build Coastguard Worker     }
364*4a64e381SAndroid Build Coastguard Worker }
365*4a64e381SAndroid Build Coastguard Worker 
GetDataState(Response & aResponse) const366*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataState(Response &aResponse) const
367*4a64e381SAndroid Build Coastguard Worker {
368*4a64e381SAndroid Build Coastguard Worker     std::string  state;
369*4a64e381SAndroid Build Coastguard Worker     std::string  errorCode;
370*4a64e381SAndroid Build Coastguard Worker     otDeviceRole role;
371*4a64e381SAndroid Build Coastguard Worker 
372*4a64e381SAndroid Build Coastguard Worker     role  = otThreadGetDeviceRole(mInstance);
373*4a64e381SAndroid Build Coastguard Worker     state = Json::String2JsonString(GetDeviceRoleName(role));
374*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(state);
375*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
376*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
377*4a64e381SAndroid Build Coastguard Worker }
378*4a64e381SAndroid Build Coastguard Worker 
SetDataState(const Request & aRequest,Response & aResponse) const379*4a64e381SAndroid Build Coastguard Worker void Resource::SetDataState(const Request &aRequest, Response &aResponse) const
380*4a64e381SAndroid Build Coastguard Worker {
381*4a64e381SAndroid Build Coastguard Worker     otbrError   error = OTBR_ERROR_NONE;
382*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
383*4a64e381SAndroid Build Coastguard Worker     std::string body;
384*4a64e381SAndroid Build Coastguard Worker 
385*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(Json::JsonString2String(aRequest.GetBody(), body), error = OTBR_ERROR_INVALID_ARGS);
386*4a64e381SAndroid Build Coastguard Worker     if (body == "enable")
387*4a64e381SAndroid Build Coastguard Worker     {
388*4a64e381SAndroid Build Coastguard Worker         if (!otIp6IsEnabled(mInstance))
389*4a64e381SAndroid Build Coastguard Worker         {
390*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(otIp6SetEnabled(mInstance, true) == OT_ERROR_NONE, error = OTBR_ERROR_INVALID_STATE);
391*4a64e381SAndroid Build Coastguard Worker         }
392*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otThreadSetEnabled(mInstance, true) == OT_ERROR_NONE, error = OTBR_ERROR_INVALID_STATE);
393*4a64e381SAndroid Build Coastguard Worker     }
394*4a64e381SAndroid Build Coastguard Worker     else if (body == "disable")
395*4a64e381SAndroid Build Coastguard Worker     {
396*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otThreadSetEnabled(mInstance, false) == OT_ERROR_NONE, error = OTBR_ERROR_INVALID_STATE);
397*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otIp6SetEnabled(mInstance, false) == OT_ERROR_NONE, error = OTBR_ERROR_INVALID_STATE);
398*4a64e381SAndroid Build Coastguard Worker     }
399*4a64e381SAndroid Build Coastguard Worker     else
400*4a64e381SAndroid Build Coastguard Worker     {
401*4a64e381SAndroid Build Coastguard Worker         ExitNow(error = OTBR_ERROR_INVALID_ARGS);
402*4a64e381SAndroid Build Coastguard Worker     }
403*4a64e381SAndroid Build Coastguard Worker 
404*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
405*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
406*4a64e381SAndroid Build Coastguard Worker 
407*4a64e381SAndroid Build Coastguard Worker exit:
408*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_INVALID_STATE)
409*4a64e381SAndroid Build Coastguard Worker     {
410*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusConflict);
411*4a64e381SAndroid Build Coastguard Worker     }
412*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_INVALID_ARGS)
413*4a64e381SAndroid Build Coastguard Worker     {
414*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusBadRequest);
415*4a64e381SAndroid Build Coastguard Worker     }
416*4a64e381SAndroid Build Coastguard Worker     else if (error != OTBR_ERROR_NONE)
417*4a64e381SAndroid Build Coastguard Worker     {
418*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
419*4a64e381SAndroid Build Coastguard Worker     }
420*4a64e381SAndroid Build Coastguard Worker }
421*4a64e381SAndroid Build Coastguard Worker 
State(const Request & aRequest,Response & aResponse) const422*4a64e381SAndroid Build Coastguard Worker void Resource::State(const Request &aRequest, Response &aResponse) const
423*4a64e381SAndroid Build Coastguard Worker {
424*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
425*4a64e381SAndroid Build Coastguard Worker 
426*4a64e381SAndroid Build Coastguard Worker     switch (aRequest.GetMethod())
427*4a64e381SAndroid Build Coastguard Worker     {
428*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kGet:
429*4a64e381SAndroid Build Coastguard Worker         GetDataState(aResponse);
430*4a64e381SAndroid Build Coastguard Worker         break;
431*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kPut:
432*4a64e381SAndroid Build Coastguard Worker         SetDataState(aRequest, aResponse);
433*4a64e381SAndroid Build Coastguard Worker         break;
434*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kOptions:
435*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
436*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
437*4a64e381SAndroid Build Coastguard Worker         aResponse.SetComplete();
438*4a64e381SAndroid Build Coastguard Worker         break;
439*4a64e381SAndroid Build Coastguard Worker     default:
440*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
441*4a64e381SAndroid Build Coastguard Worker         break;
442*4a64e381SAndroid Build Coastguard Worker     }
443*4a64e381SAndroid Build Coastguard Worker }
444*4a64e381SAndroid Build Coastguard Worker 
GetDataNetworkName(Response & aResponse) const445*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataNetworkName(Response &aResponse) const
446*4a64e381SAndroid Build Coastguard Worker {
447*4a64e381SAndroid Build Coastguard Worker     std::string networkName;
448*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
449*4a64e381SAndroid Build Coastguard Worker 
450*4a64e381SAndroid Build Coastguard Worker     networkName = otThreadGetNetworkName(mInstance);
451*4a64e381SAndroid Build Coastguard Worker     networkName = Json::String2JsonString(networkName);
452*4a64e381SAndroid Build Coastguard Worker 
453*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(networkName);
454*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
455*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
456*4a64e381SAndroid Build Coastguard Worker }
457*4a64e381SAndroid Build Coastguard Worker 
NetworkName(const Request & aRequest,Response & aResponse) const458*4a64e381SAndroid Build Coastguard Worker void Resource::NetworkName(const Request &aRequest, Response &aResponse) const
459*4a64e381SAndroid Build Coastguard Worker {
460*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
461*4a64e381SAndroid Build Coastguard Worker 
462*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
463*4a64e381SAndroid Build Coastguard Worker     {
464*4a64e381SAndroid Build Coastguard Worker         GetDataNetworkName(aResponse);
465*4a64e381SAndroid Build Coastguard Worker     }
466*4a64e381SAndroid Build Coastguard Worker     else
467*4a64e381SAndroid Build Coastguard Worker     {
468*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
469*4a64e381SAndroid Build Coastguard Worker     }
470*4a64e381SAndroid Build Coastguard Worker }
471*4a64e381SAndroid Build Coastguard Worker 
GetDataLeaderData(Response & aResponse) const472*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataLeaderData(Response &aResponse) const
473*4a64e381SAndroid Build Coastguard Worker {
474*4a64e381SAndroid Build Coastguard Worker     otbrError    error = OTBR_ERROR_NONE;
475*4a64e381SAndroid Build Coastguard Worker     otLeaderData leaderData;
476*4a64e381SAndroid Build Coastguard Worker     std::string  body;
477*4a64e381SAndroid Build Coastguard Worker     std::string  errorCode;
478*4a64e381SAndroid Build Coastguard Worker 
479*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otThreadGetLeaderData(mInstance, &leaderData) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
480*4a64e381SAndroid Build Coastguard Worker 
481*4a64e381SAndroid Build Coastguard Worker     body = Json::LeaderData2JsonString(leaderData);
482*4a64e381SAndroid Build Coastguard Worker 
483*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
484*4a64e381SAndroid Build Coastguard Worker 
485*4a64e381SAndroid Build Coastguard Worker exit:
486*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_NONE)
487*4a64e381SAndroid Build Coastguard Worker     {
488*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
489*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
490*4a64e381SAndroid Build Coastguard Worker     }
491*4a64e381SAndroid Build Coastguard Worker     else
492*4a64e381SAndroid Build Coastguard Worker     {
493*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
494*4a64e381SAndroid Build Coastguard Worker     }
495*4a64e381SAndroid Build Coastguard Worker }
496*4a64e381SAndroid Build Coastguard Worker 
LeaderData(const Request & aRequest,Response & aResponse) const497*4a64e381SAndroid Build Coastguard Worker void Resource::LeaderData(const Request &aRequest, Response &aResponse) const
498*4a64e381SAndroid Build Coastguard Worker {
499*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
500*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
501*4a64e381SAndroid Build Coastguard Worker     {
502*4a64e381SAndroid Build Coastguard Worker         GetDataLeaderData(aResponse);
503*4a64e381SAndroid Build Coastguard Worker     }
504*4a64e381SAndroid Build Coastguard Worker     else
505*4a64e381SAndroid Build Coastguard Worker     {
506*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
507*4a64e381SAndroid Build Coastguard Worker     }
508*4a64e381SAndroid Build Coastguard Worker }
509*4a64e381SAndroid Build Coastguard Worker 
GetDataNumOfRoute(Response & aResponse) const510*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataNumOfRoute(Response &aResponse) const
511*4a64e381SAndroid Build Coastguard Worker {
512*4a64e381SAndroid Build Coastguard Worker     uint8_t      count = 0;
513*4a64e381SAndroid Build Coastguard Worker     uint8_t      maxRouterId;
514*4a64e381SAndroid Build Coastguard Worker     otRouterInfo routerInfo;
515*4a64e381SAndroid Build Coastguard Worker     maxRouterId = otThreadGetMaxRouterId(mInstance);
516*4a64e381SAndroid Build Coastguard Worker     std::string body;
517*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
518*4a64e381SAndroid Build Coastguard Worker 
519*4a64e381SAndroid Build Coastguard Worker     for (uint8_t i = 0; i <= maxRouterId; ++i)
520*4a64e381SAndroid Build Coastguard Worker     {
521*4a64e381SAndroid Build Coastguard Worker         if (otThreadGetRouterInfo(mInstance, i, &routerInfo) != OT_ERROR_NONE)
522*4a64e381SAndroid Build Coastguard Worker         {
523*4a64e381SAndroid Build Coastguard Worker             continue;
524*4a64e381SAndroid Build Coastguard Worker         }
525*4a64e381SAndroid Build Coastguard Worker         ++count;
526*4a64e381SAndroid Build Coastguard Worker     }
527*4a64e381SAndroid Build Coastguard Worker 
528*4a64e381SAndroid Build Coastguard Worker     body = Json::Number2JsonString(count);
529*4a64e381SAndroid Build Coastguard Worker 
530*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
531*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
532*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
533*4a64e381SAndroid Build Coastguard Worker }
534*4a64e381SAndroid Build Coastguard Worker 
NumOfRoute(const Request & aRequest,Response & aResponse) const535*4a64e381SAndroid Build Coastguard Worker void Resource::NumOfRoute(const Request &aRequest, Response &aResponse) const
536*4a64e381SAndroid Build Coastguard Worker {
537*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
538*4a64e381SAndroid Build Coastguard Worker 
539*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
540*4a64e381SAndroid Build Coastguard Worker     {
541*4a64e381SAndroid Build Coastguard Worker         GetDataNumOfRoute(aResponse);
542*4a64e381SAndroid Build Coastguard Worker     }
543*4a64e381SAndroid Build Coastguard Worker     else
544*4a64e381SAndroid Build Coastguard Worker     {
545*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
546*4a64e381SAndroid Build Coastguard Worker     }
547*4a64e381SAndroid Build Coastguard Worker }
548*4a64e381SAndroid Build Coastguard Worker 
GetDataRloc16(Response & aResponse) const549*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataRloc16(Response &aResponse) const
550*4a64e381SAndroid Build Coastguard Worker {
551*4a64e381SAndroid Build Coastguard Worker     uint16_t    rloc16 = otThreadGetRloc16(mInstance);
552*4a64e381SAndroid Build Coastguard Worker     std::string body;
553*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
554*4a64e381SAndroid Build Coastguard Worker 
555*4a64e381SAndroid Build Coastguard Worker     body = Json::Number2JsonString(rloc16);
556*4a64e381SAndroid Build Coastguard Worker 
557*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
558*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
559*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
560*4a64e381SAndroid Build Coastguard Worker }
561*4a64e381SAndroid Build Coastguard Worker 
Rloc16(const Request & aRequest,Response & aResponse) const562*4a64e381SAndroid Build Coastguard Worker void Resource::Rloc16(const Request &aRequest, Response &aResponse) const
563*4a64e381SAndroid Build Coastguard Worker {
564*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
565*4a64e381SAndroid Build Coastguard Worker 
566*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
567*4a64e381SAndroid Build Coastguard Worker     {
568*4a64e381SAndroid Build Coastguard Worker         GetDataRloc16(aResponse);
569*4a64e381SAndroid Build Coastguard Worker     }
570*4a64e381SAndroid Build Coastguard Worker     else
571*4a64e381SAndroid Build Coastguard Worker     {
572*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
573*4a64e381SAndroid Build Coastguard Worker     }
574*4a64e381SAndroid Build Coastguard Worker }
575*4a64e381SAndroid Build Coastguard Worker 
GetDataExtendedPanId(Response & aResponse) const576*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataExtendedPanId(Response &aResponse) const
577*4a64e381SAndroid Build Coastguard Worker {
578*4a64e381SAndroid Build Coastguard Worker     const uint8_t *extPanId = reinterpret_cast<const uint8_t *>(otThreadGetExtendedPanId(mInstance));
579*4a64e381SAndroid Build Coastguard Worker     std::string    body     = Json::Bytes2HexJsonString(extPanId, OT_EXT_PAN_ID_SIZE);
580*4a64e381SAndroid Build Coastguard Worker     std::string    errorCode;
581*4a64e381SAndroid Build Coastguard Worker 
582*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
583*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
584*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
585*4a64e381SAndroid Build Coastguard Worker }
586*4a64e381SAndroid Build Coastguard Worker 
ExtendedPanId(const Request & aRequest,Response & aResponse) const587*4a64e381SAndroid Build Coastguard Worker void Resource::ExtendedPanId(const Request &aRequest, Response &aResponse) const
588*4a64e381SAndroid Build Coastguard Worker {
589*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
590*4a64e381SAndroid Build Coastguard Worker 
591*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
592*4a64e381SAndroid Build Coastguard Worker     {
593*4a64e381SAndroid Build Coastguard Worker         GetDataExtendedPanId(aResponse);
594*4a64e381SAndroid Build Coastguard Worker     }
595*4a64e381SAndroid Build Coastguard Worker     else
596*4a64e381SAndroid Build Coastguard Worker     {
597*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
598*4a64e381SAndroid Build Coastguard Worker     }
599*4a64e381SAndroid Build Coastguard Worker }
600*4a64e381SAndroid Build Coastguard Worker 
GetDataRloc(Response & aResponse) const601*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataRloc(Response &aResponse) const
602*4a64e381SAndroid Build Coastguard Worker {
603*4a64e381SAndroid Build Coastguard Worker     otIp6Address rlocAddress = *otThreadGetRloc(mInstance);
604*4a64e381SAndroid Build Coastguard Worker     std::string  body;
605*4a64e381SAndroid Build Coastguard Worker     std::string  errorCode;
606*4a64e381SAndroid Build Coastguard Worker 
607*4a64e381SAndroid Build Coastguard Worker     body = Json::IpAddr2JsonString(rlocAddress);
608*4a64e381SAndroid Build Coastguard Worker 
609*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
610*4a64e381SAndroid Build Coastguard Worker     errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
611*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
612*4a64e381SAndroid Build Coastguard Worker }
613*4a64e381SAndroid Build Coastguard Worker 
Rloc(const Request & aRequest,Response & aResponse) const614*4a64e381SAndroid Build Coastguard Worker void Resource::Rloc(const Request &aRequest, Response &aResponse) const
615*4a64e381SAndroid Build Coastguard Worker {
616*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
617*4a64e381SAndroid Build Coastguard Worker 
618*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetMethod() == HttpMethod::kGet)
619*4a64e381SAndroid Build Coastguard Worker     {
620*4a64e381SAndroid Build Coastguard Worker         GetDataRloc(aResponse);
621*4a64e381SAndroid Build Coastguard Worker     }
622*4a64e381SAndroid Build Coastguard Worker     else
623*4a64e381SAndroid Build Coastguard Worker     {
624*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
625*4a64e381SAndroid Build Coastguard Worker     }
626*4a64e381SAndroid Build Coastguard Worker }
627*4a64e381SAndroid Build Coastguard Worker 
GetDataset(DatasetType aDatasetType,const Request & aRequest,Response & aResponse) const628*4a64e381SAndroid Build Coastguard Worker void Resource::GetDataset(DatasetType aDatasetType, const Request &aRequest, Response &aResponse) const
629*4a64e381SAndroid Build Coastguard Worker {
630*4a64e381SAndroid Build Coastguard Worker     otbrError                error = OTBR_ERROR_NONE;
631*4a64e381SAndroid Build Coastguard Worker     struct NodeInfo          node;
632*4a64e381SAndroid Build Coastguard Worker     std::string              body;
633*4a64e381SAndroid Build Coastguard Worker     std::string              errorCode;
634*4a64e381SAndroid Build Coastguard Worker     otOperationalDataset     dataset;
635*4a64e381SAndroid Build Coastguard Worker     otOperationalDatasetTlvs datasetTlvs;
636*4a64e381SAndroid Build Coastguard Worker 
637*4a64e381SAndroid Build Coastguard Worker     if (aRequest.GetHeaderValue(OT_REST_ACCEPT_HEADER) == OT_REST_CONTENT_TYPE_PLAIN)
638*4a64e381SAndroid Build Coastguard Worker     {
639*4a64e381SAndroid Build Coastguard Worker         if (aDatasetType == DatasetType::kActive)
640*4a64e381SAndroid Build Coastguard Worker         {
641*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(otDatasetGetActiveTlvs(mInstance, &datasetTlvs) == OT_ERROR_NONE,
642*4a64e381SAndroid Build Coastguard Worker                          error = OTBR_ERROR_NOT_FOUND);
643*4a64e381SAndroid Build Coastguard Worker         }
644*4a64e381SAndroid Build Coastguard Worker         else if (aDatasetType == DatasetType::kPending)
645*4a64e381SAndroid Build Coastguard Worker         {
646*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(otDatasetGetPendingTlvs(mInstance, &datasetTlvs) == OT_ERROR_NONE,
647*4a64e381SAndroid Build Coastguard Worker                          error = OTBR_ERROR_NOT_FOUND);
648*4a64e381SAndroid Build Coastguard Worker         }
649*4a64e381SAndroid Build Coastguard Worker 
650*4a64e381SAndroid Build Coastguard Worker         aResponse.SetContentType(OT_REST_CONTENT_TYPE_PLAIN);
651*4a64e381SAndroid Build Coastguard Worker         body = Utils::Bytes2Hex(datasetTlvs.mTlvs, datasetTlvs.mLength);
652*4a64e381SAndroid Build Coastguard Worker     }
653*4a64e381SAndroid Build Coastguard Worker     else
654*4a64e381SAndroid Build Coastguard Worker     {
655*4a64e381SAndroid Build Coastguard Worker         if (aDatasetType == DatasetType::kActive)
656*4a64e381SAndroid Build Coastguard Worker         {
657*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(otDatasetGetActive(mInstance, &dataset) == OT_ERROR_NONE, error = OTBR_ERROR_NOT_FOUND);
658*4a64e381SAndroid Build Coastguard Worker             body = Json::ActiveDataset2JsonString(dataset);
659*4a64e381SAndroid Build Coastguard Worker         }
660*4a64e381SAndroid Build Coastguard Worker         else if (aDatasetType == DatasetType::kPending)
661*4a64e381SAndroid Build Coastguard Worker         {
662*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(otDatasetGetPending(mInstance, &dataset) == OT_ERROR_NONE, error = OTBR_ERROR_NOT_FOUND);
663*4a64e381SAndroid Build Coastguard Worker             body = Json::PendingDataset2JsonString(dataset);
664*4a64e381SAndroid Build Coastguard Worker         }
665*4a64e381SAndroid Build Coastguard Worker     }
666*4a64e381SAndroid Build Coastguard Worker 
667*4a64e381SAndroid Build Coastguard Worker     aResponse.SetBody(body);
668*4a64e381SAndroid Build Coastguard Worker 
669*4a64e381SAndroid Build Coastguard Worker exit:
670*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_NONE)
671*4a64e381SAndroid Build Coastguard Worker     {
672*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
673*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
674*4a64e381SAndroid Build Coastguard Worker     }
675*4a64e381SAndroid Build Coastguard Worker     else if (error == OTBR_ERROR_NOT_FOUND)
676*4a64e381SAndroid Build Coastguard Worker     {
677*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusNoContent);
678*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
679*4a64e381SAndroid Build Coastguard Worker     }
680*4a64e381SAndroid Build Coastguard Worker     else
681*4a64e381SAndroid Build Coastguard Worker     {
682*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
683*4a64e381SAndroid Build Coastguard Worker     }
684*4a64e381SAndroid Build Coastguard Worker }
685*4a64e381SAndroid Build Coastguard Worker 
SetDataset(DatasetType aDatasetType,const Request & aRequest,Response & aResponse) const686*4a64e381SAndroid Build Coastguard Worker void Resource::SetDataset(DatasetType aDatasetType, const Request &aRequest, Response &aResponse) const
687*4a64e381SAndroid Build Coastguard Worker {
688*4a64e381SAndroid Build Coastguard Worker     otError                  errorOt = OT_ERROR_NONE;
689*4a64e381SAndroid Build Coastguard Worker     otbrError                error   = OTBR_ERROR_NONE;
690*4a64e381SAndroid Build Coastguard Worker     struct NodeInfo          node;
691*4a64e381SAndroid Build Coastguard Worker     std::string              body;
692*4a64e381SAndroid Build Coastguard Worker     std::string              errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
693*4a64e381SAndroid Build Coastguard Worker     otOperationalDataset     dataset   = {};
694*4a64e381SAndroid Build Coastguard Worker     otOperationalDatasetTlvs datasetTlvs;
695*4a64e381SAndroid Build Coastguard Worker     otOperationalDatasetTlvs datasetUpdateTlvs;
696*4a64e381SAndroid Build Coastguard Worker     int                      ret;
697*4a64e381SAndroid Build Coastguard Worker     bool                     isTlv;
698*4a64e381SAndroid Build Coastguard Worker 
699*4a64e381SAndroid Build Coastguard Worker     if (aDatasetType == DatasetType::kActive)
700*4a64e381SAndroid Build Coastguard Worker     {
701*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otThreadGetDeviceRole(mInstance) == OT_DEVICE_ROLE_DISABLED, error = OTBR_ERROR_INVALID_STATE);
702*4a64e381SAndroid Build Coastguard Worker         errorOt = otDatasetGetActiveTlvs(mInstance, &datasetTlvs);
703*4a64e381SAndroid Build Coastguard Worker     }
704*4a64e381SAndroid Build Coastguard Worker     else if (aDatasetType == DatasetType::kPending)
705*4a64e381SAndroid Build Coastguard Worker     {
706*4a64e381SAndroid Build Coastguard Worker         errorOt = otDatasetGetPendingTlvs(mInstance, &datasetTlvs);
707*4a64e381SAndroid Build Coastguard Worker     }
708*4a64e381SAndroid Build Coastguard Worker 
709*4a64e381SAndroid Build Coastguard Worker     // Create a new operational dataset if it doesn't exist.
710*4a64e381SAndroid Build Coastguard Worker     if (errorOt == OT_ERROR_NOT_FOUND)
711*4a64e381SAndroid Build Coastguard Worker     {
712*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otDatasetCreateNewNetwork(mInstance, &dataset) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
713*4a64e381SAndroid Build Coastguard Worker         otDatasetConvertToTlvs(&dataset, &datasetTlvs);
714*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusCreated);
715*4a64e381SAndroid Build Coastguard Worker     }
716*4a64e381SAndroid Build Coastguard Worker 
717*4a64e381SAndroid Build Coastguard Worker     isTlv = aRequest.GetHeaderValue(OT_REST_CONTENT_TYPE_HEADER) == OT_REST_CONTENT_TYPE_PLAIN;
718*4a64e381SAndroid Build Coastguard Worker 
719*4a64e381SAndroid Build Coastguard Worker     if (isTlv)
720*4a64e381SAndroid Build Coastguard Worker     {
721*4a64e381SAndroid Build Coastguard Worker         ret = Json::Hex2BytesJsonString(aRequest.GetBody(), datasetUpdateTlvs.mTlvs, OT_OPERATIONAL_DATASET_MAX_LENGTH);
722*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(ret >= 0, error = OTBR_ERROR_INVALID_ARGS);
723*4a64e381SAndroid Build Coastguard Worker         datasetUpdateTlvs.mLength = ret;
724*4a64e381SAndroid Build Coastguard Worker 
725*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otDatasetParseTlvs(&datasetUpdateTlvs, &dataset) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
726*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otDatasetUpdateTlvs(&dataset, &datasetTlvs) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
727*4a64e381SAndroid Build Coastguard Worker     }
728*4a64e381SAndroid Build Coastguard Worker     else
729*4a64e381SAndroid Build Coastguard Worker     {
730*4a64e381SAndroid Build Coastguard Worker         if (aDatasetType == DatasetType::kActive)
731*4a64e381SAndroid Build Coastguard Worker         {
732*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(Json::JsonActiveDatasetString2Dataset(aRequest.GetBody(), dataset),
733*4a64e381SAndroid Build Coastguard Worker                          error = OTBR_ERROR_INVALID_ARGS);
734*4a64e381SAndroid Build Coastguard Worker         }
735*4a64e381SAndroid Build Coastguard Worker         else if (aDatasetType == DatasetType::kPending)
736*4a64e381SAndroid Build Coastguard Worker         {
737*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(Json::JsonPendingDatasetString2Dataset(aRequest.GetBody(), dataset),
738*4a64e381SAndroid Build Coastguard Worker                          error = OTBR_ERROR_INVALID_ARGS);
739*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(dataset.mComponents.mIsDelayPresent, error = OTBR_ERROR_INVALID_ARGS);
740*4a64e381SAndroid Build Coastguard Worker         }
741*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otDatasetUpdateTlvs(&dataset, &datasetTlvs) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
742*4a64e381SAndroid Build Coastguard Worker     }
743*4a64e381SAndroid Build Coastguard Worker 
744*4a64e381SAndroid Build Coastguard Worker     if (aDatasetType == DatasetType::kActive)
745*4a64e381SAndroid Build Coastguard Worker     {
746*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otDatasetSetActiveTlvs(mInstance, &datasetTlvs) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
747*4a64e381SAndroid Build Coastguard Worker     }
748*4a64e381SAndroid Build Coastguard Worker     else if (aDatasetType == DatasetType::kPending)
749*4a64e381SAndroid Build Coastguard Worker     {
750*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(otDatasetSetPendingTlvs(mInstance, &datasetTlvs) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
751*4a64e381SAndroid Build Coastguard Worker     }
752*4a64e381SAndroid Build Coastguard Worker 
753*4a64e381SAndroid Build Coastguard Worker     aResponse.SetResponsCode(errorCode);
754*4a64e381SAndroid Build Coastguard Worker 
755*4a64e381SAndroid Build Coastguard Worker exit:
756*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_INVALID_ARGS)
757*4a64e381SAndroid Build Coastguard Worker     {
758*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusBadRequest);
759*4a64e381SAndroid Build Coastguard Worker     }
760*4a64e381SAndroid Build Coastguard Worker     else if (error == OTBR_ERROR_INVALID_STATE)
761*4a64e381SAndroid Build Coastguard Worker     {
762*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusConflict);
763*4a64e381SAndroid Build Coastguard Worker     }
764*4a64e381SAndroid Build Coastguard Worker     else if (error != OTBR_ERROR_NONE)
765*4a64e381SAndroid Build Coastguard Worker     {
766*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
767*4a64e381SAndroid Build Coastguard Worker     }
768*4a64e381SAndroid Build Coastguard Worker }
769*4a64e381SAndroid Build Coastguard Worker 
Dataset(DatasetType aDatasetType,const Request & aRequest,Response & aResponse) const770*4a64e381SAndroid Build Coastguard Worker void Resource::Dataset(DatasetType aDatasetType, const Request &aRequest, Response &aResponse) const
771*4a64e381SAndroid Build Coastguard Worker {
772*4a64e381SAndroid Build Coastguard Worker     std::string errorCode;
773*4a64e381SAndroid Build Coastguard Worker 
774*4a64e381SAndroid Build Coastguard Worker     switch (aRequest.GetMethod())
775*4a64e381SAndroid Build Coastguard Worker     {
776*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kGet:
777*4a64e381SAndroid Build Coastguard Worker         GetDataset(aDatasetType, aRequest, aResponse);
778*4a64e381SAndroid Build Coastguard Worker         break;
779*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kPut:
780*4a64e381SAndroid Build Coastguard Worker         SetDataset(aDatasetType, aRequest, aResponse);
781*4a64e381SAndroid Build Coastguard Worker         break;
782*4a64e381SAndroid Build Coastguard Worker     case HttpMethod::kOptions:
783*4a64e381SAndroid Build Coastguard Worker         errorCode = GetHttpStatus(HttpStatusCode::kStatusOk);
784*4a64e381SAndroid Build Coastguard Worker         aResponse.SetResponsCode(errorCode);
785*4a64e381SAndroid Build Coastguard Worker         aResponse.SetComplete();
786*4a64e381SAndroid Build Coastguard Worker         break;
787*4a64e381SAndroid Build Coastguard Worker     default:
788*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusMethodNotAllowed);
789*4a64e381SAndroid Build Coastguard Worker         break;
790*4a64e381SAndroid Build Coastguard Worker     }
791*4a64e381SAndroid Build Coastguard Worker }
792*4a64e381SAndroid Build Coastguard Worker 
DatasetActive(const Request & aRequest,Response & aResponse) const793*4a64e381SAndroid Build Coastguard Worker void Resource::DatasetActive(const Request &aRequest, Response &aResponse) const
794*4a64e381SAndroid Build Coastguard Worker {
795*4a64e381SAndroid Build Coastguard Worker     Dataset(DatasetType::kActive, aRequest, aResponse);
796*4a64e381SAndroid Build Coastguard Worker }
797*4a64e381SAndroid Build Coastguard Worker 
DatasetPending(const Request & aRequest,Response & aResponse) const798*4a64e381SAndroid Build Coastguard Worker void Resource::DatasetPending(const Request &aRequest, Response &aResponse) const
799*4a64e381SAndroid Build Coastguard Worker {
800*4a64e381SAndroid Build Coastguard Worker     Dataset(DatasetType::kPending, aRequest, aResponse);
801*4a64e381SAndroid Build Coastguard Worker }
802*4a64e381SAndroid Build Coastguard Worker 
DeleteOutDatedDiagnostic(void)803*4a64e381SAndroid Build Coastguard Worker void Resource::DeleteOutDatedDiagnostic(void)
804*4a64e381SAndroid Build Coastguard Worker {
805*4a64e381SAndroid Build Coastguard Worker     auto eraseIt = mDiagSet.begin();
806*4a64e381SAndroid Build Coastguard Worker     for (eraseIt = mDiagSet.begin(); eraseIt != mDiagSet.end();)
807*4a64e381SAndroid Build Coastguard Worker     {
808*4a64e381SAndroid Build Coastguard Worker         auto diagInfo = eraseIt->second;
809*4a64e381SAndroid Build Coastguard Worker         auto duration = duration_cast<microseconds>(steady_clock::now() - diagInfo.mStartTime).count();
810*4a64e381SAndroid Build Coastguard Worker 
811*4a64e381SAndroid Build Coastguard Worker         if (duration >= kDiagResetTimeout)
812*4a64e381SAndroid Build Coastguard Worker         {
813*4a64e381SAndroid Build Coastguard Worker             eraseIt = mDiagSet.erase(eraseIt);
814*4a64e381SAndroid Build Coastguard Worker         }
815*4a64e381SAndroid Build Coastguard Worker         else
816*4a64e381SAndroid Build Coastguard Worker         {
817*4a64e381SAndroid Build Coastguard Worker             eraseIt++;
818*4a64e381SAndroid Build Coastguard Worker         }
819*4a64e381SAndroid Build Coastguard Worker     }
820*4a64e381SAndroid Build Coastguard Worker }
821*4a64e381SAndroid Build Coastguard Worker 
UpdateDiag(std::string aKey,std::vector<otNetworkDiagTlv> & aDiag)822*4a64e381SAndroid Build Coastguard Worker void Resource::UpdateDiag(std::string aKey, std::vector<otNetworkDiagTlv> &aDiag)
823*4a64e381SAndroid Build Coastguard Worker {
824*4a64e381SAndroid Build Coastguard Worker     DiagInfo value;
825*4a64e381SAndroid Build Coastguard Worker 
826*4a64e381SAndroid Build Coastguard Worker     value.mStartTime = steady_clock::now();
827*4a64e381SAndroid Build Coastguard Worker     value.mDiagContent.assign(aDiag.begin(), aDiag.end());
828*4a64e381SAndroid Build Coastguard Worker     mDiagSet[aKey] = value;
829*4a64e381SAndroid Build Coastguard Worker }
830*4a64e381SAndroid Build Coastguard Worker 
Diagnostic(const Request & aRequest,Response & aResponse) const831*4a64e381SAndroid Build Coastguard Worker void Resource::Diagnostic(const Request &aRequest, Response &aResponse) const
832*4a64e381SAndroid Build Coastguard Worker {
833*4a64e381SAndroid Build Coastguard Worker     otbrError error = OTBR_ERROR_NONE;
834*4a64e381SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aRequest);
835*4a64e381SAndroid Build Coastguard Worker     struct otIp6Address rloc16address = *otThreadGetRloc(mInstance);
836*4a64e381SAndroid Build Coastguard Worker     struct otIp6Address multicastAddress;
837*4a64e381SAndroid Build Coastguard Worker 
838*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otThreadSendDiagnosticGet(mInstance, &rloc16address, kAllTlvTypes, sizeof(kAllTlvTypes),
839*4a64e381SAndroid Build Coastguard Worker                                            &Resource::DiagnosticResponseHandler,
840*4a64e381SAndroid Build Coastguard Worker                                            const_cast<Resource *>(this)) == OT_ERROR_NONE,
841*4a64e381SAndroid Build Coastguard Worker                  error = OTBR_ERROR_REST);
842*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otIp6AddressFromString(kMulticastAddrAllRouters, &multicastAddress) == OT_ERROR_NONE,
843*4a64e381SAndroid Build Coastguard Worker                  error = OTBR_ERROR_REST);
844*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(otThreadSendDiagnosticGet(mInstance, &multicastAddress, kAllTlvTypes, sizeof(kAllTlvTypes),
845*4a64e381SAndroid Build Coastguard Worker                                            &Resource::DiagnosticResponseHandler,
846*4a64e381SAndroid Build Coastguard Worker                                            const_cast<Resource *>(this)) == OT_ERROR_NONE,
847*4a64e381SAndroid Build Coastguard Worker                  error = OTBR_ERROR_REST);
848*4a64e381SAndroid Build Coastguard Worker 
849*4a64e381SAndroid Build Coastguard Worker exit:
850*4a64e381SAndroid Build Coastguard Worker 
851*4a64e381SAndroid Build Coastguard Worker     if (error == OTBR_ERROR_NONE)
852*4a64e381SAndroid Build Coastguard Worker     {
853*4a64e381SAndroid Build Coastguard Worker         aResponse.SetStartTime(steady_clock::now());
854*4a64e381SAndroid Build Coastguard Worker         aResponse.SetCallback();
855*4a64e381SAndroid Build Coastguard Worker     }
856*4a64e381SAndroid Build Coastguard Worker     else
857*4a64e381SAndroid Build Coastguard Worker     {
858*4a64e381SAndroid Build Coastguard Worker         ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
859*4a64e381SAndroid Build Coastguard Worker     }
860*4a64e381SAndroid Build Coastguard Worker }
861*4a64e381SAndroid Build Coastguard Worker 
DiagnosticResponseHandler(otError aError,otMessage * aMessage,const otMessageInfo * aMessageInfo,void * aContext)862*4a64e381SAndroid Build Coastguard Worker void Resource::DiagnosticResponseHandler(otError              aError,
863*4a64e381SAndroid Build Coastguard Worker                                          otMessage           *aMessage,
864*4a64e381SAndroid Build Coastguard Worker                                          const otMessageInfo *aMessageInfo,
865*4a64e381SAndroid Build Coastguard Worker                                          void                *aContext)
866*4a64e381SAndroid Build Coastguard Worker {
867*4a64e381SAndroid Build Coastguard Worker     static_cast<Resource *>(aContext)->DiagnosticResponseHandler(aError, aMessage, aMessageInfo);
868*4a64e381SAndroid Build Coastguard Worker }
869*4a64e381SAndroid Build Coastguard Worker 
DiagnosticResponseHandler(otError aError,const otMessage * aMessage,const otMessageInfo * aMessageInfo)870*4a64e381SAndroid Build Coastguard Worker void Resource::DiagnosticResponseHandler(otError aError, const otMessage *aMessage, const otMessageInfo *aMessageInfo)
871*4a64e381SAndroid Build Coastguard Worker {
872*4a64e381SAndroid Build Coastguard Worker     std::vector<otNetworkDiagTlv> diagSet;
873*4a64e381SAndroid Build Coastguard Worker     otNetworkDiagTlv              diagTlv;
874*4a64e381SAndroid Build Coastguard Worker     otNetworkDiagIterator         iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT;
875*4a64e381SAndroid Build Coastguard Worker     otError                       error;
876*4a64e381SAndroid Build Coastguard Worker     char                          rloc[7];
877*4a64e381SAndroid Build Coastguard Worker     std::string                   keyRloc = "0xffee";
878*4a64e381SAndroid Build Coastguard Worker 
879*4a64e381SAndroid Build Coastguard Worker     SuccessOrExit(aError);
880*4a64e381SAndroid Build Coastguard Worker 
881*4a64e381SAndroid Build Coastguard Worker     OTBR_UNUSED_VARIABLE(aMessageInfo);
882*4a64e381SAndroid Build Coastguard Worker 
883*4a64e381SAndroid Build Coastguard Worker     while ((error = otThreadGetNextDiagnosticTlv(aMessage, &iterator, &diagTlv)) == OT_ERROR_NONE)
884*4a64e381SAndroid Build Coastguard Worker     {
885*4a64e381SAndroid Build Coastguard Worker         if (diagTlv.mType == OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS)
886*4a64e381SAndroid Build Coastguard Worker         {
887*4a64e381SAndroid Build Coastguard Worker             snprintf(rloc, sizeof(rloc), "0x%04x", diagTlv.mData.mAddr16);
888*4a64e381SAndroid Build Coastguard Worker             keyRloc = Json::CString2JsonString(rloc);
889*4a64e381SAndroid Build Coastguard Worker         }
890*4a64e381SAndroid Build Coastguard Worker         diagSet.push_back(diagTlv);
891*4a64e381SAndroid Build Coastguard Worker     }
892*4a64e381SAndroid Build Coastguard Worker     UpdateDiag(keyRloc, diagSet);
893*4a64e381SAndroid Build Coastguard Worker 
894*4a64e381SAndroid Build Coastguard Worker exit:
895*4a64e381SAndroid Build Coastguard Worker     if (aError != OT_ERROR_NONE)
896*4a64e381SAndroid Build Coastguard Worker     {
897*4a64e381SAndroid Build Coastguard Worker         otbrLogWarning("Failed to get diagnostic data: %s", otThreadErrorToString(aError));
898*4a64e381SAndroid Build Coastguard Worker     }
899*4a64e381SAndroid Build Coastguard Worker }
900*4a64e381SAndroid Build Coastguard Worker 
901*4a64e381SAndroid Build Coastguard Worker } // namespace rest
902*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
903