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 5
42 RemoteEnrollee::RemoteEnrollee(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();
57 ESResult RemoteEnrollee::registerSecurityCallbackHandler(SecurityPinCb securityPinCb,
58 SecProvisioningDbPathCb secProvisioningDbPathCb)
60 // No need to check NULL for m_secProvisioningDbPathCB as this is not a mandatory
61 // callback function. If m_secProvisioningDbPathCB is NULL, provisioning manager
62 // in security layer will try to find the PDM.db file in the local path.
63 // If PDM.db is found, the provisioning manager operations will succeed.
64 // Otherwise all the provisioning manager operations will fail.
65 m_secProvisioningDbPathCb = secProvisioningDbPathCb;
66 m_securityPinCb = securityPinCb;
69 #endif //__WITH_DTLS__
71 void RemoteEnrollee::securityStatusHandler(
72 std::shared_ptr< SecProvisioningStatus > status)
74 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "easySetupStatusCallback status is, UUID = %s,"
75 "Status = %d", status->getDeviceUUID().c_str(),
76 status->getESResult());
78 if(status->getESResult() == ES_OK)
80 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are successful. "
81 "Continue with Network information provisioning");
83 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before ProvisionEnrollee");
85 m_securityProvStatusCb(status);
89 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are fail");
91 m_securityProvStatusCb(status);
95 void RemoteEnrollee::getStatusHandler(std::shared_ptr< GetEnrolleeStatus > status)
97 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getStatusHandler");
99 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"getStatusHandler = %d", status->getESResult());
101 m_getStatusCb(status);
104 void RemoteEnrollee::getConfigurationStatusHandler (
105 std::shared_ptr< GetConfigurationStatus > status)
107 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getConfigurationStatusHandler");
109 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
110 status->getESResult());
112 m_getConfigurationStatusCb(status);
115 void RemoteEnrollee::devicePropProvisioningStatusHandler(
116 std::shared_ptr< DevicePropProvisioningStatus > status)
118 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering DevicePropProvisioningStatusHandler");
120 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"ProvStatus = %d", status->getESResult());
122 m_devicePropProvStatusCb(status);
127 void RemoteEnrollee::cloudPropProvisioningStatusHandler (
128 std::shared_ptr< CloudPropProvisioningStatus > status)
130 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering cloudPropProvisioningStatusHandler");
132 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
133 status->getESCloudState());
135 m_cloudPropProvStatusCb(status);
139 void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
141 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered");
143 std::string resourceURI;
144 std::string hostAddress;
145 std::string hostDeviceID;
151 if(!(resource->connectivityType() & CT_ADAPTER_TCP))
153 // Get the resource URI
154 resourceURI = resource->uri();
155 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
156 "URI of the resource: %s", resourceURI.c_str());
158 // Get the resource host address
159 hostAddress = resource->host();
160 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
161 "Host address of the resource: %s", hostAddress.c_str());
163 hostDeviceID = resource->sid();
164 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
165 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
167 if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
169 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched CloudResource");
170 m_ocResource = resource;
171 m_discoveryResponse = true;
177 catch(std::exception& e)
179 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
180 "Exception in foundResource: %s", e.what());
184 ESResult RemoteEnrollee::discoverResource()
186 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Enter discoverResource");
188 std::string query("");
189 query.append(ES_BASE_RES_URI);
190 query.append("?rt=");
191 query.append(OC_RSRVD_ES_RES_TYPE_PROV);
193 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
195 m_discoveryResponse = false;
197 std::function< void (std::shared_ptr<OC::OCResource>) > onDeviceDiscoveredCb =
198 std::bind(&RemoteEnrollee::onDeviceDiscovered, this,
199 std::placeholders::_1);
200 OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT,
201 onDeviceDiscoveredCb);
203 if (result != OCStackResult::OC_STACK_OK)
205 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
206 "Failed discoverResource");
210 std::unique_lock<std::mutex> lck(m_discoverymtx);
211 m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
213 if (!m_discoveryResponse)
215 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
216 "Failed discoverResource because timeout");
222 void RemoteEnrollee::provisionSecurity(SecurityProvStatusCb callback)
225 m_securityProvStatusCb = callback;
227 SecurityProvStatusCb securityProvStatusCb = std::bind(
228 &RemoteEnrollee::securityStatusHandler,
230 std::placeholders::_1);
231 //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
232 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
234 m_enrolleeSecurity->registerCallbackHandler(securityProvStatusCb, m_securityPinCb,
235 m_secProvisioningDbPathCb);
239 m_enrolleeSecurity->performOwnershipTransfer();
241 catch (const std::exception& e)
243 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
244 "Exception for performOwnershipTransfer : %s", e.what());
246 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Fail performOwnershipTransfer");
247 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
248 std::make_shared< SecProvisioningStatus >
249 (m_enrolleeSecurity->getUUID(), ES_ERROR);
250 m_securityProvStatusCb(securityProvisioningStatus);
254 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured.");
256 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
257 std::make_shared< SecProvisioningStatus >
258 ("", ES_UNSUPPORTED_OPERATION);
259 m_securityProvStatusCb(securityProvisioningStatus);
263 void RemoteEnrollee::getStatus(GetStatusCb callback)
267 throw ESInvalidParameterException("Callback is empty");
270 if (m_enrolleeResource == nullptr)
272 throw ESBadRequestException ("Device not created");
275 m_getStatusCb = callback;
277 GetStatusCb getStatusCb = std::bind(
278 &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
279 m_enrolleeResource->registerGetStatusCallback(getStatusCb);
280 m_enrolleeResource->getStatus();
284 void RemoteEnrollee::getConfiguration(GetConfigurationStatusCb callback)
288 throw ESInvalidParameterException("Callback is empty");
291 if (m_enrolleeResource == nullptr)
293 throw ESBadRequestException ("Device not created");
296 m_getConfigurationStatusCb = callback;
298 GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
299 &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
300 m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
301 m_enrolleeResource->getConfiguration();
304 void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
305 DevicePropProvStatusCb callback)
307 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionDeviceProperties");
311 throw ESInvalidParameterException("Callback is empty");
314 m_devicePropProvStatusCb = callback;
316 if (m_enrolleeResource == nullptr)
318 throw ESBadRequestException ("Device not created");
321 if(!deviceProp.toOCRepresentation().hasAttribute(OC_RSRVD_ES_SSID))
323 throw ESBadRequestException ("Invalid Provisiong Data.");
326 DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
327 &RemoteEnrollee::devicePropProvisioningStatusHandler,
328 this, std::placeholders::_1);
330 m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
331 m_enrolleeResource->provisionEnrollee(deviceProp);
334 void RemoteEnrollee::initCloudResource()
336 ESResult result = ES_ERROR;
338 if (m_cloudResource != nullptr)
340 throw ESBadRequestException ("Already created");
343 result = discoverResource();
345 if (result == ES_ERROR)
347 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
348 "Failed to create resource object using discoverResource");
349 throw ESBadRequestException ("Resource object not created");
354 if(m_ocResource != nullptr)
356 m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
358 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
359 CloudPropProvisioningStatus >(ESResult::ES_OK,
360 ESCloudProvState::ES_CLOUD_ENROLLEE_FOUND);
362 m_cloudPropProvStatusCb(provStatus);
366 throw ESBadGetException ("Resource handle is invalid");
371 void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
372 CloudPropProvStatusCb callback)
374 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionCloudProperties");
375 ESResult res = ES_OK;
379 throw ESInvalidParameterException("Callback is empty");
382 m_cloudPropProvStatusCb = callback;
384 if(!cloudProp.toOCRepresentation().hasAttribute(OC_RSRVD_ES_AUTHCODE) ||
385 !cloudProp.toOCRepresentation().hasAttribute(OC_RSRVD_ES_AUTHPROVIDER) ||
386 !cloudProp.toOCRepresentation().hasAttribute(OC_RSRVD_ES_CISERVER))
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_ERROR,
403 ESCloudProvState::ES_CLOUD_ENROLLEE_NOT_FOUND);
404 m_cloudPropProvStatusCb(provStatus);
411 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
413 if(cloudProp.getCloudID().empty())
415 throw ESBadRequestException("Invalid Cloud Server UUID.");
418 res = m_enrolleeSecurity->performACLProvisioningForCloudServer(cloudProp.getCloudID());
420 if(res == ESResult::ES_ERROR)
422 throw ESBadRequestException("Error in provisioning operation!");
427 catch (const std::exception& e)
429 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
430 "Exception caught in provisionCloudProperties = %s", e.what());
432 m_cloudResource = nullptr;
434 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
435 CloudPropProvisioningStatus >(ESResult::ES_ERROR,
436 ESCloudProvState::ES_CLOUD_PROVISIONING_ERROR);
437 m_cloudPropProvStatusCb(provStatus);
442 if (m_cloudResource == nullptr)
444 throw ESBadRequestException ("Cloud Resource not created");
447 CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
448 &RemoteEnrollee::cloudPropProvisioningStatusHandler,
449 this, std::placeholders::_1);
451 m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
452 m_cloudResource->provisionEnrollee(cloudProp);