X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=service%2Feasy-setup%2Fmediator%2Frichsdk%2Fsrc%2FRemoteEnrollee.cpp;h=941239d537e3db51c47d1c78979063202ae6113a;hb=3c093548382bb2542c87a67e6e5fa32552c29cb3;hp=cb6cb7ae2f690f21fe3797764f4647a21bb64c7e;hpb=cf56a410a2150ae474c676e7e6d01b89552a4873;p=platform%2Fupstream%2Fiotivity.git diff --git a/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp b/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp index cb6cb7a..941239d 100755 --- a/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp +++ b/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp @@ -19,286 +19,673 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "RemoteEnrollee.h" -#include "RemoteEnrolleeResource.h" +#include "EnrolleeResource.h" +#include "CloudResource.h" +#include "OCPlatform.h" #include "ESException.h" #include "logger.h" +#include "OCResource.h" +#include "oic_string.h" #ifdef __WITH_DTLS__ #include "EnrolleeSecurity.h" +#include "base64.h" +#include "oic_malloc.h" +#include "cacommon.h" #endif //__WITH_DTLS namespace OIC { - #define ES_REMOTE_ENROLLEE_TAG "ES_REMOTE_ENROLLEE" - namespace Service { - RemoteEnrollee::RemoteEnrollee(const ProvConfig& provConfig, const WiFiOnboadingConnection& connection) : - m_ProvConfig(provConfig), m_wifiOnboardingconn(connection) + static const char ES_BASE_RES_URI[] = "/oic/res"; + #define ES_REMOTE_ENROLLEE_TAG "ES_REMOTE_ENROLLEE" + #define DISCOVERY_TIMEOUT 1 + + RemoteEnrollee::RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource) { - m_currentESState = CurrentESState::ES_UNKNOWN; - m_isSecured = connection.isSecured; //enrolleeNWProvInfo.needSecuredEasysetup; + m_ocResource = resource; + m_enrolleeResource = std::make_shared(m_ocResource); + m_securityProvStatusCb = nullptr; + m_getConfigurationStatusCb = nullptr; + m_securityPinCb = nullptr; + m_secProvisioningDbPathCb = nullptr; + m_devicePropProvStatusCb = nullptr; + m_cloudPropProvStatusCb = nullptr; + m_connectRequestStatusCb = nullptr; + + m_deviceId = resource->sid(); + } - OIC_LOG ( DEBUG, ES_REMOTE_ENROLLEE_TAG, "Inside RemoteEnrollee constr"); + void RemoteEnrollee::onSecurityStatusHandlerCallback( + const std::shared_ptr< SecProvisioningStatus > status, + std::weak_ptr this_ptr) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onSecurityStatusHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) + { + Ptr->securityStatusHandler(status); + } } -#ifdef __WITH_DTLS__ - ESResult RemoteEnrollee::registerSecurityCallbackHandler(SecurityPinCb securityPinCb, - SecProvisioningDbPathCb secProvisioningDbPathCb) + void RemoteEnrollee::securityStatusHandler( + const std::shared_ptr< SecProvisioningStatus > status) const { - // No need to check NULL for m_secProvisioningDbPathCB as this is not a mandatory - // callback function. If m_secProvisioningDbPathCB is NULL, provisioning manager - // in security layer will try to find the PDM.db file in the local path. - // If PDM.db is found, the provisioning manager operations will succeed. - // Otherwise all the provisioning manager operations will fail. - m_secProvisioningDbPathCb = secProvisioningDbPathCb; - m_securityPinCb = securityPinCb; - return ES_OK; + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr IN"); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "UUID = %s", status->getDeviceUUID().c_str()); + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "ESResult = %d", status->getESResult()); + + if(status->getESResult() == ES_OK) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is successfully done."); + m_securityProvStatusCb(status); + } + else + { + OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is failed."); + m_securityProvStatusCb(status); + } + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr OUT"); } -#endif //__WITH_DTLS__ - void RemoteEnrollee::registerEasySetupStatusHandler(EasySetupStatusCB callback) + ESOwnershipTransferData RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback( + const std::shared_ptr< SecProvisioningStatus > status, + std::weak_ptr this_ptr) { - OIC_LOG ( DEBUG, ES_REMOTE_ENROLLEE_TAG, "Entered registerStatusHandler"); - if(!callback) + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onSecurityStatusWithOptionHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) { - throw ESInvalidParameterException("Callback is empty"); + return Ptr->securityStatusWithOptionHandler(status); } + return ESOwnershipTransferData(); + } + + ESOwnershipTransferData RemoteEnrollee::securityStatusWithOptionHandler( + const std::shared_ptr< SecProvisioningStatus > status) const + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler IN"); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "UUID = %s", status->getDeviceUUID().c_str()); + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "ESResult = %d", status->getESResult()); - if (m_easySetupStatusCb) + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler OUT"); + return m_securityProvStatusCbWithOption(status); + } + + void RemoteEnrollee::onGetStatusHandlerCallback( + const std::shared_ptr< GetEnrolleeStatus > status, + std::weak_ptr this_ptr) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onGetStatusHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) { - throw ESBadRequestException("Callback handler already registered"); + Ptr->getStatusHandler(status); } - else + } + + void RemoteEnrollee::getStatusHandler( + const std::shared_ptr< GetEnrolleeStatus > status) const + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler IN"); + + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler = %d", + status->getESResult()); + m_getStatusCb(status); + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler OUT"); + } + + void RemoteEnrollee::onGetConfigurationStatusHandlerCallback( + const std::shared_ptr< GetConfigurationStatus > status, + std::weak_ptr this_ptr) + { + OIC_LOG(INFO,ES_REMOTE_ENROLLEE_TAG,"onGetConfigurationStatusHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) { - m_easySetupStatusCb = callback; + Ptr->getConfigurationStatusHandler(status); + } + } + + void RemoteEnrollee::getConfigurationStatusHandler ( + const std::shared_ptr< GetConfigurationStatus > status) const + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler IN"); + + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d", + status->getESResult()); + m_getConfigurationStatusCb(status); + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler OUT"); + } - m_remoteResource = std::make_shared< RemoteEnrolleeResource >(m_ProvConfig, m_wifiOnboardingconn); + void RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback( + const std::shared_ptr< DevicePropProvisioningStatus > status, + std::weak_ptr this_ptr) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDevicePropProvisioningStatusHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) + { + Ptr->devicePropProvisioningStatusHandler(status); } } - void RemoteEnrollee::easySetupSecurityStatusCallback( - std::shared_ptr< SecProvisioningResult > secProvisioningResult) + void RemoteEnrollee::devicePropProvisioningStatusHandler( + const std::shared_ptr< DevicePropProvisioningStatus > status) const { - OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "easySetupStatusCallback status is, UUID = %s, " - "Status = %d", secProvisioningResult->getDeviceUUID().c_str(), - secProvisioningResult->getResult()); + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler IN"); + + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "DeviceProvStatus = %d", status->getESResult()); + m_devicePropProvStatusCb(status); +#ifdef __WITH_DTLS__ + if( m_ocResource.get() != nullptr && + !(m_ocResource->connectivityType() & CT_ADAPTER_GATT_BTLE) && + ES_OK == status->getESResult() ) + { + // NOTE: Temporary patch + CAEndpoint_t endpoint = {.adapter = CA_ADAPTER_IP}; + + OCDevAddr address = m_ocResource->getDevAddr(); + OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE, address.addr); + endpoint.port = address.port; + + OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "HOST = %s", endpoint.addr); + OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "PORT = %u", endpoint.port); + CAcloseSslSession(&endpoint); + } +#endif + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler OUT"); + } - if(secProvisioningResult->getResult() == ES_OK) + void RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback( + const std::shared_ptr< CloudPropProvisioningStatus > status, + std::weak_ptr this_ptr) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onCloudPropProvisioningStatusHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) { - OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are successful. " - "Continue with Network information provisioning"); + Ptr->cloudPropProvisioningStatusHandler(status); + } + } - m_currentESState = CurrentESState::ES_OWNED; + void RemoteEnrollee::cloudPropProvisioningStatusHandler ( + const std::shared_ptr< CloudPropProvisioningStatus > status) const + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler IN"); - OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before ProvisionEnrollee"); + OIC_LOG_V(INFO,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d", + status->getESResult()); + m_cloudPropProvStatusCb(status); - RemoteEnrolleeResource::ProvStatusCb provStatusCb = std::bind( - &RemoteEnrollee::provisioningStatusHandler, this, std::placeholders::_1); + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT"); + } - m_remoteResource->registerProvStatusCallback(provStatusCb); - m_remoteResource->provisionEnrollee(); + void RemoteEnrollee::onConnectRequestStatusHandlerCallback( + const std::shared_ptr< ConnectRequestStatus > status, + std::weak_ptr this_ptr) + { + OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onConnectRequestStatusHandlerCallback"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) + { + Ptr->connectRequestStatusHandler(status); } - else + } + + void RemoteEnrollee::connectRequestStatusHandler( + const std::shared_ptr< ConnectRequestStatus > status) const + { + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler IN"); + + OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "RequestConnectStatus = %d", status->getESResult()); + m_connectRequestStatusCb(status); + + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler OUT"); + } + + void RemoteEnrollee::onDiscoveredCallback(const std::shared_ptr resource, + std::weak_ptr this_ptr) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDiscoveredCallback()"); + std::shared_ptr Ptr = this_ptr.lock(); + if(Ptr) { - OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership and ACL are successful"); - std::shared_ptr< EasySetupStatus > easySetupStatus = nullptr; - easySetupStatus = std::make_shared< EasySetupStatus >(DEVICE_NOT_PROVISIONED, - m_ProvConfig); - if (m_easySetupStatusCb) + Ptr->onDeviceDiscovered(resource); + } + } + + void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr resource) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN"); + + try + { + if(resource) { - if (easySetupStatus) - { - m_easySetupStatusCb(easySetupStatus); - } - else + if(!(resource->connectivityType() & CT_ADAPTER_TCP)) { - m_easySetupStatusCb(nullptr); + std::string resourceURI; + std::string hostAddress; + std::string hostDeviceID; + + // Get the resource URI + resourceURI = resource->uri(); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, + "URI of the resource: %s", resourceURI.c_str()); + + // Get the resource host address + hostAddress = resource->host(); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, + "Host address of the resource: %s", hostAddress.c_str()); + + hostDeviceID = resource->sid(); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, + "Host DeviceID of the resource: %s", hostDeviceID.c_str()); + + if(!m_deviceId.empty() && m_deviceId == hostDeviceID) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning"); + m_ocResource = resource; + m_discoveryResponse = true; + m_cond.notify_all(); + } } } } + catch(std::exception& e) + { + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, + "Exception in foundResource: %s", e.what()); + } + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT"); } - void RemoteEnrollee::provisioningStatusHandler( - std::shared_ptr< ProvisioningStatus > provStatus) + ESResult RemoteEnrollee::discoverResource() { - OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering ProvisioningStatusHandler"); + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN"); - OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"ProvStatus = %d", provStatus->getESResult()); + std::string query(""); + query.append(ES_BASE_RES_URI); + query.append("?rt="); + query.append(OC_RSRVD_ES_RES_TYPE_EASYSETUP); - std::shared_ptr< EasySetupStatus > easySetupStatus = nullptr; + OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str()); - if (m_isSecured) + m_discoveryResponse = false; + + onDeviceDiscoveredCb cb = std::bind(&RemoteEnrollee::onDiscoveredCallback, + std::placeholders::_1, + shared_from_this()); + + OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT, cb); + + if (result != OCStackResult::OC_STACK_OK) { - if (m_currentESState >= CurrentESState::ES_OWNED) - { - goto CALLBACK_CHECK; - } - else - { - goto FAILURE; - } + OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, + "Failed discoverResource"); + return ES_ERROR; } - else + + std::unique_lock lck(m_discoverymtx); + m_cond.wait_for(lck, std::chrono::seconds(DISCOVERY_TIMEOUT)); + + if (!m_discoveryResponse) { - goto CALLBACK_CHECK; + OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, + "Failed discoverResource because timeout"); + return ES_ERROR; } - CALLBACK_CHECK: + return ES_OK; + } - if (provStatus->getESResult() == ES_OK) + void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN"); +#ifdef __WITH_DTLS__ + ESResult res = ESResult::ES_ERROR; + if(!callback) { - if (provStatus->getESState() >= ESState::ES_PROVISIONED_ALREADY) - { - easySetupStatus = std::make_shared< EasySetupStatus >(DEVICE_PROVISIONED, - m_ProvConfig); - } - else - { - easySetupStatus = std::make_shared< EasySetupStatus >(DEVICE_NOT_PROVISIONED, - m_ProvConfig); - } + throw ESInvalidParameterException("Callback is empty"); } - else + m_securityProvStatusCb = callback; + + SecurityProvStatusCb securityProvStatusCb = std::bind( + &RemoteEnrollee::onSecurityStatusHandlerCallback, + std::placeholders::_1, + shared_from_this()); + //TODO : DBPath is passed empty as of now. Need to take dbpath from application. + if(!m_localEnrolleeSecurity.get()) { - easySetupStatus = std::make_shared< EasySetupStatus >(DEVICE_NOT_PROVISIONED, - m_ProvConfig); + m_localEnrolleeSecurity = std::make_shared (m_ocResource); } - if (m_easySetupStatusCb) + res = m_localEnrolleeSecurity->provisionOwnership(NULL); + + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res); + securityProvStatusCb(securityProvisioningStatus); +#else + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built."); + + if(!callback) { - if (easySetupStatus) - { - m_easySetupStatusCb(easySetupStatus); - } - else - { - m_easySetupStatusCb(nullptr); - } + throw ESInvalidParameterException("Callback is empty"); } + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus > + ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED); + callback(securityProvisioningStatus); +#endif + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT"); + } - return; - - FAILURE: + void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCbWithOption callback) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN"); +#ifdef __WITH_DTLS__ + ESResult res = ESResult::ES_ERROR; + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + m_securityProvStatusCbWithOption = callback; - easySetupStatus = std::make_shared< EasySetupStatus >(DEVICE_NOT_PROVISIONED, - m_ProvConfig); + SecurityProvStatusCbWithOption securityProvStatusCbWithOption = std::bind( + &RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback, + std::placeholders::_1, + shared_from_this()); - if (easySetupStatus) + if(!m_localEnrolleeSecurity.get()) { - m_easySetupStatusCb(easySetupStatus); + m_localEnrolleeSecurity = std::make_shared (m_ocResource); } - else + + res = m_localEnrolleeSecurity->provisionOwnership(securityProvStatusCbWithOption); + + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res); + securityProvStatusCbWithOption(securityProvisioningStatus); +#else + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built."); + + if(!callback) { - m_easySetupStatusCb(nullptr); + throw ESInvalidParameterException("Callback is empty"); } - return; + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus > + ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED); + callback(securityProvisioningStatus); +#endif + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT"); } - void RemoteEnrollee::startProvisioning() + void RemoteEnrollee::getStatus(const GetStatusCb callback) { - OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering startProvisioning"); - if (m_remoteResource == nullptr) + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus IN"); + + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + + if (m_enrolleeResource == nullptr) { throw ESBadRequestException ("Device not created"); } - ESResult result = ES_ERROR; + m_getStatusCb = callback; - result = m_remoteResource->constructResourceObject(); + GetStatusCb getStatusCb = std::bind( + &RemoteEnrollee::onGetStatusHandlerCallback, + std::placeholders::_1, + shared_from_this()); - if (result == ES_ERROR) + m_enrolleeResource->registerGetStatusCallback(getStatusCb); + m_enrolleeResource->getStatus(); + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT"); + } + + void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN"); + + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + + if (m_enrolleeResource == nullptr) { - OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG, - "Failed to create device using constructResourceObject"); throw ESBadRequestException ("Device not created"); } - m_currentESState = CurrentESState::ES_ONBOARDED; + m_getConfigurationStatusCb = callback; -#ifdef __WITH_DTLS__ - if (m_isSecured && m_currentESState < CurrentESState::ES_OWNED) + GetConfigurationStatusCb getConfigurationStatusCb = std::bind( + &RemoteEnrollee::onGetConfigurationStatusHandlerCallback, + std::placeholders::_1, + shared_from_this()); + + m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb); + m_enrolleeResource->getConfiguration(); + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT"); + } + + void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp, + const DevicePropProvStatusCb callback) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN"); + + if(!callback) { - EnrolleeSecStatusCb securityProvStatusCb = std::bind( - &RemoteEnrollee::easySetupSecurityStatusCallback, - this, - std::placeholders::_1); - //TODO : DBPath is passed empty as of now. Need to take dbpath from application. - m_enrolleeSecurity = std::make_shared (m_remoteResource, ""); + throw ESInvalidParameterException("Callback is empty"); + } - m_enrolleeSecurity->registerCallbackHandler(securityProvStatusCb, - m_securityPinCb, m_secProvisioningDbPathCb); + m_devicePropProvStatusCb = callback; - try - { - EasySetupState easySetupState = m_enrolleeSecurity->performOwnershipTransfer(); - if (easySetupState == DEVICE_NOT_OWNED) - { - OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, - "performOwnershipTransfer returned : %d", - easySetupState); - return; - } - else if (easySetupState == DEVICE_OWNED) - { - OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, - "performOwnershipTransfer returned : %d", - easySetupState); - OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before ProvisionEnrollee"); + if (m_enrolleeResource == nullptr) + { + throw ESBadRequestException ("Device not created"); + } - RemoteEnrolleeResource::ProvStatusCb provStatusCb = std::bind( - &RemoteEnrollee::provisioningStatusHandler, - this, std::placeholders::_1); + DevicePropProvStatusCb devicePropProvStatusCb = std::bind( + &RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback, + std::placeholders::_1, + shared_from_this()); - m_remoteResource->registerProvStatusCallback(provStatusCb); - m_remoteResource->provisionEnrollee(); - } + m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb); + m_enrolleeResource->provisionProperties(deviceProp); + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT"); + } + + void RemoteEnrollee::initCloudResource() + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN"); + + ESResult result = ES_ERROR; + + result = discoverResource(); + + if (result == ES_ERROR) + { + OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, + "Failed to create resource object using discoverResource"); + throw ESBadRequestException ("Resource object not created"); + } + + else + { + if(m_ocResource != nullptr) + { + m_cloudResource = std::make_shared(m_ocResource); } - catch (OCException & e) + else { - OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG, - "Exception for performOwnershipTransfer : %s", e.reason().c_str()); - return ; + throw ESBadGetException ("Resource handle is invalid"); } } -#else - OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Before ProvisionEnrollee"); - - RemoteEnrolleeResource::ProvStatusCb provStatusCb = std::bind( - &RemoteEnrollee::provisioningStatusHandler, this, std::placeholders::_1); - m_remoteResource->registerProvStatusCallback(provStatusCb); - m_remoteResource->provisionEnrollee(); -#endif + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT"); } - void RemoteEnrollee::stopProvisioning() + void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp, + const CloudPropProvStatusCb callback) { - m_currentESState = CurrentESState::ES_UNKNOWN; + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource IN"); + + provisionCloudProperties(NULL, cloudProp, callback); - m_remoteResource->unprovisionEnrollee(); + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource OUT"); } - bool RemoteEnrollee::isEnrolleeProvisioned() + void RemoteEnrollee::provisionCloudProperties(const std::shared_ptr< OC::OCResource > resource, + const CloudProp& cloudProp, + const CloudPropProvStatusCb callback) { - if(m_currentESState >= CurrentESState::ES_PROVISIONED) + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN"); + + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + + m_cloudPropProvStatusCb = callback; + + if((cloudProp.getAuthCode().empty() && cloudProp.getAccessToken().empty()) || + cloudProp.getAuthProvider().empty() || + cloudProp.getCiServer().empty()) + { + throw ESBadRequestException ("Invalid Cloud Provisiong Info."); + } + + if(resource) + { + if(resource->getResourceTypes().at(0) != OC_RSRVD_ES_RES_TYPE_EASYSETUP || + resource->connectivityType() & CT_ADAPTER_TCP) + { + OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Given resource is not valid due to wrong rt or conntype"); + throw ESInvalidParameterException("A given OCResource is wrong"); + } + + auto interfaces = resource->getResourceInterfaces(); + bool isFound = false; + for(auto interface : interfaces) + { + if(interface.compare(BATCH_INTERFACE) == 0) + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "RemoteEnrollee object is succeessfully created"); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "HOST: %s", resource->host().c_str()); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "URI: %s", resource->uri().c_str()); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "SID: %s", resource->sid().c_str()); + OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "CONNECTIVITY: %d", resource->connectivityType()); + isFound = true; + } + } + + if(!isFound) + { + throw ESInvalidParameterException("A given OCResource has no batch interface"); + } + } + + try { - return true; + if(resource == NULL) + { + initCloudResource(); + } + else + { + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Skip to find a provisioning resource"); + m_ocResource = resource; + m_cloudResource = std::make_shared(m_ocResource); + } + } + catch (const std::exception& e) + { + OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG, + "Exception caught in provisionCloudProperties = %s", e.what()); + + std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared< + CloudPropProvisioningStatus >(ESResult::ES_ENROLLEE_DISCOVERY_FAILURE); + m_cloudPropProvStatusCb(provStatus); + return; + } +#if defined(__WITH_DTLS__) && defined(__WITH_TLS__) + if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0)) + { + ESResult res = ESResult::ES_ERROR; + if(!m_cloudEnrolleeSecurity.get()) + { + m_cloudEnrolleeSecurity = std::make_shared (m_ocResource); + } + + + res = m_cloudEnrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(), + cloudProp.getCredID()); + + if(res != ESResult::ES_OK) + { + m_cloudResource = nullptr; + std::shared_ptr< CloudPropProvisioningStatus > provStatus = std::make_shared< + CloudPropProvisioningStatus >(res); + m_cloudPropProvStatusCb(provStatus); + return; + } } else { - return false; + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped."); + } +#endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__) + + if (m_cloudResource == nullptr) + { + throw ESBadRequestException ("Cloud Resource not created"); } + + CloudPropProvStatusCb cloudPropProvStatusCb = std::bind( + &RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback, + std::placeholders::_1, + shared_from_this()); + + m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb); + m_cloudResource->provisionProperties(cloudProp); + + OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT"); } - ProvConfig RemoteEnrollee::getProvConfig () + void RemoteEnrollee::requestToConnect(const std::vector &connectTypes, const ConnectRequestStatusCb callback) { - return m_ProvConfig; - } + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect IN"); + + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + + m_connectRequestStatusCb = callback; + + ConnectRequestStatusCb connectRequestStatusCb = std::bind( + &RemoteEnrollee::onConnectRequestStatusHandlerCallback, + std::placeholders::_1, + shared_from_this()); - WiFiOnboadingConnection RemoteEnrollee::getOnboardConn() - { - return m_wifiOnboardingconn; - } + m_enrolleeResource->registerConnectRequestStatusCallback(connectRequestStatusCb); + m_enrolleeResource->requestToConnect(connectTypes); + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect OUT"); + } } } + +