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(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();
57 ESResult RemoteEnrollee::registerSecurityCallbackHandler(
58 const SecurityPinCb securityPinCb,
59 const SecProvisioningDbPathCb secProvisioningDbPathCb)
61 // No need to check NULL for m_secProvisioningDbPathCB as this is not a mandatory
62 // callback function. If m_secProvisioningDbPathCB is NULL, provisioning manager
63 // in security layer will try to find the PDM.db file in the local path.
64 // If PDM.db is found, the provisioning manager operations will succeed.
65 // Otherwise all the provisioning manager operations will fail.
66 m_secProvisioningDbPathCb = secProvisioningDbPathCb;
67 m_securityPinCb = securityPinCb;
70 #endif //__WITH_DTLS__
72 void RemoteEnrollee::securityStatusHandler(
73 const std::shared_ptr< SecProvisioningStatus > status) const
75 OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "easySetupStatusCallback status is, UUID = %s,"
76 "Status = %d", status->getDeviceUUID().c_str(),
77 status->getESResult());
79 if(status->getESResult() == ES_OK)
81 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are successful. "
82 "Continue with Network information provisioning");
84 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before provisionProperties");
86 m_securityProvStatusCb(status);
90 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are fail");
92 m_securityProvStatusCb(status);
96 void RemoteEnrollee::getStatusHandler(
97 const std::shared_ptr< GetEnrolleeStatus > status) const
99 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getStatusHandler");
101 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"getStatusHandler = %d", status->getESResult());
103 m_getStatusCb(status);
106 void RemoteEnrollee::getConfigurationStatusHandler (
107 const std::shared_ptr< GetConfigurationStatus > status) const
109 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getConfigurationStatusHandler");
111 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
112 status->getESResult());
114 m_getConfigurationStatusCb(status);
117 void RemoteEnrollee::devicePropProvisioningStatusHandler(
118 const std::shared_ptr< DevicePropProvisioningStatus > status) const
120 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering DevicePropProvisioningStatusHandler");
122 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"ProvStatus = %d", status->getESResult());
124 m_devicePropProvStatusCb(status);
129 void RemoteEnrollee::cloudPropProvisioningStatusHandler (
130 const std::shared_ptr< CloudPropProvisioningStatus > status) const
132 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering cloudPropProvisioningStatusHandler");
134 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
135 status->getESResult());
137 m_cloudPropProvStatusCb(status);
141 void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
143 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered");
145 std::string resourceURI;
146 std::string hostAddress;
147 std::string hostDeviceID;
153 if(!(resource->connectivityType() & CT_ADAPTER_TCP))
155 // Get the resource URI
156 resourceURI = resource->uri();
157 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
158 "URI of the resource: %s", resourceURI.c_str());
160 // Get the resource host address
161 hostAddress = resource->host();
162 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
163 "Host address of the resource: %s", hostAddress.c_str());
165 hostDeviceID = resource->sid();
166 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
167 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
169 if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
171 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched CloudResource");
172 m_ocResource = resource;
173 m_discoveryResponse = true;
179 catch(std::exception& e)
181 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
182 "Exception in foundResource: %s", e.what());
186 ESResult RemoteEnrollee::discoverResource()
188 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Enter discoverResource");
190 std::string query("");
191 query.append(ES_BASE_RES_URI);
192 query.append("?rt=");
193 query.append(OC_RSRVD_ES_RES_TYPE_PROV);
195 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
197 m_discoveryResponse = false;
199 std::function< void (std::shared_ptr<OC::OCResource>) > onDeviceDiscoveredCb =
200 std::bind(&RemoteEnrollee::onDeviceDiscovered, this,
201 std::placeholders::_1);
202 OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT,
203 onDeviceDiscoveredCb);
205 if (result != OCStackResult::OC_STACK_OK)
207 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
208 "Failed discoverResource");
212 std::unique_lock<std::mutex> lck(m_discoverymtx);
213 m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
215 if (!m_discoveryResponse)
217 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
218 "Failed discoverResource because timeout");
224 void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
227 std::cout << __func__ << std::endl;
230 throw ESInvalidParameterException("Callback is empty");
232 m_securityProvStatusCb = callback;
234 SecurityProvStatusCb securityProvStatusCb = std::bind(
235 &RemoteEnrollee::securityStatusHandler,
237 std::placeholders::_1);
238 //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
239 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
241 m_enrolleeSecurity->registerCallbackHandler(securityProvStatusCb, m_securityPinCb,
242 m_secProvisioningDbPathCb);
246 m_enrolleeSecurity->provisionOwnership();
248 catch (const std::exception& e)
250 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
251 "Exception for performOwnershipTransfer : %s", e.what());
253 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Fail performOwnershipTransfer");
254 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
255 std::make_shared< SecProvisioningStatus >
256 (m_enrolleeSecurity->getUUID(), ES_ERROR);
257 m_securityProvStatusCb(securityProvisioningStatus);
261 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured.");
264 throw ESInvalidParameterException("Callback is empty");
266 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
267 std::make_shared< SecProvisioningStatus >
268 ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
269 callback(securityProvisioningStatus);
273 void RemoteEnrollee::getStatus(const GetStatusCb callback)
277 throw ESInvalidParameterException("Callback is empty");
280 if (m_enrolleeResource == nullptr)
282 throw ESBadRequestException ("Device not created");
285 m_getStatusCb = callback;
287 GetStatusCb getStatusCb = std::bind(
288 &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
289 m_enrolleeResource->registerGetStatusCallback(getStatusCb);
290 m_enrolleeResource->getStatus();
294 void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
298 throw ESInvalidParameterException("Callback is empty");
301 if (m_enrolleeResource == nullptr)
303 throw ESBadRequestException ("Device not created");
306 m_getConfigurationStatusCb = callback;
308 GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
309 &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
310 m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
311 m_enrolleeResource->getConfiguration();
314 void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
315 const DevicePropProvStatusCb callback)
317 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionDeviceProperties");
321 throw ESInvalidParameterException("Callback is empty");
324 m_devicePropProvStatusCb = callback;
326 if (m_enrolleeResource == nullptr)
328 throw ESBadRequestException ("Device not created");
331 if(deviceProp.getSsid().empty())
333 throw ESBadRequestException ("Invalid Provisiong Data.");
336 DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
337 &RemoteEnrollee::devicePropProvisioningStatusHandler,
338 this, std::placeholders::_1);
340 m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
341 m_enrolleeResource->provisionProperties(deviceProp);
344 void RemoteEnrollee::initCloudResource()
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);
363 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
364 CloudPropProvisioningStatus >(ESResult::ES_FOUND_ENROLLEE);
366 m_cloudPropProvStatusCb(provStatus);
370 throw ESBadGetException ("Resource handle is invalid");
375 void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
376 const CloudPropProvStatusCb callback)
378 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionCloudProperties");
382 throw ESInvalidParameterException("Callback is empty");
385 m_cloudPropProvStatusCb = callback;
387 if(cloudProp.getAuthCode().empty() ||
388 cloudProp.getAuthProvider().empty() ||
389 cloudProp.getCiServer().empty())
391 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
399 catch (const std::exception& e)
401 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
402 "Exception caught in provisionCloudProperties = %s", e.what());
404 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
405 CloudPropProvisioningStatus >(ESResult::ES_NOT_FOUND_ENROLLEE);
406 m_cloudPropProvStatusCb(provStatus);
409 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
412 if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
414 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
416 m_enrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
417 cloudProp.getCredID());
421 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
425 catch (const std::exception& e)
427 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
428 "Exception caught in provisionCloudProperties = %s", e.what());
430 m_cloudResource = nullptr;
432 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
433 CloudPropProvisioningStatus >(ESResult::ES_ERROR);
434 m_cloudPropProvStatusCb(provStatus);
437 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
439 if (m_cloudResource == nullptr)
441 throw ESBadRequestException ("Cloud Resource not created");
444 CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
445 &RemoteEnrollee::cloudPropProvisioningStatusHandler,
446 this, std::placeholders::_1);
448 m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
449 m_cloudResource->provisionProperties(cloudProp);