Update snapshot(2017-10-11)
[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 = {
189                     .adapter = CA_ADAPTER_IP,
190                     .flags = CA_DEFAULT_FLAGS,
191                     .port = 0,
192                     .addr = {0},
193                     .ifindex = 0,
194                     .remoteId = {0},
195 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
196                     .routeData = {0}
197 #endif
198                 };
199                 OCDevAddr address = m_ocResource->getDevAddr();
200                 OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE, address.addr);
201                 endpoint.port = address.port;
202
203                 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "HOST = %s", endpoint.addr);
204                 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "PORT = %u", endpoint.port);
205                 CAcloseSslSession(&endpoint);
206             }
207 #endif
208             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler OUT");
209         }
210
211         void RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback(
212                 const std::shared_ptr< CloudPropProvisioningStatus > status,
213                 std::weak_ptr<RemoteEnrollee> this_ptr)
214         {
215             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onCloudPropProvisioningStatusHandlerCallback");
216             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
217             if(Ptr)
218             {
219                 Ptr->cloudPropProvisioningStatusHandler(status);
220             }
221         }
222
223         void RemoteEnrollee::cloudPropProvisioningStatusHandler (
224                 const std::shared_ptr< CloudPropProvisioningStatus > status) const
225         {
226             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler IN");
227
228             OIC_LOG_V(INFO,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
229                                                     status->getESResult());
230             m_cloudPropProvStatusCb(status);
231
232             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT");
233         }
234
235         void RemoteEnrollee::onConnectRequestStatusHandlerCallback(
236                 const std::shared_ptr< ConnectRequestStatus > status,
237                 std::weak_ptr<RemoteEnrollee> this_ptr)
238         {
239             OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onConnectRequestStatusHandlerCallback");
240             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
241             if(Ptr)
242             {
243                 Ptr->connectRequestStatusHandler(status);
244             }
245         }
246
247         void RemoteEnrollee::connectRequestStatusHandler(
248                 const std::shared_ptr< ConnectRequestStatus > status) const
249         {
250             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler IN");
251
252             OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "RequestConnectStatus = %d", status->getESResult());
253             m_connectRequestStatusCb(status);
254
255             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler OUT");
256         }
257
258         void RemoteEnrollee::onDiscoveredCallback(const std::shared_ptr<OC::OCResource> resource,
259             std::weak_ptr<RemoteEnrollee> this_ptr)
260         {
261             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDiscoveredCallback()");
262             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
263             if(Ptr)
264             {
265                 Ptr->onDeviceDiscovered(resource);
266             }
267         }
268
269         void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
270         {
271             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN");
272
273             try
274             {
275                 if(resource)
276                 {
277                     if(!(resource->connectivityType() & CT_ADAPTER_TCP))
278                     {
279                         std::string resourceURI;
280                         std::string hostAddress;
281                         std::string hostDeviceID;
282
283                         // Get the resource URI
284                         resourceURI = resource->uri();
285                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
286                                 "URI of the resource: %s", resourceURI.c_str());
287
288                         // Get the resource host address
289                         hostAddress = resource->host();
290                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
291                                 "Host address of the resource: %s", hostAddress.c_str());
292
293                         hostDeviceID = resource->sid();
294                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
295                                 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
296
297                         if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
298                         {
299                             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning");
300                             m_ocResource = resource;
301                             m_discoveryResponse = true;
302                             m_cond.notify_all();
303                         }
304                     }
305                 }
306             }
307             catch(std::exception& e)
308             {
309                 OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG,
310                         "Exception in foundResource: %s", e.what());
311             }
312
313             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT");
314         }
315
316         ESResult RemoteEnrollee::discoverResource()
317         {
318             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN");
319
320             std::string query("");
321             query.append(ES_BASE_RES_URI);
322             query.append("?rt=");
323             query.append(OC_RSRVD_ES_RES_TYPE_EASYSETUP);
324
325             OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
326
327             m_discoveryResponse = false;
328
329             onDeviceDiscoveredCb cb = std::bind(&RemoteEnrollee::onDiscoveredCallback,
330                                                 std::placeholders::_1,
331                                                 shared_from_this());
332
333             OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT, cb);
334
335             if (result != OCStackResult::OC_STACK_OK)
336             {
337                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
338                         "Failed discoverResource");
339                 return ES_ERROR;
340             }
341
342             std::unique_lock<std::mutex> lck(m_discoverymtx);
343             m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
344
345             if (!m_discoveryResponse)
346             {
347                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
348                         "Failed discoverResource because timeout");
349                 return ES_ERROR;
350             }
351
352             return ES_OK;
353         }
354
355         void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
356         {
357             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
358 #ifdef __WITH_DTLS__
359             ESResult res = ESResult::ES_ERROR;
360             if(!callback)
361             {
362                 throw ESInvalidParameterException("Callback is empty");
363             }
364             m_securityProvStatusCb = callback;
365
366             SecurityProvStatusCb securityProvStatusCb = std::bind(
367                     &RemoteEnrollee::onSecurityStatusHandlerCallback,
368                     std::placeholders::_1,
369                     shared_from_this());
370             //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
371             if(!m_localEnrolleeSecurity.get())
372             {
373                 m_localEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
374             }
375
376             res = m_localEnrolleeSecurity->provisionOwnership(NULL);
377
378             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
379                             std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res);
380             securityProvStatusCb(securityProvisioningStatus);
381 #else
382             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
383
384             if(!callback)
385             {
386                 throw ESInvalidParameterException("Callback is empty");
387             }
388             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
389                      std::make_shared< SecProvisioningStatus >
390                                    ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
391             callback(securityProvisioningStatus);
392 #endif
393             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
394         }
395
396         void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCbWithOption callback)
397         {
398             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
399 #ifdef __WITH_DTLS__
400             ESResult res = ESResult::ES_ERROR;
401             if(!callback)
402             {
403                 throw ESInvalidParameterException("Callback is empty");
404             }
405             m_securityProvStatusCbWithOption = callback;
406
407             SecurityProvStatusCbWithOption securityProvStatusCbWithOption = std::bind(
408                                     &RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback,
409                                     std::placeholders::_1,
410                                     shared_from_this());
411
412             if(!m_localEnrolleeSecurity.get())
413             {
414                 m_localEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
415             }
416
417             res = m_localEnrolleeSecurity->provisionOwnership(securityProvStatusCbWithOption);
418
419             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
420                             std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res);
421             securityProvStatusCbWithOption(securityProvisioningStatus);
422 #else
423             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
424
425             if(!callback)
426             {
427                 throw ESInvalidParameterException("Callback is empty");
428             }
429             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
430                      std::make_shared< SecProvisioningStatus >
431                                    ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
432             callback(securityProvisioningStatus);
433 #endif
434             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
435         }
436
437         void RemoteEnrollee::getStatus(const GetStatusCb callback)
438         {
439             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus IN");
440
441             if(!callback)
442             {
443                 throw ESInvalidParameterException("Callback is empty");
444             }
445
446             if (m_enrolleeResource == nullptr)
447             {
448                 throw ESBadRequestException ("Device not created");
449             }
450
451             m_getStatusCb = callback;
452
453             GetStatusCb getStatusCb = std::bind(
454                 &RemoteEnrollee::onGetStatusHandlerCallback,
455                 std::placeholders::_1,
456                 shared_from_this());
457
458             m_enrolleeResource->registerGetStatusCallback(getStatusCb);
459             m_enrolleeResource->getStatus();
460
461             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT");
462         }
463
464         void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
465         {
466             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN");
467
468             if(!callback)
469             {
470                 throw ESInvalidParameterException("Callback is empty");
471             }
472
473             if (m_enrolleeResource == nullptr)
474             {
475                 throw ESBadRequestException ("Device not created");
476             }
477
478             m_getConfigurationStatusCb = callback;
479
480             GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
481                     &RemoteEnrollee::onGetConfigurationStatusHandlerCallback,
482                     std::placeholders::_1,
483                     shared_from_this());
484
485             m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
486             m_enrolleeResource->getConfiguration();
487
488             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT");
489         }
490
491         void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
492                                                             const DevicePropProvStatusCb callback)
493         {
494             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN");
495
496             if(!callback)
497             {
498                 throw ESInvalidParameterException("Callback is empty");
499             }
500
501             m_devicePropProvStatusCb = callback;
502
503             if (m_enrolleeResource == nullptr)
504             {
505                 throw ESBadRequestException ("Device not created");
506             }
507
508             DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
509                     &RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback,
510                     std::placeholders::_1,
511                     shared_from_this());
512
513             m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
514             m_enrolleeResource->provisionProperties(deviceProp);
515
516             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT");
517         }
518
519         void RemoteEnrollee::initCloudResource()
520         {
521             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN");
522
523             ESResult result = ES_ERROR;
524
525             result = discoverResource();
526
527             if (result == ES_ERROR)
528             {
529                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
530                                     "Failed to create resource object using discoverResource");
531                 throw ESBadRequestException ("Resource object not created");
532             }
533
534             else
535             {
536                 if(m_ocResource != nullptr)
537                 {
538                     m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
539                 }
540                 else
541                 {
542                     throw ESBadGetException ("Resource handle is invalid");
543                 }
544             }
545
546             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT");
547         }
548
549         void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
550                                                             const CloudPropProvStatusCb callback)
551         {
552             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource IN");
553
554             provisionCloudProperties(NULL, cloudProp, callback);
555
556             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource OUT");
557         }
558
559         void RemoteEnrollee::provisionCloudProperties(const std::shared_ptr< OC::OCResource > resource,
560                                                         const CloudProp& cloudProp,
561                                                         const CloudPropProvStatusCb callback)
562         {
563             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN");
564
565             if(!callback)
566             {
567                 throw ESInvalidParameterException("Callback is empty");
568             }
569
570             m_cloudPropProvStatusCb = callback;
571
572             if((cloudProp.getAuthCode().empty() && cloudProp.getAccessToken().empty()) ||
573                 cloudProp.getAuthProvider().empty() ||
574                 cloudProp.getCiServer().empty())
575             {
576                 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
577             }
578
579             if(resource)
580             {
581                 if(resource->getResourceTypes().at(0) != OC_RSRVD_ES_RES_TYPE_EASYSETUP ||
582                                 resource->connectivityType() & CT_ADAPTER_TCP)
583                 {
584                     OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Given resource is not valid due to wrong rt or conntype");
585                     throw ESInvalidParameterException("A given OCResource is wrong");
586                 }
587
588                 auto interfaces = resource->getResourceInterfaces();
589                 bool isFound = false;
590                 for(auto interface : interfaces)
591                 {
592                     if(interface.compare(BATCH_INTERFACE) == 0)
593                     {
594                         OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "RemoteEnrollee object is succeessfully created");
595                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "HOST: %s", resource->host().c_str());
596                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "URI: %s", resource->uri().c_str());
597                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "SID: %s", resource->sid().c_str());
598                         OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "CONNECTIVITY: %d", resource->connectivityType());
599                         isFound = true;
600                     }
601                 }
602
603                 if(!isFound)
604                 {
605                     throw ESInvalidParameterException("A given OCResource has no batch interface");
606                 }
607             }
608
609             try
610             {
611                 if(resource == NULL)
612                 {
613                     initCloudResource();
614                 }
615                 else
616                 {
617                     OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Skip to find a provisioning resource");
618                     m_ocResource = resource;
619                     m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
620                 }
621             }
622             catch (const std::exception& e)
623             {
624                 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
625                     "Exception caught in provisionCloudProperties = %s", e.what());
626
627                 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
628                         CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE);
629                 m_cloudPropProvStatusCb(provStatus);
630                 return;
631             }
632 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
633             if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
634             {
635                 ESResult res = ESResult::ES_ERROR;
636                 if(!m_cloudEnrolleeSecurity.get())
637                 {
638                     m_cloudEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
639                 }
640
641
642                 res = m_cloudEnrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
643                                                                           cloudProp.getCredID());
644
645                 if(res != ESResult::ES_OK)
646                 {
647                     m_cloudResource = nullptr;
648                     std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
649                             CloudPropProvisioningStatus >(res);
650                     m_cloudPropProvStatusCb(provStatus);
651                     return;
652                 }
653             }
654             else
655             {
656                 OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
657             }
658 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
659
660             if (m_cloudResource == nullptr)
661             {
662                 throw ESBadRequestException ("Cloud Resource not created");
663             }
664
665             CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
666                     &RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback,
667                     std::placeholders::_1,
668                     shared_from_this());
669
670             m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
671             m_cloudResource->provisionProperties(cloudProp);
672
673             OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");
674         }
675
676         void RemoteEnrollee::requestToConnect(const std::vector<ES_CONNECT_TYPE> &connectTypes, const ConnectRequestStatusCb callback)
677         {
678             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect IN");
679
680             if(!callback)
681             {
682                 throw ESInvalidParameterException("Callback is empty");
683             }
684
685             m_connectRequestStatusCb = callback;
686
687             ConnectRequestStatusCb connectRequestStatusCb = std::bind(
688                         &RemoteEnrollee::onConnectRequestStatusHandlerCallback,
689                         std::placeholders::_1,
690                         shared_from_this());
691
692             m_enrolleeResource->registerConnectRequestStatusCallback(connectRequestStatusCb);
693             m_enrolleeResource->requestToConnect(connectTypes);
694
695             OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect OUT");
696         }
697     }
698 }
699
700