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_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "easySetupStatusCallback status is, UUID = %s,"
60 "Status = %d", status->getDeviceUUID().c_str(),
61 status->getESResult());
63 if(status->getESResult() == ES_OK)
65 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are successful. "
66 "Continue with Network information provisioning");
68 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before provisionProperties");
70 m_securityProvStatusCb(status);
74 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are fail");
76 m_securityProvStatusCb(status);
80 void RemoteEnrollee::getStatusHandler(
81 const std::shared_ptr< GetEnrolleeStatus > status) const
83 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getStatusHandler");
85 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"getStatusHandler = %d", status->getESResult());
87 m_getStatusCb(status);
90 void RemoteEnrollee::getConfigurationStatusHandler (
91 const std::shared_ptr< GetConfigurationStatus > status) const
93 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getConfigurationStatusHandler");
95 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
96 status->getESResult());
98 m_getConfigurationStatusCb(status);
101 void RemoteEnrollee::devicePropProvisioningStatusHandler(
102 const std::shared_ptr< DevicePropProvisioningStatus > status) const
104 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering DevicePropProvisioningStatusHandler");
106 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"ProvStatus = %d", status->getESResult());
108 m_devicePropProvStatusCb(status);
113 void RemoteEnrollee::cloudPropProvisioningStatusHandler (
114 const std::shared_ptr< CloudPropProvisioningStatus > status) const
116 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering cloudPropProvisioningStatusHandler");
118 OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
119 status->getESResult());
121 m_cloudPropProvStatusCb(status);
125 void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
127 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered");
129 std::string resourceURI;
130 std::string hostAddress;
131 std::string hostDeviceID;
137 if(!(resource->connectivityType() & CT_ADAPTER_TCP))
139 // Get the resource URI
140 resourceURI = resource->uri();
141 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
142 "URI of the resource: %s", resourceURI.c_str());
144 // Get the resource host address
145 hostAddress = resource->host();
146 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
147 "Host address of the resource: %s", hostAddress.c_str());
149 hostDeviceID = resource->sid();
150 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
151 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
153 if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
155 OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched CloudResource");
156 m_ocResource = resource;
157 m_discoveryResponse = true;
163 catch(std::exception& e)
165 OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
166 "Exception in foundResource: %s", e.what());
170 ESResult RemoteEnrollee::discoverResource()
172 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Enter discoverResource");
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");
208 void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
211 ESResult res = ESResult::ES_ERROR;
214 throw ESInvalidParameterException("Callback is empty");
216 m_securityProvStatusCb = callback;
218 SecurityProvStatusCb securityProvStatusCb = std::bind(
219 &RemoteEnrollee::securityStatusHandler,
221 std::placeholders::_1);
222 //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
223 if(!m_enrolleeSecurity.get())
225 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
228 res = m_enrolleeSecurity->provisionOwnership();
230 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
231 std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res);
232 m_securityProvStatusCb(securityProvisioningStatus);
233 m_enrolleeSecurity.reset();
235 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured.");
238 throw ESInvalidParameterException("Callback is empty");
240 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
241 std::make_shared< SecProvisioningStatus >
242 ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
243 callback(securityProvisioningStatus);
247 void RemoteEnrollee::getStatus(const GetStatusCb callback)
251 throw ESInvalidParameterException("Callback is empty");
254 if (m_enrolleeResource == nullptr)
256 throw ESBadRequestException ("Device not created");
259 m_getStatusCb = callback;
261 GetStatusCb getStatusCb = std::bind(
262 &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
263 m_enrolleeResource->registerGetStatusCallback(getStatusCb);
264 m_enrolleeResource->getStatus();
268 void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
272 throw ESInvalidParameterException("Callback is empty");
275 if (m_enrolleeResource == nullptr)
277 throw ESBadRequestException ("Device not created");
280 m_getConfigurationStatusCb = callback;
282 GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
283 &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
284 m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
285 m_enrolleeResource->getConfiguration();
288 void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
289 const DevicePropProvStatusCb callback)
291 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionDeviceProperties");
295 throw ESInvalidParameterException("Callback is empty");
298 m_devicePropProvStatusCb = callback;
300 if (m_enrolleeResource == nullptr)
302 throw ESBadRequestException ("Device not created");
305 if(deviceProp.getSsid().empty())
307 throw ESBadRequestException ("Invalid Provisiong Data.");
310 DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
311 &RemoteEnrollee::devicePropProvisioningStatusHandler,
312 this, std::placeholders::_1);
314 m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
315 m_enrolleeResource->provisionProperties(deviceProp);
318 void RemoteEnrollee::initCloudResource()
320 ESResult result = ES_ERROR;
322 result = discoverResource();
324 if (result == ES_ERROR)
326 OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
327 "Failed to create resource object using discoverResource");
328 throw ESBadRequestException ("Resource object not created");
333 if(m_ocResource != nullptr)
335 m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
339 throw ESBadGetException ("Resource handle is invalid");
344 void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
345 const CloudPropProvStatusCb callback)
347 OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Enter provisionCloudProperties");
351 throw ESInvalidParameterException("Callback is empty");
354 m_cloudPropProvStatusCb = callback;
356 if(cloudProp.getAuthCode().empty() ||
357 cloudProp.getAuthProvider().empty() ||
358 cloudProp.getCiServer().empty())
360 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
368 catch (const std::exception& e)
370 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
371 "Exception caught in provisionCloudProperties = %s", e.what());
373 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
374 CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE);
375 m_cloudPropProvStatusCb(provStatus);
378 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
379 if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
381 ESResult res = ESResult::ES_ERROR;
382 if(!m_enrolleeSecurity.get())
384 m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
388 res = m_enrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
389 cloudProp.getCredID());
390 m_enrolleeSecurity.reset();
391 if(res != ESResult::ES_OK)
393 m_cloudResource = nullptr;
394 std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared<
395 CloudPropProvisioningStatus >(res);
396 m_cloudPropProvStatusCb(provStatus);
402 OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
404 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
406 if (m_cloudResource == nullptr)
408 throw ESBadRequestException ("Cloud Resource not created");
411 CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
412 &RemoteEnrollee::cloudPropProvisioningStatusHandler,
413 this, std::placeholders::_1);
415 m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
416 m_cloudResource->provisionProperties(cloudProp);