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();
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::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
125 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN");
131 if(!(resource->connectivityType() & CT_ADAPTER_TCP))
133 std::string resourceURI;
134 std::string hostAddress;
135 std::string hostDeviceID;
137 // Get the resource URI
138 resourceURI = resource->uri();
139 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
140 "URI of the resource: %s", resourceURI.c_str());
142 // Get the resource host address
143 hostAddress = resource->host();
144 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
145 "Host address of the resource: %s", hostAddress.c_str());
147 hostDeviceID = resource->sid();
148 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
149 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
151 if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
153 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning");
154 m_ocResource = resource;
155 m_discoveryResponse = true;
161 catch(std::exception& e)
163 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
164 "Exception in foundResource: %s", e.what());
167 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT");
170 ESResult RemoteEnrollee::discoverResource()
172 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN");
174 std::string query("");
175 query.append(ES_BASE_RES_URI);
176 query.append("?rt=");
177 query.append(OC_RSRVD_ES_RES_TYPE_PROV);
179 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
181 m_discoveryResponse = false;
183 std::function< void (std::shared_ptr<OC::OCResource>) > onDeviceDiscoveredCb =
184 std::bind(&RemoteEnrollee::onDeviceDiscovered, this,
185 std::placeholders::_1);
186 OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT,
187 onDeviceDiscoveredCb);
189 if (result != OCStackResult::OC_STACK_OK)
191 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
192 "Failed discoverResource");
196 std::unique_lock<std::mutex> lck(m_discoverymtx);
197 m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT));
199 if (!m_discoveryResponse)
201 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
202 "Failed discoverResource because timeout");
209 void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
211 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
213 ESResult res = ESResult::ES_ERROR;
216 throw ESInvalidParameterException("Callback is empty");
218 m_securityProvStatusCb = callback;
220 SecurityProvStatusCb securityProvStatusCb = std::bind(
221 &RemoteEnrollee::securityStatusHandler,
223 std::placeholders::_1);
224 //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
225 if(!m_enrolleeSecurity.get())
227 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
230 res = m_enrolleeSecurity->provisionOwnership();
232 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
233 std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res);
234 m_securityProvStatusCb(securityProvisioningStatus);
235 m_enrolleeSecurity.reset();
237 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
241 throw ESInvalidParameterException("Callback is empty");
243 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
244 std::make_shared< SecProvisioningStatus >
245 ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
246 callback(securityProvisioningStatus);
248 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
251 void RemoteEnrollee::getStatus(const GetStatusCb callback)
253 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus IN");
257 throw ESInvalidParameterException("Callback is empty");
260 if (m_enrolleeResource == nullptr)
262 throw ESBadRequestException ("Device not created");
265 m_getStatusCb = callback;
267 GetStatusCb getStatusCb = std::bind(
268 &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
269 m_enrolleeResource->registerGetStatusCallback(getStatusCb);
270 m_enrolleeResource->getStatus();
272 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT");
275 void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
277 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN");
281 throw ESInvalidParameterException("Callback is empty");
284 if (m_enrolleeResource == nullptr)
286 throw ESBadRequestException ("Device not created");
289 m_getConfigurationStatusCb = callback;
291 GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
292 &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
293 m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
294 m_enrolleeResource->getConfiguration();
296 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT");
299 void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
300 const DevicePropProvStatusCb callback)
302 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN");
306 throw ESInvalidParameterException("Callback is empty");
309 m_devicePropProvStatusCb = callback;
311 if (m_enrolleeResource == nullptr)
313 throw ESBadRequestException ("Device not created");
316 if(deviceProp.getSsid().empty())
318 throw ESBadRequestException ("Invalid Provisiong Data.");
321 DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
322 &RemoteEnrollee::devicePropProvisioningStatusHandler,
323 this, std::placeholders::_1);
325 m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
326 m_enrolleeResource->provisionProperties(deviceProp);
328 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT");
331 void RemoteEnrollee::initCloudResource()
333 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN");
335 ESResult result = ES_ERROR;
337 result = discoverResource();
339 if (result == ES_ERROR)
341 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
342 "Failed to create resource object using discoverResource");
343 throw ESBadRequestException ("Resource object not created");
348 if(m_ocResource != nullptr)
350 m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
354 throw ESBadGetException ("Resource handle is invalid");
358 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT");
361 void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
362 const CloudPropProvStatusCb callback)
364 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN");
368 throw ESInvalidParameterException("Callback is empty");
371 m_cloudPropProvStatusCb = callback;
373 if(cloudProp.getAuthCode().empty() ||
374 cloudProp.getAuthProvider().empty() ||
375 cloudProp.getCiServer().empty())
377 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
385 catch (const std::exception& e)
387 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
388 "Exception caught in provisionCloudProperties = %s", e.what());
390 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
391 CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE);
392 m_cloudPropProvStatusCb(provStatus);
395 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
396 if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
398 ESResult res = ESResult::ES_ERROR;
399 if(!m_enrolleeSecurity.get())
401 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
405 res = m_enrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
406 cloudProp.getCredID());
407 m_enrolleeSecurity.reset();
408 if(res != ESResult::ES_OK)
410 m_cloudResource = nullptr;
411 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
412 CloudPropProvisioningStatus >(res);
413 m_cloudPropProvStatusCb(provStatus);
419 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
421 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
423 if (m_cloudResource == nullptr)
425 throw ESBadRequestException ("Cloud Resource not created");
428 CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
429 &RemoteEnrollee::cloudPropProvisioningStatusHandler,
430 this, std::placeholders::_1);
432 m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
433 m_cloudResource->provisionProperties(cloudProp);
435 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");