replace : iotivity -> iotivity-sec
[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 #include "oic_string.h"
29 #ifdef __WITH_DTLS__
30 #include "EnrolleeSecurity.h"
31 #include "base64.h"
32 #include "oic_malloc.h"
33 #include "cacommon.h"
34 #endif //__WITH_DTLS
35
36 namespace OIC
37 {
38     namespace Service
39     {
40         static const char ES_BASE_RES_URI[] = "/oic/res";
41         #define ES_REMOTE_ENROLLEE_TAG "ES_REMOTE_ENROLLEE"
42         #define DISCOVERY_TIMEOUT 1
43
44         RemoteEnrollee::RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource)
45         {
46             m_ocResource = resource;
47             m_enrolleeResource = std::make_shared<EnrolleeResource>(m_ocResource);
48             m_securityProvStatusCb = nullptr;
49             m_getConfigurationStatusCb = nullptr;
50             m_securityPinCb = nullptr;
51             m_secProvisioningDbPathCb = nullptr;
52             m_devicePropProvStatusCb = nullptr;
53             m_cloudPropProvStatusCb = nullptr;
54             m_connectRequestStatusCb = nullptr;
55
56             m_deviceId = resource->sid();
57         }
58
59         void RemoteEnrollee::onSecurityStatusHandlerCallback(
60                 const std::shared_ptr< SecProvisioningStatus > status,
61                 std::weak_ptr<RemoteEnrollee> this_ptr)
62         {
63             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onSecurityStatusHandlerCallback");
64             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
65             if(Ptr)
66             {
67                 Ptr->securityStatusHandler(status);
68             }
69         }
70
71         void RemoteEnrollee::securityStatusHandler(
72                 const std::shared_ptr< SecProvisioningStatus > status) const
73         {
74             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr IN");
75             OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "UUID = %s", status->getDeviceUUID().c_str());
76             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "ESResult = %d", status->getESResult());
77
78             if(status->getESResult() == ES_OK)
79             {
80                 OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is successfully done.");
81                 m_securityProvStatusCb(status);
82             }
83             else
84             {
85                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is failed.");
86                 m_securityProvStatusCb(status);
87             }
88             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr OUT");
89         }
90
91         ESOwnershipTransferData RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback(
92                 const std::shared_ptr< SecProvisioningStatus > status,
93                 std::weak_ptr<RemoteEnrollee> this_ptr)
94         {
95             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onSecurityStatusWithOptionHandlerCallback");
96             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
97             if(Ptr)
98             {
99                 return Ptr->securityStatusWithOptionHandler(status);
100             }
101             return ESOwnershipTransferData();
102         }
103
104         ESOwnershipTransferData RemoteEnrollee::securityStatusWithOptionHandler(
105                 const std::shared_ptr< SecProvisioningStatus > status) const
106         {
107             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler IN");
108             OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "UUID = %s", status->getDeviceUUID().c_str());
109             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "ESResult = %d", status->getESResult());
110
111             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler OUT");
112             return m_securityProvStatusCbWithOption(status);
113         }
114
115         void RemoteEnrollee::onGetStatusHandlerCallback(
116                 const std::shared_ptr< GetEnrolleeStatus > status,
117                 std::weak_ptr<RemoteEnrollee> this_ptr)
118         {
119             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onGetStatusHandlerCallback");
120             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
121             if(Ptr)
122             {
123                 Ptr->getStatusHandler(status);
124             }
125         }
126
127         void RemoteEnrollee::getStatusHandler(
128                 const std::shared_ptr< GetEnrolleeStatus > status) const
129         {
130             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler IN");
131
132             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler = %d",
133                                                     status->getESResult());
134             m_getStatusCb(status);
135
136             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler OUT");
137         }
138
139         void RemoteEnrollee::onGetConfigurationStatusHandlerCallback(
140                 const std::shared_ptr< GetConfigurationStatus > status,
141                 std::weak_ptr<RemoteEnrollee> this_ptr)
142         {
143             OIC_LOG(INFO,ES_REMOTE_ENROLLEE_TAG,"onGetConfigurationStatusHandlerCallback");
144             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
145             if(Ptr)
146             {
147                 Ptr->getConfigurationStatusHandler(status);
148             }
149         }
150
151         void RemoteEnrollee::getConfigurationStatusHandler (
152                 const std::shared_ptr< GetConfigurationStatus > status) const
153         {
154             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler IN");
155
156             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
157                                                     status->getESResult());
158             m_getConfigurationStatusCb(status);
159
160             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler OUT");
161         }
162
163         void RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback(
164                 const std::shared_ptr< DevicePropProvisioningStatus > status,
165                 std::weak_ptr<RemoteEnrollee> this_ptr)
166         {
167             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDevicePropProvisioningStatusHandlerCallback");
168             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
169             if(Ptr)
170             {
171                 Ptr->devicePropProvisioningStatusHandler(status);
172             }
173         }
174
175         void RemoteEnrollee::devicePropProvisioningStatusHandler(
176                 const std::shared_ptr< DevicePropProvisioningStatus > status) const
177         {
178             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler IN");
179
180             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "DeviceProvStatus = %d", status->getESResult());
181             m_devicePropProvStatusCb(status);
182 #ifdef __WITH_DTLS__
183             if( m_ocResource.get() != nullptr &&
184                     !(m_ocResource->connectivityType() & CT_ADAPTER_GATT_BTLE) &&
185                     ES_OK == status->getESResult() )
186             {
187                 // NOTE: Temporary patch
188                 CAEndpoint_t endpoint = {.adapter = CA_ADAPTER_IP};
189
190                 OCDevAddr address = m_ocResource->getDevAddr();
191                 OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE, address.addr);
192                 endpoint.port = address.port;
193
194                 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "HOST = %s", endpoint.addr);
195                 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "PORT = %u", endpoint.port);
196                 CAcloseSslSession(&endpoint);
197             }
198 #endif
199             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler OUT");
200         }
201
202         void RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback(
203                 const std::shared_ptr< CloudPropProvisioningStatus > status,
204                 std::weak_ptr<RemoteEnrollee> this_ptr)
205         {
206             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onCloudPropProvisioningStatusHandlerCallback");
207             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
208             if(Ptr)
209             {
210                 Ptr->cloudPropProvisioningStatusHandler(status);
211             }
212         }
213
214         void RemoteEnrollee::cloudPropProvisioningStatusHandler (
215                 const std::shared_ptr< CloudPropProvisioningStatus > status) const
216         {
217             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler IN");
218
219             OIC_LOG_V(INFO,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
220                                                     status->getESResult());
221             m_cloudPropProvStatusCb(status);
222
223             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT");
224         }
225
226         void RemoteEnrollee::onConnectRequestStatusHandlerCallback(
227                 const std::shared_ptr< ConnectRequestStatus > status,
228                 std::weak_ptr<RemoteEnrollee> this_ptr)
229         {
230             OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onConnectRequestStatusHandlerCallback");
231             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
232             if(Ptr)
233             {
234                 Ptr->connectRequestStatusHandler(status);
235             }
236         }
237
238         void RemoteEnrollee::connectRequestStatusHandler(
239                 const std::shared_ptr< ConnectRequestStatus > status) const
240         {
241             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler IN");
242
243             OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "RequestConnectStatus = %d", status->getESResult());
244             m_connectRequestStatusCb(status);
245
246             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler OUT");
247         }
248
249         void RemoteEnrollee::onDiscoveredCallback(const std::shared_ptr<OC::OCResource> resource,
250             std::weak_ptr<RemoteEnrollee> this_ptr)
251         {
252             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDiscoveredCallback()");
253             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
254             if(Ptr)
255             {
256                 Ptr->onDeviceDiscovered(resource);
257             }
258         }
259
260         void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
261         {
262             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN");
263
264             try
265             {
266                 if(resource)
267                 {
268                     if(!(resource->connectivityType() & CT_ADAPTER_TCP))
269                     {
270                         std::string resourceURI;
271                         std::string hostAddress;
272                         std::string hostDeviceID;
273
274                         // Get the resource URI
275                         resourceURI = resource->uri();
276                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
277                                 "URI of the resource: %s", resourceURI.c_str());
278
279                         // Get the resource host address
280                         hostAddress = resource->host();
281                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
282                                 "Host address of the resource: %s", hostAddress.c_str());
283
284                         hostDeviceID = resource->sid();
285                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
286                                 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
287
288                         if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
289                         {
290                             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning");
291                             m_ocResource = resource;
292                             m_discoveryResponse = true;
293                             m_cond.notify_all();
294                         }
295                     }
296                 }
297             }
298             catch(std::exception& e)
299             {
300                 OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG,
301                         "Exception in foundResource: %s", e.what());
302             }
303
304             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT");
305         }
306
307         ESResult RemoteEnrollee::discoverResource()
308         {
309             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN");
310
311             std::string query("");
312             query.append(ES_BASE_RES_URI);
313             query.append("?rt=");
314             query.append(OC_RSRVD_ES_RES_TYPE_EASYSETUP);
315
316             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
317
318             m_discoveryResponse = false;
319
320             onDeviceDiscoveredCb cb = std::bind(&RemoteEnrollee::onDiscoveredCallback,
321                                                 std::placeholders::_1,
322                                                 shared_from_this());
323
324             OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT, cb);
325
326             if (result != OCStackResult::OC_STACK_OK)
327             {
328                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
329                         "Failed discoverResource");
330                 return ES_ERROR;
331             }
332
333             std::unique_lock<std::mutex> lck(m_discoverymtx);
334             m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
335
336             if (!m_discoveryResponse)
337             {
338                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
339                         "Failed discoverResource because timeout");
340                 return ES_ERROR;
341             }
342
343             return ES_OK;
344         }
345
346         void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
347         {
348             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
349 #ifdef __WITH_DTLS__
350             ESResult res = ESResult::ES_ERROR;
351             if(!callback)
352             {
353                 throw ESInvalidParameterException("Callback is empty");
354             }
355             m_securityProvStatusCb = callback;
356
357             SecurityProvStatusCb securityProvStatusCb = std::bind(
358                     &RemoteEnrollee::onSecurityStatusHandlerCallback,
359                     std::placeholders::_1,
360                     shared_from_this());
361             //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
362             if(!m_localEnrolleeSecurity.get())
363             {
364                 m_localEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
365             }
366
367             res = m_localEnrolleeSecurity->provisionOwnership(NULL);
368
369             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
370                             std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res);
371             securityProvStatusCb(securityProvisioningStatus);
372 #else
373             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
374
375             if(!callback)
376             {
377                 throw ESInvalidParameterException("Callback is empty");
378             }
379             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
380                      std::make_shared< SecProvisioningStatus >
381                                    ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
382             callback(securityProvisioningStatus);
383 #endif
384             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
385         }
386
387         void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCbWithOption callback)
388         {
389             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
390 #ifdef __WITH_DTLS__
391             ESResult res = ESResult::ES_ERROR;
392             if(!callback)
393             {
394                 throw ESInvalidParameterException("Callback is empty");
395             }
396             m_securityProvStatusCbWithOption = callback;
397
398             SecurityProvStatusCbWithOption securityProvStatusCbWithOption = std::bind(
399                                     &RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback,
400                                     std::placeholders::_1,
401                                     shared_from_this());
402
403             if(!m_localEnrolleeSecurity.get())
404             {
405                 m_localEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
406             }
407
408             res = m_localEnrolleeSecurity->provisionOwnership(securityProvStatusCbWithOption);
409
410             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
411                             std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res);
412             securityProvStatusCbWithOption(securityProvisioningStatus);
413 #else
414             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
415
416             if(!callback)
417             {
418                 throw ESInvalidParameterException("Callback is empty");
419             }
420             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
421                      std::make_shared< SecProvisioningStatus >
422                                    ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
423             callback(securityProvisioningStatus);
424 #endif
425             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
426         }
427
428         void RemoteEnrollee::getStatus(const GetStatusCb callback)
429         {
430             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus IN");
431
432             if(!callback)
433             {
434                 throw ESInvalidParameterException("Callback is empty");
435             }
436
437             if (m_enrolleeResource == nullptr)
438             {
439                 throw ESBadRequestException ("Device not created");
440             }
441
442             m_getStatusCb = callback;
443
444             GetStatusCb getStatusCb = std::bind(
445                 &RemoteEnrollee::onGetStatusHandlerCallback,
446                 std::placeholders::_1,
447                 shared_from_this());
448
449             m_enrolleeResource->registerGetStatusCallback(getStatusCb);
450             m_enrolleeResource->getStatus();
451
452             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT");
453         }
454
455         void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
456         {
457             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN");
458
459             if(!callback)
460             {
461                 throw ESInvalidParameterException("Callback is empty");
462             }
463
464             if (m_enrolleeResource == nullptr)
465             {
466                 throw ESBadRequestException ("Device not created");
467             }
468
469             m_getConfigurationStatusCb = callback;
470
471             GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
472                     &RemoteEnrollee::onGetConfigurationStatusHandlerCallback,
473                     std::placeholders::_1,
474                     shared_from_this());
475
476             m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
477             m_enrolleeResource->getConfiguration();
478
479             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT");
480         }
481
482         void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
483                                                             const DevicePropProvStatusCb callback)
484         {
485             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN");
486
487             if(!callback)
488             {
489                 throw ESInvalidParameterException("Callback is empty");
490             }
491
492             m_devicePropProvStatusCb = callback;
493
494             if (m_enrolleeResource == nullptr)
495             {
496                 throw ESBadRequestException ("Device not created");
497             }
498
499             DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
500                     &RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback,
501                     std::placeholders::_1,
502                     shared_from_this());
503
504             m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
505             m_enrolleeResource->provisionProperties(deviceProp);
506
507             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT");
508         }
509
510         void RemoteEnrollee::initCloudResource()
511         {
512             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN");
513
514             ESResult result = ES_ERROR;
515
516             result = discoverResource();
517
518             if (result == ES_ERROR)
519             {
520                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
521                                     "Failed to create resource object using discoverResource");
522                 throw ESBadRequestException ("Resource object not created");
523             }
524
525             else
526             {
527                 if(m_ocResource != nullptr)
528                 {
529                     m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
530                 }
531                 else
532                 {
533                     throw ESBadGetException ("Resource handle is invalid");
534                 }
535             }
536
537             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT");
538         }
539
540         void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
541                                                             const CloudPropProvStatusCb callback)
542         {
543             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource IN");
544
545             provisionCloudProperties(NULL, cloudProp, callback);
546
547             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource OUT");
548         }
549
550         void RemoteEnrollee::provisionCloudProperties(const std::shared_ptr< OC::OCResource > resource,
551                                                         const CloudProp& cloudProp,
552                                                         const CloudPropProvStatusCb callback)
553         {
554             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN");
555
556             if(!callback)
557             {
558                 throw ESInvalidParameterException("Callback is empty");
559             }
560
561             m_cloudPropProvStatusCb = callback;
562
563             if((cloudProp.getAuthCode().empty() && cloudProp.getAccessToken().empty()) ||
564                 cloudProp.getAuthProvider().empty() ||
565                 cloudProp.getCiServer().empty())
566             {
567                 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
568             }
569
570             if(resource)
571             {
572                 if(resource->getResourceTypes().at(0) != OC_RSRVD_ES_RES_TYPE_EASYSETUP ||
573                                 resource->connectivityType() & CT_ADAPTER_TCP)
574                 {
575                     OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Given resource is not valid due to wrong rt or conntype");
576                     throw ESInvalidParameterException("A given OCResource is wrong");
577                 }
578
579                 auto interfaces = resource->getResourceInterfaces();
580                 bool isFound = false;
581                 for(auto interface : interfaces)
582                 {
583                     if(interface.compare(BATCH_INTERFACE) == 0)
584                     {
585                         OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "RemoteEnrollee object is succeessfully created");
586                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "HOST: %s", resource->host().c_str());
587                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "URI: %s", resource->uri().c_str());
588                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "SID: %s", resource->sid().c_str());
589                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "CONNECTIVITY: %d", resource->connectivityType());
590                         isFound = true;
591                     }
592                 }
593
594                 if(!isFound)
595                 {
596                     throw ESInvalidParameterException("A given OCResource has no batch interface");
597                 }
598             }
599
600             try
601             {
602                 if(resource == NULL)
603                 {
604                     initCloudResource();
605                 }
606                 else
607                 {
608                     OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Skip to find a provisioning resource");
609                     m_ocResource = resource;
610                     m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
611                 }
612             }
613             catch (const std::exception& e)
614             {
615                 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
616                     "Exception caught in provisionCloudProperties = %s", e.what());
617
618                 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
619                         CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE);
620                 m_cloudPropProvStatusCb(provStatus);
621                 return;
622             }
623 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
624             if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
625             {
626                 ESResult res = ESResult::ES_ERROR;
627                 if(!m_cloudEnrolleeSecurity.get())
628                 {
629                     m_cloudEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
630                 }
631
632
633                 res = m_cloudEnrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
634                                                                           cloudProp.getCredID());
635
636                 if(res != ESResult::ES_OK)
637                 {
638                     m_cloudResource = nullptr;
639                     std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
640                             CloudPropProvisioningStatus >(res);
641                     m_cloudPropProvStatusCb(provStatus);
642                     return;
643                 }
644             }
645             else
646             {
647                 OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
648             }
649 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
650
651             if (m_cloudResource == nullptr)
652             {
653                 throw ESBadRequestException ("Cloud Resource not created");
654             }
655
656             CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
657                     &RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback,
658                     std::placeholders::_1,
659                     shared_from_this());
660
661             m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
662             m_cloudResource->provisionProperties(cloudProp);
663
664             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");
665         }
666
667         void RemoteEnrollee::requestToConnect(const std::vector<ES_CONNECT_TYPE> &connectTypes, const ConnectRequestStatusCb callback)
668         {
669             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect IN");
670
671             if(!callback)
672             {
673                 throw ESInvalidParameterException("Callback is empty");
674             }
675
676             m_connectRequestStatusCb = callback;
677
678             ConnectRequestStatusCb connectRequestStatusCb = std::bind(
679                         &RemoteEnrollee::onConnectRequestStatusHandlerCallback,
680                         std::placeholders::_1,
681                         shared_from_this());
682
683             m_enrolleeResource->registerConnectRequestStatusCallback(connectRequestStatusCb);
684             m_enrolleeResource->requestToConnect(connectTypes);
685
686             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect OUT");
687         }
688     }
689 }
690
691