1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "RemoteEnrollee.h"
22 #include "EnrolleeResource.h"
23 #include "CloudResource.h"
24 #include "OCPlatform.h"
25 #include "ESException.h"
27 #include "OCResource.h"
29 #include "EnrolleeSecurity.h"
31 #include "oic_malloc.h"
38 static const char ES_BASE_RES_URI[] = "/oic/res";
39 #define ES_REMOTE_ENROLLEE_TAG "ES_REMOTE_ENROLLEE"
40 #define DISCOVERY_TIMEOUT 1
42 RemoteEnrollee::RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource)
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;
53 m_deviceId = resource->sid();
56 void RemoteEnrollee::securityStatusHandler(
57 const std::shared_ptr< SecProvisioningStatus > status) const
59 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr IN");
60 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "UUID = %s, ESResult = %d",
61 status->getDeviceUUID().c_str(), status->getESResult());
63 if(status->getESResult() == ES_OK)
65 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is successfully done.");
66 m_securityProvStatusCb(status);
70 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is failed.");
71 m_securityProvStatusCb(status);
73 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr OUT");
76 void RemoteEnrollee::getStatusHandler(
77 const std::shared_ptr< GetEnrolleeStatus > status) const
79 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler IN");
81 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler = %d",
82 status->getESResult());
83 m_getStatusCb(status);
85 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler OUT");
88 void RemoteEnrollee::getConfigurationStatusHandler (
89 const std::shared_ptr< GetConfigurationStatus > status) const
91 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler IN");
93 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
94 status->getESResult());
95 m_getConfigurationStatusCb(status);
97 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler OUT");
100 void RemoteEnrollee::devicePropProvisioningStatusHandler(
101 const std::shared_ptr< DevicePropProvisioningStatus > status) const
103 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler IN");
105 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ProvStatus = %d", status->getESResult());
106 m_devicePropProvStatusCb(status);
108 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler OUT");
111 void RemoteEnrollee::cloudPropProvisioningStatusHandler (
112 const std::shared_ptr< CloudPropProvisioningStatus > status) const
114 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler IN");
116 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
117 status->getESResult());
118 m_cloudPropProvStatusCb(status);
120 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT");
123 void RemoteEnrollee::onDiscoveredCallback(const std::shared_ptr<OC::OCResource> resource,
124 std::weak_ptr<RemoteEnrollee> this_ptr)
126 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onDiscoveredCallback()");
127 std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
130 Ptr->onDeviceDiscovered(resource);
134 void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
136 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN");
142 if(!(resource->connectivityType() & CT_ADAPTER_TCP))
144 std::string resourceURI;
145 std::string hostAddress;
146 std::string hostDeviceID;
148 // Get the resource URI
149 resourceURI = resource->uri();
150 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
151 "URI of the resource: %s", resourceURI.c_str());
153 // Get the resource host address
154 hostAddress = resource->host();
155 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
156 "Host address of the resource: %s", hostAddress.c_str());
158 hostDeviceID = resource->sid();
159 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
160 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
162 if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
164 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning");
165 m_ocResource = resource;
166 m_discoveryResponse = true;
172 catch(std::exception& e)
174 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
175 "Exception in foundResource: %s", e.what());
178 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT");
181 ESResult RemoteEnrollee::discoverResource()
183 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN");
185 std::string query("");
186 query.append(ES_BASE_RES_URI);
187 query.append("?rt=");
188 query.append(OC_RSRVD_ES_RES_TYPE_PROV);
190 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
192 m_discoveryResponse = false;
194 onDeviceDiscoveredCb cb = std::bind(&RemoteEnrollee::onDiscoveredCallback,
195 std::placeholders::_1,
198 OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT, cb);
200 if (result != OCStackResult::OC_STACK_OK)
202 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
203 "Failed discoverResource");
207 std::unique_lock<std::mutex> lck(m_discoverymtx);
208 m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
210 if (!m_discoveryResponse)
212 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
213 "Failed discoverResource because timeout");
220 void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
222 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
224 ESResult res = ESResult::ES_ERROR;
227 throw ESInvalidParameterException("Callback is empty");
229 m_securityProvStatusCb = callback;
231 SecurityProvStatusCb securityProvStatusCb = std::bind(
232 &RemoteEnrollee::securityStatusHandler,
234 std::placeholders::_1);
235 //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
236 if(!m_enrolleeSecurity.get())
238 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
241 res = m_enrolleeSecurity->provisionOwnership();
243 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
244 std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res);
245 m_securityProvStatusCb(securityProvisioningStatus);
246 m_enrolleeSecurity.reset();
248 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
252 throw ESInvalidParameterException("Callback is empty");
254 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
255 std::make_shared< SecProvisioningStatus >
256 ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
257 callback(securityProvisioningStatus);
259 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
262 void RemoteEnrollee::getStatus(const GetStatusCb callback)
264 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus IN");
268 throw ESInvalidParameterException("Callback is empty");
271 if (m_enrolleeResource == nullptr)
273 throw ESBadRequestException ("Device not created");
276 m_getStatusCb = callback;
278 GetStatusCb getStatusCb = std::bind(
279 &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
280 m_enrolleeResource->registerGetStatusCallback(getStatusCb);
281 m_enrolleeResource->getStatus();
283 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT");
286 void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
288 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN");
292 throw ESInvalidParameterException("Callback is empty");
295 if (m_enrolleeResource == nullptr)
297 throw ESBadRequestException ("Device not created");
300 m_getConfigurationStatusCb = callback;
302 GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
303 &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
304 m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
305 m_enrolleeResource->getConfiguration();
307 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT");
310 void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
311 const DevicePropProvStatusCb callback)
313 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN");
317 throw ESInvalidParameterException("Callback is empty");
320 m_devicePropProvStatusCb = callback;
322 if (m_enrolleeResource == nullptr)
324 throw ESBadRequestException ("Device not created");
327 if(deviceProp.getSsid().empty())
329 throw ESBadRequestException ("Invalid Provisiong Data.");
332 DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
333 &RemoteEnrollee::devicePropProvisioningStatusHandler,
334 this, std::placeholders::_1);
336 m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
337 m_enrolleeResource->provisionProperties(deviceProp);
339 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT");
342 void RemoteEnrollee::initCloudResource()
344 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN");
346 ESResult result = ES_ERROR;
348 result = discoverResource();
350 if (result == ES_ERROR)
352 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
353 "Failed to create resource object using discoverResource");
354 throw ESBadRequestException ("Resource object not created");
359 if(m_ocResource != nullptr)
361 m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
365 throw ESBadGetException ("Resource handle is invalid");
369 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT");
372 void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
373 const CloudPropProvStatusCb callback)
375 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN");
379 throw ESInvalidParameterException("Callback is empty");
382 m_cloudPropProvStatusCb = callback;
384 if(cloudProp.getAuthCode().empty() ||
385 cloudProp.getAuthProvider().empty() ||
386 cloudProp.getCiServer().empty())
388 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
396 catch (const std::exception& e)
398 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
399 "Exception caught in provisionCloudProperties = %s", e.what());
401 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
402 CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE);
403 m_cloudPropProvStatusCb(provStatus);
406 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
407 if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
409 ESResult res = ESResult::ES_ERROR;
410 if(!m_enrolleeSecurity.get())
412 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
416 res = m_enrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
417 cloudProp.getCredID());
418 m_enrolleeSecurity.reset();
419 if(res != ESResult::ES_OK)
421 m_cloudResource = nullptr;
422 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
423 CloudPropProvisioningStatus >(res);
424 m_cloudPropProvStatusCb(provStatus);
430 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
432 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
434 if (m_cloudResource == nullptr)
436 throw ESBadRequestException ("Cloud Resource not created");
439 CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
440 &RemoteEnrollee::cloudPropProvisioningStatusHandler,
441 this, std::placeholders::_1);
443 m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
444 m_cloudResource->provisionProperties(cloudProp);
446 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");