Remove unused old API.
[platform/upstream/iotivity.git] / service / easy-setup / mediator / richsdk / src / RemoteEnrollee.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 "RemoteEnrollee.h"
22 #include "EnrolleeResource.h"
23 #include "CloudResource.h"
24 #include "OCPlatform.h"
25 #include "ESException.h"
26 #include "logger.h"
27 #include "OCResource.h"
28 #ifdef __WITH_DTLS__
29 #include "EnrolleeSecurity.h"
30 #include "base64.h"
31 #include "oic_malloc.h"
32 #endif //__WITH_DTLS
33
34 namespace OIC
35 {
36     namespace Service
37     {
38         static const char ES_BASE_RES_URI[] = "/oic/res";
39         #define ES_REMOTE_ENROLLEE_TAG "ES_REMOTE_ENROLLEE"
40         #define DISCOVERY_TIMEOUT 5
41
42         RemoteEnrollee::RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource)
43         {
44             m_ocResource = resource;
45             m_enrolleeResource = std::make_shared<EnrolleeResource>(m_ocResource);
46             m_securityProvStatusCb = nullptr;
47             m_getConfigurationStatusCb = nullptr;
48             m_securityPinCb = nullptr;
49             m_secProvisioningDbPathCb = nullptr;
50             m_devicePropProvStatusCb = nullptr;
51             m_cloudPropProvStatusCb = nullptr;
52
53             m_deviceId = resource->sid();
54         }
55
56         void RemoteEnrollee::securityStatusHandler(
57                 const std::shared_ptr< SecProvisioningStatus > status) const
58         {
59             OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "easySetupStatusCallback status is, UUID = %s,"
60                     "Status = %d", status->getDeviceUUID().c_str(),
61                     status->getESResult());
62
63             if(status->getESResult() == ES_OK)
64             {
65                 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are successful. "
66                         "Continue with Network information provisioning");
67
68                 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before provisionProperties");
69
70                 m_securityProvStatusCb(status);
71             }
72             else
73             {
74                 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are fail");
75
76                 m_securityProvStatusCb(status);
77             }
78         }
79
80         void RemoteEnrollee::getStatusHandler(
81                 const std::shared_ptr< GetEnrolleeStatus > status) const
82         {
83             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getStatusHandler");
84
85             OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"getStatusHandler = %d", status->getESResult());
86
87             m_getStatusCb(status);
88         }
89
90         void RemoteEnrollee::getConfigurationStatusHandler (
91                 const std::shared_ptr< GetConfigurationStatus > status) const
92         {
93             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getConfigurationStatusHandler");
94
95             OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
96                                                     status->getESResult());
97
98             m_getConfigurationStatusCb(status);
99         }
100
101         void RemoteEnrollee::devicePropProvisioningStatusHandler(
102                 const std::shared_ptr< DevicePropProvisioningStatus > status) const
103         {
104             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering DevicePropProvisioningStatusHandler");
105
106             OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"ProvStatus = %d", status->getESResult());
107
108             m_devicePropProvStatusCb(status);
109
110             return;
111         }
112
113         void RemoteEnrollee::cloudPropProvisioningStatusHandler (
114                 const std::shared_ptr< CloudPropProvisioningStatus > status) const
115         {
116             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering cloudPropProvisioningStatusHandler");
117
118             OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
119                                                     status->getESResult());
120
121             m_cloudPropProvStatusCb(status);
122             return;
123         }
124
125         void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
126         {
127             OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered");
128
129             std::string resourceURI;
130             std::string hostAddress;
131             std::string hostDeviceID;
132
133             try
134             {
135                 if(resource)
136                 {
137                     if(!(resource->connectivityType() & CT_ADAPTER_TCP))
138                     {
139                         // Get the resource URI
140                         resourceURI = resource->uri();
141                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
142                                 "URI of the resource: %s", resourceURI.c_str());
143
144                         // Get the resource host address
145                         hostAddress = resource->host();
146                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
147                                 "Host address of the resource: %s", hostAddress.c_str());
148
149                         hostDeviceID = resource->sid();
150                         OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
151                                 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
152
153                         if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
154                         {
155                             OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched CloudResource");
156                             m_ocResource = resource;
157                             m_discoveryResponse = true;
158                             m_cond.notify_all();
159                         }
160                     }
161                 }
162             }
163             catch(std::exception& e)
164             {
165                 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
166                         "Exception in foundResource: %s", e.what());
167             }
168         }
169
170         ESResult RemoteEnrollee::discoverResource()
171         {
172             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Enter discoverResource");
173
174             std::string query("");
175             query.append(ES_BASE_RES_URI);
176             query.append("?rt=");
177             query.append(OC_RSRVD_ES_RES_TYPE_PROV);
178
179             OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
180
181             m_discoveryResponse = false;
182
183             std::function< void (std::shared_ptr<OC::OCResource>) > onDeviceDiscoveredCb =
184                     std::bind(&RemoteEnrollee::onDeviceDiscovered, this,
185                                                     std::placeholders::_1);
186             OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT,
187                     onDeviceDiscoveredCb);
188
189             if (result != OCStackResult::OC_STACK_OK)
190             {
191                 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
192                         "Failed discoverResource");
193                 return ES_ERROR;
194             }
195
196             std::unique_lock<std::mutex> lck(m_discoverymtx);
197             m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
198
199             if (!m_discoveryResponse)
200             {
201                 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
202                         "Failed discoverResource because timeout");
203                 return ES_ERROR;
204             }
205             return ES_OK;
206         }
207
208         void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
209         {
210 #ifdef __WITH_DTLS__
211             ESResult res = ESResult::ES_ERROR;
212             if(!callback)
213             {
214                 throw ESInvalidParameterException("Callback is empty");
215             }
216             m_securityProvStatusCb = callback;
217
218             SecurityProvStatusCb securityProvStatusCb = std::bind(
219                     &RemoteEnrollee::securityStatusHandler,
220                     this,
221                     std::placeholders::_1);
222             //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
223             m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
224
225             res = m_enrolleeSecurity->provisionOwnership();
226
227             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
228                             std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res);
229             m_securityProvStatusCb(securityProvisioningStatus);
230 #else
231             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured.");
232             if(!callback)
233             {
234                 throw ESInvalidParameterException("Callback is empty");
235             }
236             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
237                      std::make_shared< SecProvisioningStatus >
238                                    ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
239             callback(securityProvisioningStatus);
240 #endif
241         }
242
243         void RemoteEnrollee::getStatus(const GetStatusCb callback)
244         {
245             if(!callback)
246             {
247                 throw ESInvalidParameterException("Callback is empty");
248             }
249
250             if (m_enrolleeResource == nullptr)
251             {
252                 throw ESBadRequestException ("Device not created");
253             }
254
255             m_getStatusCb = callback;
256
257             GetStatusCb getStatusCb = std::bind(
258                 &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
259             m_enrolleeResource->registerGetStatusCallback(getStatusCb);
260             m_enrolleeResource->getStatus();
261
262         }
263
264         void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
265         {
266             if(!callback)
267             {
268                 throw ESInvalidParameterException("Callback is empty");
269             }
270
271             if (m_enrolleeResource == nullptr)
272             {
273                 throw ESBadRequestException ("Device not created");
274             }
275
276             m_getConfigurationStatusCb = callback;
277
278             GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
279                     &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
280             m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
281             m_enrolleeResource->getConfiguration();
282         }
283
284         void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
285                                                             const DevicePropProvStatusCb callback)
286         {
287             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionDeviceProperties");
288
289             if(!callback)
290             {
291                 throw ESInvalidParameterException("Callback is empty");
292             }
293
294             m_devicePropProvStatusCb = callback;
295
296             if (m_enrolleeResource == nullptr)
297             {
298                 throw ESBadRequestException ("Device not created");
299             }
300
301             if(deviceProp.getSsid().empty())
302             {
303                 throw ESBadRequestException ("Invalid Provisiong Data.");
304             }
305
306             DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
307                     &RemoteEnrollee::devicePropProvisioningStatusHandler,
308                     this, std::placeholders::_1);
309
310             m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
311             m_enrolleeResource->provisionProperties(deviceProp);
312         }
313
314         void RemoteEnrollee::initCloudResource()
315         {
316             ESResult result = ES_ERROR;
317
318             result = discoverResource();
319
320             if (result == ES_ERROR)
321             {
322                 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
323                                     "Failed to create resource object using discoverResource");
324                 throw ESBadRequestException ("Resource object not created");
325             }
326
327             else
328             {
329                 if(m_ocResource != nullptr)
330                 {
331                     m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
332                 }
333                 else
334                 {
335                     throw ESBadGetException ("Resource handle is invalid");
336                 }
337             }
338         }
339
340         void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
341                                                             const CloudPropProvStatusCb callback)
342         {
343             OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionCloudProperties");
344
345             if(!callback)
346             {
347                 throw ESInvalidParameterException("Callback is empty");
348             }
349
350             m_cloudPropProvStatusCb = callback;
351
352             if(cloudProp.getAuthCode().empty() ||
353                 cloudProp.getAuthProvider().empty() ||
354                 cloudProp.getCiServer().empty())
355             {
356                 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
357             }
358
359             try
360             {
361                 initCloudResource();
362             }
363
364             catch (const std::exception& e)
365             {
366                 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
367                     "Exception caught in provisionCloudProperties = %s", e.what());
368
369                 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
370                         CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE);
371                 m_cloudPropProvStatusCb(provStatus);
372                 return;
373             }
374 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
375             if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
376             {
377                 ESResult res = ESResult::ES_ERROR;
378                 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
379
380                 res = m_enrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
381                                                                           cloudProp.getCredID());
382
383                 if(res != ESResult::ES_OK)
384                 {
385                     m_cloudResource = nullptr;
386                     std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
387                             CloudPropProvisioningStatus >(res);
388                     m_cloudPropProvStatusCb(provStatus);
389                     return;
390                 }
391             }
392             else
393             {
394                 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
395             }
396 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
397
398             if (m_cloudResource == nullptr)
399             {
400                 throw ESBadRequestException ("Cloud Resource not created");
401             }
402
403             CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
404                     &RemoteEnrollee::cloudPropProvisioningStatusHandler,
405                                     this, std::placeholders::_1);
406
407             m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
408             m_cloudResource->provisionProperties(cloudProp);
409         }
410     }
411 }