From: Jihun Ha Date: Thu, 16 Feb 2017 09:32:32 +0000 (+0900) Subject: [IOT-1824] Add an API to request a WiFi Connection to Enrollee X-Git-Tag: 1.3.0~625 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9bce51757d5549e73d685f3bcfe386dc23965f9c;p=platform%2Fupstream%2Fiotivity.git [IOT-1824] Add an API to request a WiFi Connection to Enrollee This API would be helpful to Enrollee when it destroys its Soft AP network and tries to connect an WiFi AP with given WiFi information from Mediator oic.r.easysetup resource + "connect" or "cn" property - type: array of integer(enum) - e.g., "cn" : [ 1 ] or ''cn" : [ 2 ] or "cn" : [ 1, 2 ] // 1 : WiFi, 2 : BLE , 3 : other transport to be added in a future Change-Id: I476c95696c8df243e83232cedc27852c875b2dbe Signed-off-by: Jihun Ha Reviewed-on: https://gerrit.iotivity.org/gerrit/17061 Tested-by: jenkins-iotivity Reviewed-by: Heewon Park Reviewed-by: Uze Choi --- diff --git a/service/easy-setup/inc/escommon.h b/service/easy-setup/inc/escommon.h index 20e4e43..2b66b7a 100755 --- a/service/easy-setup/inc/escommon.h +++ b/service/easy-setup/inc/escommon.h @@ -64,6 +64,7 @@ extern "C" #define OC_RSRVD_ES_MODELNUMBER "mnmo" #define OC_RSRVD_ES_LOCATION "loc" #define OC_RSRVD_ES_HREF "href" +#define OC_RSRVD_ES_CONNECT "cn" /** * Easysetup defined resoruce types and uris. @@ -138,6 +139,15 @@ typedef enum } OAUTH_TOKENTYPE; /** + * @brief A target configuration type to be connected (or executed) + */ +typedef enum +{ + ES_CONNECT_WIFI = 0x01, /**< WiFi Conf resource **/ + ES_CONNECT_COAPCLOUD = 0x02 /**< Coap Cloud Conf resource **/ +} ES_CONNECT_TYPE; + +/** * @brief A result of Easy Setup */ typedef enum diff --git a/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h b/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h index 4c9a8f5..6fe0416 100755 --- a/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h +++ b/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h @@ -972,6 +972,39 @@ namespace OIC ESResult m_result; }; + /** + * Status object for connect API. This object is given to application + * when a response for 'Connect' request from Enrollee is arrived. + */ + class ConnectRequestStatus + { + public: + /** + * Constructor + */ + ConnectRequestStatus(ESResult result) : + m_result(result) + { + } + + /** + * Get a result of Connect request + * + * @return ::ES_OK\n + * ::ES_COMMUNICATION_ERROR\n + * ::ES_ERROR\n + * + * @see ESResult + */ + ESResult getESResult() + { + return m_result; + } + + private: + ESResult m_result; + }; + class ESOwnershipTransferData { public: @@ -1060,6 +1093,12 @@ namespace OIC typedef function< void(shared_ptr< CloudPropProvisioningStatus >) > CloudPropProvStatusCb; /** + * Callback function definition for providing 'Connect' request status + */ + typedef function< void(shared_ptr< ConnectRequestStatus >) > ConnectRequestStatusCb; + + + /** * Callback function definition for providing Enrollee security provisioning status */ typedef function< void(shared_ptr) > SecurityProvStatusCb; diff --git a/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h b/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h index 69ea0ae..76ce155 100755 --- a/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h +++ b/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h @@ -161,6 +161,17 @@ namespace OIC const CloudProp& cloudProp, const CloudPropProvStatusCb callback); + /** + * Notify an Enrollee to Connect WiFi/Cloud + * + * @param connectTypes Target configurations to be connected. E.g. WiFi and coap cloud server + * @param callback will give the result if the connect request succeeds or fails + * + * @see ES_CONNECT_TYPE + * @see ConnectRequestStatusCb + */ + void requestToConnect(const std::vector &connectTypes, const ConnectRequestStatusCb callback); + private: RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource); @@ -185,6 +196,10 @@ namespace OIC const std::shared_ptr< CloudPropProvisioningStatus > status, std::weak_ptr this_ptr); + static void onConnectRequestStatusHandlerCallback( + const std::shared_ptr< ConnectRequestStatus > status, + std::weak_ptr this_ptr); + static void onSecurityStatusHandlerCallback( const std::shared_ptr< SecProvisioningStatus > status, std::weak_ptr this_ptr); @@ -204,6 +219,8 @@ namespace OIC (const std::shared_ptr< DevicePropProvisioningStatus > status) const; void cloudPropProvisioningStatusHandler (const std::shared_ptr< CloudPropProvisioningStatus > status) const; + void connectRequestStatusHandler( + const std::shared_ptr< ConnectRequestStatus > status) const; void securityStatusHandler (const std::shared_ptr< SecProvisioningStatus > status) const; ESOwnershipTransferData securityStatusWithOptionHandler @@ -230,6 +247,7 @@ namespace OIC SecProvisioningDbPathCb m_secProvisioningDbPathCb; DevicePropProvStatusCb m_devicePropProvStatusCb; CloudPropProvStatusCb m_cloudPropProvStatusCb; + ConnectRequestStatusCb m_connectRequestStatusCb; friend class EasySetup; }; diff --git a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp index 48750fb..a1e35e9 100755 --- a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp +++ b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp @@ -36,6 +36,10 @@ namespace OIC EnrolleeResource::EnrolleeResource(std::shared_ptr< OC::OCResource > resource) { m_ocResource = resource; + m_getStatusCb = nullptr; + m_getConfigurationStatusCb = nullptr; + m_devicePropProvStatusCb = nullptr; + m_connectRequestStatusCb = nullptr; } void EnrolleeResource::onEnrolleeResourceSafetyCB(const HeaderOptions& headerOptions, @@ -157,6 +161,41 @@ namespace OIC } } + void EnrolleeResource::onConnectRequestResponse(const HeaderOptions& /*headerOptions*/, + const OCRepresentation& /*rep*/, const int eCode) + { + OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onConnectRequestResponse : eCode = %d", + eCode); + + if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED) + { + ESResult result = ESResult::ES_ERROR; + + OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, + "onConnectRequestResponse : onConnectRequestResponse is failed "); + + if(eCode == OCStackResult::OC_STACK_COMM_ERROR) + { + OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, + "can't receive any response from Enrollee by a timeout threshold."); + result = ESResult::ES_COMMUNICATION_ERROR; + } + + std::shared_ptr< ConnectRequestStatus > connectRequestStatus = std::make_shared< + ConnectRequestStatus >(result); + m_connectRequestStatusCb(connectRequestStatus); + return; + } + + OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, + "onConnectRequestResponse : Provisioning is success. "); + + std::shared_ptr< ConnectRequestStatus > connectRequestStatus = std::make_shared< + ConnectRequestStatus >(ESResult::ES_OK); + m_connectRequestStatusCb(connectRequestStatus); + } + + void EnrolleeResource::registerGetStatusCallback( const GetStatusCb callback) { @@ -175,6 +214,12 @@ namespace OIC m_devicePropProvStatusCb = callback; } + void EnrolleeResource::registerConnectRequestStatusCallback( + const ConnectRequestStatusCb callback) + { + m_connectRequestStatusCb = callback; + } + void EnrolleeResource::getStatus() { OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getStatus IN"); @@ -277,5 +322,38 @@ namespace OIC OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "provisionProperties OUT"); } + + void EnrolleeResource::requestToConnect(const std::vector &connectTypes) + { + OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "requestToConnect IN"); + if (m_ocResource == nullptr) + { + throw ESBadRequestException("Resource is not initialized"); + } + + OC::QueryParamsMap query; + OC::OCRepresentation requestRepresentation; + std::vector connectTypes_int; + connectTypes_int.clear(); + + for(auto it : connectTypes) + { + connectTypes_int.push_back(static_cast(it)); + } + + requestRepresentation.setValue>(OC_RSRVD_ES_CONNECT, connectTypes_int); + + ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + static_cast( + std::bind(&EnrolleeResource::onConnectRequestResponse, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)), + shared_from_this()); + + m_ocResource->post(OC_RSRVD_ES_RES_TYPE_EASYSETUP, OC_RSRVD_INTERFACE_DEFAULT, + requestRepresentation, QueryParamsMap(), cb, OC::QualityOfService::HighQos); + + OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "requestToConnect OUT"); + } } } diff --git a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h index 803e802..f345a91 100755 --- a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h +++ b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h @@ -59,11 +59,13 @@ namespace OIC const GetConfigurationStatusCb callback); void registerDevicePropProvStatusCallback( const DevicePropProvStatusCb callback); + void registerConnectRequestStatusCallback( + const ConnectRequestStatusCb callback); void getConfiguration(); void getStatus(); - void provisionProperties(const DeviceProp& deviceProp); + void requestToConnect(const std::vector &connectTypes); private: std::shared_ptr< OC::OCResource > m_ocResource; @@ -71,6 +73,7 @@ namespace OIC GetStatusCb m_getStatusCb; GetConfigurationStatusCb m_getConfigurationStatusCb; DevicePropProvStatusCb m_devicePropProvStatusCb; + ConnectRequestStatusCb m_connectRequestStatusCb; private: static void onEnrolleeResourceSafetyCB(const HeaderOptions& headerOptions, @@ -89,6 +92,9 @@ namespace OIC void onProvisioningResponse(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); + void onConnectRequestResponse(const HeaderOptions& headerOptions, + const OCRepresentation& rep, + const int eCode); }; } } diff --git a/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp b/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp index 5bba4e5..d5ed06b 100755 --- a/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp +++ b/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp @@ -49,6 +49,7 @@ namespace OIC m_secProvisioningDbPathCb = nullptr; m_devicePropProvStatusCb = nullptr; m_cloudPropProvStatusCb = nullptr; + m_connectRequestStatusCb = nullptr; m_deviceId = resource->sid(); } @@ -204,6 +205,29 @@ namespace OIC OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT"); } + 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); + } + } + + 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) { @@ -626,6 +650,28 @@ namespace OIC OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT"); } + + void RemoteEnrollee::requestToConnect(const std::vector &connectTypes, const ConnectRequestStatusCb callback) + { + 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()); + + m_enrolleeResource->registerConnectRequestStatusCallback(connectRequestStatusCb); + m_enrolleeResource->requestToConnect(connectTypes); + + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect OUT"); + } } } diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp index 7ecf8da..55513a8 100755 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp @@ -255,6 +255,41 @@ void provisionDeviceProperty() } } +void connectRequestStatusCallback(std::shared_ptr< ConnectRequestStatus > requestStatus) +{ + if(requestStatus->getESResult() != ES_OK) + { + cout << "Request to connection is failed." << endl; + return; + } + else + { + cout << "Request to connection is success." << endl; + } +} + +void requestToConnect() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + try + { + std::vector types; + types.push_back(ES_CONNECT_WIFI); + types.push_back(ES_CONNECT_COAPCLOUD); + remoteEnrollee->requestToConnect(types, connectRequestStatusCallback); + } + catch (OCException &e) + { + std::cout << "Exception during provisionDeviceProperties call" << e.reason(); + return; + } +} + void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus) { switch (provStatus->getESResult()) @@ -360,9 +395,9 @@ void foundResource(std::shared_ptr resource) void discoveryEnrolleeResource() { - try - { - std::ostringstream requestURI; + try + { + std::ostringstream requestURI; requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP; OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource); std::cout<< "Finding Resource... " < lck(g_discoverymtx); g_cond.wait_for(lck, std::chrono::seconds(5)); } - catch (OCException &e) - { - std::cout << "Exception in discoveryEnrolleeResource: "< requestStatus) +{ + if(requestStatus->getESResult() != ES_OK) + { + cout << "Request to connection is failed." << endl; + return; + } + else + { + cout << "Request to connection is success." << endl; + } +} + +void requestToConnect() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + try + { + std::vector types; + types.push_back(ES_CONNECT_WIFI); + types.push_back(ES_CONNECT_COAPCLOUD); + remoteEnrollee->requestToConnect(types, connectRequestStatusCallback); + } + catch (OCException &e) + { + std::cout << "Exception during provisionDeviceProperties call" << e.reason(); + return; + } +} + void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus) { switch (provStatus->getESResult()) @@ -357,9 +392,9 @@ void foundResource(std::shared_ptr resource) void discoveryEnrolleeResource() { - try - { - std::ostringstream requestURI; + try + { + std::ostringstream requestURI; requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP; OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource); std::cout<< "Finding Resource... " <