#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.
OAUTH_TOKENTYPE_MAC
} 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
*/
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:
*/
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
*/
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<ES_CONNECT_TYPE> &connectTypes, const ConnectRequestStatusCb callback);
+
private:
RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource);
const std::shared_ptr< CloudPropProvisioningStatus > status,
std::weak_ptr<RemoteEnrollee> this_ptr);
+ static void onConnectRequestStatusHandlerCallback(
+ const std::shared_ptr< ConnectRequestStatus > status,
+ std::weak_ptr<RemoteEnrollee> this_ptr);
+
static void onSecurityStatusHandlerCallback(
const std::shared_ptr< SecProvisioningStatus > status,
std::weak_ptr<RemoteEnrollee> this_ptr);
(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
SecProvisioningDbPathCb m_secProvisioningDbPathCb;
DevicePropProvStatusCb m_devicePropProvStatusCb;
CloudPropProvStatusCb m_cloudPropProvStatusCb;
+ ConnectRequestStatusCb m_connectRequestStatusCb;
friend class EasySetup;
};
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,
}
}
+ 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)
{
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");
OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "provisionProperties OUT");
}
+
+ void EnrolleeResource::requestToConnect(const std::vector<ES_CONNECT_TYPE> &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<int> connectTypes_int;
+ connectTypes_int.clear();
+
+ for(auto it : connectTypes)
+ {
+ connectTypes_int.push_back(static_cast<int>(it));
+ }
+
+ requestRepresentation.setValue<std::vector<int>>(OC_RSRVD_ES_CONNECT, connectTypes_int);
+
+ ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ static_cast<ESEnrolleeResourceCb>(
+ 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");
+ }
}
}
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<ES_CONNECT_TYPE> &connectTypes);
private:
std::shared_ptr< OC::OCResource > m_ocResource;
GetStatusCb m_getStatusCb;
GetConfigurationStatusCb m_getConfigurationStatusCb;
DevicePropProvStatusCb m_devicePropProvStatusCb;
+ ConnectRequestStatusCb m_connectRequestStatusCb;
private:
static void onEnrolleeResourceSafetyCB(const HeaderOptions& headerOptions,
void onProvisioningResponse(const HeaderOptions& headerOptions,
const OCRepresentation& rep,
const int eCode);
+ void onConnectRequestResponse(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep,
+ const int eCode);
};
}
}
m_secProvisioningDbPathCb = nullptr;
m_devicePropProvStatusCb = nullptr;
m_cloudPropProvStatusCb = nullptr;
+ m_connectRequestStatusCb = nullptr;
m_deviceId = resource->sid();
}
OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT");
}
+ void RemoteEnrollee::onConnectRequestStatusHandlerCallback(
+ const std::shared_ptr< ConnectRequestStatus > status,
+ std::weak_ptr<RemoteEnrollee> this_ptr)
+ {
+ OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onConnectRequestStatusHandlerCallback");
+ std::shared_ptr<RemoteEnrollee> 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<OC::OCResource> resource,
std::weak_ptr<RemoteEnrollee> this_ptr)
{
OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");
}
+
+ void RemoteEnrollee::requestToConnect(const std::vector<ES_CONNECT_TYPE> &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");
+ }
}
}
}
}
+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<ES_CONNECT_TYPE> 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())
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... " <<std::endl;
std::unique_lock<std::mutex> lck(g_discoverymtx);
g_cond.wait_for(lck, std::chrono::seconds(5));
}
- catch (OCException &e)
- {
- std::cout << "Exception in discoveryEnrolleeResource: "<<e.what();
- }
+ catch (OCException &e)
+ {
+ std::cout << "Exception in discoveryEnrolleeResource: "<<e.what();
+ }
}
void DisplayMenu()
{
- constexpr int DISCOVERY_ENROLLEE = 1;
+ constexpr int DISCOVERY_ENROLLEE = 1;
constexpr int PROVISION_SECURITY = 2;
constexpr int GET_STATUS = 3;
constexpr int GET_CONFIGURATION = 4;
constexpr int PROVISION_DEVICE_PROPERTY = 5;
- constexpr int PROVISION_CLOUD_PROPERTY = 6;
+ constexpr int REQUEST_TO_CONNECT = 6;
+ constexpr int PROVISION_CLOUD_PROPERTY = 7;
std::cout << "========================================================\n";
std::cout << DISCOVERY_ENROLLEE << ". Discovery Enrollee Resource \n";
std::cout << GET_STATUS << ". Get Status from Enrollee \n";
std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee \n";
std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
+ std::cout << REQUEST_TO_CONNECT << ". Request to Connect \n";
std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property \n";
std::cout << "========================================================\n";
case PROVISION_DEVICE_PROPERTY:
provisionDeviceProperty();
break;
+ case REQUEST_TO_CONNECT:
+ requestToConnect();
+ break;
case PROVISION_CLOUD_PROPERTY:
provisionCloudProperty();
break;
}
}
+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<ES_CONNECT_TYPE> 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())
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... " <<std::endl;
void DisplayMenu()
{
- constexpr int DISCOVERY_ENROLLEE = 1;
+ constexpr int DISCOVERY_ENROLLEE = 1;
constexpr int PROVISION_SECURITY = 2;
constexpr int GET_STATUS = 3;
constexpr int GET_CONFIGURATION = 4;
constexpr int PROVISION_DEVICE_PROPERTY = 5;
- constexpr int PROVISION_CLOUD_PROPERTY = 6;
+ constexpr int REQUEST_TO_CONNECT = 6;
+ constexpr int PROVISION_CLOUD_PROPERTY = 7;
std::cout << "========================================================\n";
std::cout << DISCOVERY_ENROLLEE << ". Discovery Enrollee Resource \n";
std::cout << GET_STATUS << ". Get Status from Enrollee \n";
std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee \n";
std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
+ std::cout << REQUEST_TO_CONNECT << ". Request to Connect \n";
std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property \n";
std::cout << "========================================================\n";
case PROVISION_DEVICE_PROPERTY:
provisionDeviceProperty();
break;
+ case REQUEST_TO_CONNECT:
+ requestToConnect();
+ break;
case PROVISION_CLOUD_PROPERTY:
provisionCloudProperty();
break;