Merge branch 'master' into extended-easysetup
[platform/upstream/iotivity.git] / service / easy-setup / mediator / richsdk / src / EnrolleeResource.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <functional>
22
23 #include "EnrolleeResource.h"
24
25 #include "OCPlatform.h"
26 #include "ESException.h"
27 #include "OCResource.h"
28 #include "logger.h"
29
30 namespace OIC
31 {
32     namespace Service
33     {
34         #define ES_REMOTE_ENROLLEE_RES_TAG "ES_ENROLLEE_RESOURCE"
35
36         EnrolleeResource::EnrolleeResource(std::shared_ptr< OC::OCResource > resource)
37         {
38             m_ocResource = resource;
39         }
40
41         void EnrolleeResource::checkProvInformationCb(const HeaderOptions& /*headerOptions*/,
42                 const OCRepresentation& rep, const int eCode)
43         {
44             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : %s, eCode = %d",
45                     rep.getUri().c_str(),
46                     eCode);
47
48             if (eCode != 0)
49             {
50                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
51                         "checkProvInformationCb : Provisioning is failed ");
52                 std::shared_ptr< DataProvisioningStatus > provStatus = std::make_shared<
53                         DataProvisioningStatus >(ESResult::ES_ERROR, ESDataProvState::ES_PROVISIONING_ERROR);
54                 m_dataProvStatusCb(provStatus);
55                 return;
56             }
57             // int ps = -1;
58             // rep.getValue(OC_RSRVD_ES_PROVSTATUS, ps);
59             // OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : ps - %d", ps);
60
61             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
62                     "checkProvInformationCb : Provisioning is success. "
63                     "Now trigger network connection ");
64
65             std::shared_ptr< DataProvisioningStatus > provStatus = std::make_shared<
66                     DataProvisioningStatus >(ESResult::ES_OK, ESDataProvState::ES_PROVISIONING_SUCCESS);
67             m_dataProvStatusCb(provStatus);
68         }
69
70         void EnrolleeResource::onRequestPropertyDataResponse(const HeaderOptions& /*headerOptions*/,
71                 const OCRepresentation& rep, const int eCode)
72         {
73             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onRequestPropertyDataResponse : %s, eCode = %d",
74                     rep.getUri().c_str(), eCode);
75
76             if (eCode != 0)
77             {
78                 ESResult result  = ESResult::ES_ERROR;
79
80                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,"onRequestPropertyDataResponse : onRequestPropertyDataResponse is failed ");
81
82                 if (eCode == OCStackResult::OC_STACK_UNAUTHORIZED_REQ)
83                 {
84                     OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
85                         "Mediator is unauthorized from Enrollee.");
86                     result = ESResult::ES_UNAUTHORIZED;
87                 }
88
89                 PropertyData propertyData;
90                 std::shared_ptr< RequestPropertyDataStatus > requestPropertyDataStatus = std::make_shared<
91                         RequestPropertyDataStatus >(result, propertyData );
92                 m_RequestPropertyDataStatusCb(requestPropertyDataStatus);
93             }
94
95             else
96             {
97                 PropertyData propertyData = parsePropertyDataFromRepresentation(rep);
98
99                 std::shared_ptr< RequestPropertyDataStatus > requestPropertyDataStatus = std::make_shared<
100                         RequestPropertyDataStatus >(ESResult::ES_OK, propertyData);
101                 m_RequestPropertyDataStatusCb(requestPropertyDataStatus);
102             }
103         }
104
105         void EnrolleeResource::getProvStatusResponse(const HeaderOptions& /*headerOptions*/,
106                 const OCRepresentation& rep, const int eCode)
107         {
108             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : %s, eCode = %d",
109                     rep.getUri().c_str(),
110                     eCode);
111
112             if (eCode != 0)
113             {
114                 ESResult result  = ESResult::ES_ERROR;
115
116                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,"getProvStatusResponse : Provisioning is failed ");
117
118                 if (eCode == OCStackResult::OC_STACK_UNAUTHORIZED_REQ)
119                 {
120                     OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
121                         "Mediator is unauthorized from Enrollee.");
122                     result = ESResult::ES_UNAUTHORIZED;
123                 }
124                 std::shared_ptr< DataProvisioningStatus > provStatus = std::make_shared<
125                         DataProvisioningStatus >(result, ESDataProvState::ES_PROVISIONING_ERROR);
126                 m_dataProvStatusCb(provStatus);
127
128                 return;
129             }
130
131             int ps = -1;
132
133             rep.getValue(OC_RSRVD_ES_PROVSTATUS, ps);
134
135             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : ps - %d",
136                     ps);
137
138             //if (ps == ES_PS_NEED_PROVISIONING) //Indicates the need for provisioning
139             if (ps == 0) //Indicates the need for provisioning
140             {
141                 OCRepresentation provisioningRepresentation;
142
143                 provisioningRepresentation.setValue(OC_RSRVD_ES_SSID, m_dataProvInfo.WIFI.ssid);
144                 provisioningRepresentation.setValue(OC_RSRVD_ES_CRED, m_dataProvInfo.WIFI.pwd);
145                 provisioningRepresentation.setValue(OC_RSRVD_ES_AUTHTYPE, m_dataProvInfo.WIFI.authtype);
146                 provisioningRepresentation.setValue(OC_RSRVD_ES_ENCTYPE, m_dataProvInfo.WIFI.enctype);
147                 provisioningRepresentation.setValue(OC_RSRVD_ES_LANGUAGE, m_dataProvInfo.Device.language);
148                 provisioningRepresentation.setValue(OC_RSRVD_ES_COUNTRY, m_dataProvInfo.Device.country);
149
150                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : ssid - %s",
151                         (m_dataProvInfo.WIFI.ssid).c_str());
152                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : pwd - %s",
153                         (m_dataProvInfo.WIFI.pwd).c_str());
154                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : authtype - %d",
155                         m_dataProvInfo.WIFI.authtype);
156                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : enctype - %d",
157                         m_dataProvInfo.WIFI.enctype);
158                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : language - %s",
159                         (m_dataProvInfo.Device.language).c_str());
160                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : country - %s",
161                         (m_dataProvInfo.Device.country).c_str());
162
163                 m_ocResource->post(OC_RSRVD_ES_PROV_RES_TYPE, BATCH_INTERFACE,
164                         provisioningRepresentation, QueryParamsMap(),
165                         std::function<
166                                 void(const HeaderOptions& headerOptions,
167                                         const OCRepresentation& rep, const int eCode) >(
168                         std::bind(&EnrolleeResource::checkProvInformationCb, this,
169                         std::placeholders::_1, std::placeholders::_2,
170                         std::placeholders::_3)));
171             }
172             else if (ps == ES_PS_PROVISIONING_COMPLETED) //Indicates that provisioning is completed
173             {
174                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
175                         "getProvStatusResponse : Provisioning is successful");
176                 std::shared_ptr< DataProvisioningStatus > provStatus = std::make_shared<
177                         DataProvisioningStatus >(ESResult::ES_OK, ESDataProvState::ES_PROVISIONED_ALREADY);
178                 m_dataProvStatusCb(provStatus);
179             }
180         }
181
182         void EnrolleeResource::registerRequestPropertyDataStatusCallback(RequestPropertyDataStatusCb callback)
183         {
184             m_RequestPropertyDataStatusCb = callback;
185         }
186
187         void EnrolleeResource::registerProvStatusCallback(DataProvStatusCb callback)
188         {
189             m_dataProvStatusCb = callback;
190         }
191
192         void EnrolleeResource::RequestPropertyData()
193         {
194             if (m_ocResource == nullptr)
195             {
196                 throw ESBadRequestException("Resource is not initialized");
197             }
198
199             OC::QueryParamsMap query;
200             OC::OCRepresentation rep;
201
202             std::function< OCStackResult(void) > requestPropertyDataStatus = [&]
203             {   return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
204                         BATCH_INTERFACE, query, std::function<void(const HeaderOptions& headerOptions,
205                         const OCRepresentation& rep, const int eCode) >(
206                                 std::bind(&EnrolleeResource::onRequestPropertyDataResponse, this,
207                                         std::placeholders::_1, std::placeholders::_2,
208                                         std::placeholders::_3)));
209             };
210
211             OCStackResult result = requestPropertyDataStatus();
212
213             if (result != OCStackResult::OC_STACK_OK)
214             {
215                 PropertyData propertyData;
216                 std::shared_ptr< RequestPropertyDataStatus > requestPropertyDataStatus = std::make_shared<
217                         RequestPropertyDataStatus >(ESResult::ES_ERROR, propertyData);
218                 m_RequestPropertyDataStatusCb(requestPropertyDataStatus);
219                 return;
220             }
221         }
222
223         void EnrolleeResource::provisionEnrollee(const DataProvInfo& dataProvInfo)
224
225         {
226             if (m_ocResource == nullptr)
227             {
228                 throw ESBadRequestException("Resource is not initialized");
229             }
230
231             m_dataProvInfo = dataProvInfo;
232
233             OC::QueryParamsMap query;
234             OC::OCRepresentation rep;
235
236             std::function< OCStackResult(void) > getProvisioingStatus = [&]
237             {   return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
238                         m_ocResource->getResourceInterfaces().at(0), query,
239                         std::function<
240                         void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
241                                 const int eCode) >(
242                                 std::bind(&EnrolleeResource::getProvStatusResponse, this,
243                                         std::placeholders::_1, std::placeholders::_2,
244                                         std::placeholders::_3)));
245             };
246
247             OCStackResult result = getProvisioingStatus();
248
249             if (result != OCStackResult::OC_STACK_OK)
250             {
251                 std::shared_ptr< DataProvisioningStatus > provStatus = std::make_shared<
252                         DataProvisioningStatus >(ESResult::ES_ERROR, ESDataProvState::ES_PROVISIONING_ERROR);
253                 m_dataProvStatusCb(provStatus);
254                 return;
255             }
256         }
257
258         void EnrolleeResource::unprovisionEnrollee()
259         {
260             if (m_ocResource == nullptr)
261             {
262                 throw ESBadRequestException("Resource is not initialized");
263             }
264
265             OCRepresentation provisioningRepresentation;
266
267             provisioningRepresentation.setValue(OC_RSRVD_ES_SSID, "");
268             provisioningRepresentation.setValue(OC_RSRVD_ES_CRED, "");
269
270             m_ocResource->post(provisioningRepresentation, QueryParamsMap(),
271                     std::function<
272                             void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
273                                     const int eCode) >(
274                     std::bind(&EnrolleeResource::checkProvInformationCb, this,
275                     std::placeholders::_1, std::placeholders::_2,
276                     std::placeholders::_3)));
277         }
278
279         PropertyData EnrolleeResource::parsePropertyDataFromRepresentation(const OCRepresentation& rep)
280         {
281             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_RES_TAG, "Enter parsePropertyDataFromRepresentation");
282
283             DeviceConfig devInfo;
284             NetworkInfo netInfo;
285             bool cloudable = false;
286
287             std::vector<OCRepresentation> children = rep.getChildren();
288
289             for(auto prop = children.begin(); prop != children.end(); ++prop)
290             {
291                 if(prop->getUri().find(OC_RSRVD_ES_URI_WIFI) != std::string::npos)
292                 {
293                     OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_RES_TAG, "Find wifi resource");
294                     if(prop->hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIMODE)
295                                 && prop->hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIFREQ))
296                     {
297                         std::vector<int> types = prop->getValue<std::vector<int>>(OC_RSRVD_ES_SUPPORTEDWIFIMODE);
298
299                         for(auto type = types.begin(); type != types.end(); ++type)
300                         {
301                             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "OC_RSRVD_ES_SUPPORTEDWIFIMODE = %d",
302                                 *type);
303                             netInfo.types.push_back(static_cast<WIFI_MODE>(*type));
304                         }
305
306                         netInfo.freq = static_cast<WIFI_FREQ>(prop->getValue<int>(OC_RSRVD_ES_SUPPORTEDWIFIFREQ));
307
308
309                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "OC_RSRVD_ES_SUPPORTEDWIFIFREQ = %d",
310                                 netInfo.freq);
311                     }
312                 }
313
314                 else if(prop->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
315                 {
316                     OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_RES_TAG, "Find devconf");
317                     if(prop->hasAttribute(OC_RSRVD_ES_DEVNAME)
318                                 && prop->hasAttribute(OC_RSRVD_ES_LANGUAGE)
319                                 && prop->hasAttribute(OC_RSRVD_ES_COUNTRY))
320                     {
321                         //TODO:: setting DeviceID.
322                         //devInfo.id = devId;
323                         devInfo.name = prop->getValue<std::string>(OC_RSRVD_ES_DEVNAME);
324                         devInfo.language = prop->getValue<std::string>(OC_RSRVD_ES_LANGUAGE);
325                         devInfo.country = prop->getValue<std::string>(OC_RSRVD_ES_COUNTRY);
326
327                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "OC_RSRVD_ES_DEVNAME = %s",
328                                 devInfo.name.c_str());
329                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "OC_RSRVD_ES_LANGUAGE = %s",
330                                 devInfo.language.c_str());
331                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "OC_RSRVD_ES_COUNTRY = %s",
332                                 devInfo.country.c_str());
333                     }
334                 }
335
336                 else if(prop->getUri().find(OC_RSRVD_ES_URI_CLOUDSERVER) != std::string::npos)
337                 {
338                     OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_RES_TAG, "Find cloudserver");
339                     cloudable = true;
340                     OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "cloudable = %d",
341                                 cloudable);
342                 }
343             }
344
345             return PropertyData(devInfo, netInfo, cloudable);
346         }
347
348     }
349 }