-//******************************************************************\r
-//\r
-// Copyright 2015 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-// http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-#include <functional>\r
-#include <time.h>\r
-\r
-#include "RemoteEnrolleeResource.h"\r
-\r
-#include "OCPlatform.h"\r
-#include "ESException.h"\r
-#include "OCResource.h"\r
-#include "logger.h"\r
-\r
-namespace OIC\r
-{\r
- namespace Service\r
- {\r
- #define ES_REMOTE_ENROLLEE_RES_TAG "ES_REMOTE_ENROLLEE_RES"\r
- #define DISCOVERY_TIMEOUT 5\r
-\r
- static const char ES_BASE_RES_URI[] = "/oic/res";\r
- static const char ES_PROV_RES_URI[] = "/oic/prov";\r
- static const char ES_PROV_RES_TYPE[] = "oic.r.prov";\r
-\r
- RemoteEnrolleeResource::RemoteEnrolleeResource(EnrolleeNWProvInfo enrolleeNWProvInfo)\r
- {\r
- m_enrolleeNWProvInfo = enrolleeNWProvInfo;\r
- m_discoveryResponse = false;\r
- }\r
-\r
- void RemoteEnrolleeResource::checkProvInformationCb(const HeaderOptions& /*headerOptions*/,\r
- const OCRepresentation& rep, const int eCode)\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : %s, eCode = %d",\r
- rep.getUri().c_str(),\r
- eCode);\r
-\r
- if (eCode != 0)\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : Provisioning is failed ");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
-\r
- int ps = -1;\r
- std::string tnn = "";\r
- std::string cd = "";\r
-\r
- rep.getValue(OC_RSRVD_ES_PS, ps);\r
- rep.getValue(OC_RSRVD_ES_TNN, tnn);\r
- rep.getValue(OC_RSRVD_ES_CD, cd);\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : ps - %d", ps);\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : tnn - %s", tnn.c_str());\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : cd - %s", cd.c_str());\r
-\r
- //Provisioning status check\r
- if (ps == ES_PS_PROVISIONING_COMPLETED)\r
- {\r
- if (tnn != std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ssid))\r
- {\r
- OC_LOG_V (ERROR, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : Network SSID is not the same as the "\r
- "SSID provisioned");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_ERROR,\r
- ESState::ES_PROVISIONING_ERROR);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
-\r
- if (cd != std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.pwd))\r
- {\r
- OC_LOG_V (ERROR, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : Network PWD is not the same as the "\r
- "PWD provisioned");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_ERROR,\r
- ESState::ES_PROVISIONING_ERROR);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : Provisioning is success ");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_OK, ESState::ES_PROVISIONING_SUCCESS);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
- else\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "checkProvInformationCb : Provisioning is failed ");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
- }\r
-\r
- void RemoteEnrolleeResource::getProvStatusResponse(const HeaderOptions& /*headerOptions*/,\r
- const OCRepresentation& rep, const int eCode)\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : %s, eCode = %d",\r
- rep.getUri().c_str(),\r
- eCode);\r
-\r
- if (eCode != 0)\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "getProvStatusResponse : Provisioning is failed ");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
-\r
- int ps = -1;\r
- std::string tnn = "";\r
- std::string cd = "";\r
-\r
- rep.getValue(OC_RSRVD_ES_PS, ps);\r
- rep.getValue(OC_RSRVD_ES_TNN, tnn);\r
- rep.getValue(OC_RSRVD_ES_CD, cd);\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : ps - %d",\r
- ps);\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : tnn - %s",\r
- tnn.c_str());\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : cd - %s",\r
- cd.c_str());\r
-\r
- if (ps == ES_PS_NEED_PROVISIONING) //Indicates the need for provisioning\r
- {\r
- OCRepresentation provisioningRepresentation;\r
-\r
- provisioningRepresentation.setValue(OC_RSRVD_ES_TNN,\r
- std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ssid));\r
- provisioningRepresentation.setValue(OC_RSRVD_ES_CD,\r
- std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.pwd));\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : ssid - %s",\r
- m_enrolleeNWProvInfo.netAddressInfo.WIFI.ssid);\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : pwd - %s",\r
- m_enrolleeNWProvInfo.netAddressInfo.WIFI.pwd);\r
-\r
- m_ocResource->put(provisioningRepresentation, QueryParamsMap(),\r
- std::function<\r
- void(const HeaderOptions& headerOptions,\r
- const OCRepresentation& rep, const int eCode) >(\r
- std::bind(&RemoteEnrolleeResource::checkProvInformationCb, this,\r
- std::placeholders::_1, std::placeholders::_2,\r
- std::placeholders::_3)));\r
- }\r
- else if (ps == ES_PS_PROVISIONING_COMPLETED) //Indicates that provisioning is completed\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "getProvStatusResponse : Provisioning is successful");\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_OK, ESState::ES_PROVISIONED_ALREADY);\r
- m_provStatusCb(provStatus);\r
- }\r
- }\r
-\r
- void RemoteEnrolleeResource::registerProvStatusCallback(ProvStatusCb provStatusCb)\r
- {\r
- m_provStatusCb = provStatusCb;\r
- }\r
-\r
- ESResult RemoteEnrolleeResource::ESDiscoveryTimeout(unsigned short waittime)\r
- {\r
- struct timespec startTime;\r
- startTime.tv_sec=0;\r
- startTime.tv_sec=0;\r
- struct timespec currTime;\r
- currTime.tv_sec=0;\r
- currTime.tv_nsec=0;\r
-\r
- ESResult res = ES_OK;\r
- #ifdef _POSIX_MONOTONIC_CLOCK\r
- int clock_res = clock_gettime(CLOCK_MONOTONIC, &startTime);\r
- #else\r
- int clock_res = clock_gettime(CLOCK_REALTIME, &startTime);\r
- #endif\r
-\r
- if (0 != clock_res)\r
- {\r
- return ES_ERROR;\r
- }\r
-\r
- while (ES_OK == res || m_discoveryResponse == false)\r
- {\r
- #ifdef _POSIX_MONOTONIC_CLOCK\r
- clock_res = clock_gettime(CLOCK_MONOTONIC, &currTime);\r
- #else\r
- clock_res = clock_gettime(CLOCK_REALTIME, &currTime);\r
- #endif\r
-\r
- if (0 != clock_res)\r
- {\r
- return ES_ERROR;\r
- }\r
- long elapsed = (currTime.tv_sec - startTime.tv_sec);\r
- if (elapsed > waittime)\r
- {\r
- return ES_OK;\r
- }\r
- if (m_discoveryResponse)\r
- {\r
- res = ES_OK;\r
- }\r
- }\r
- return res;\r
- }\r
-\r
- void RemoteEnrolleeResource::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)\r
- {\r
- OC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onDeviceDiscovered");\r
-\r
- std::string resourceURI;\r
- std::string hostAddress;\r
- try\r
- {\r
- if(resource)\r
- {\r
- // Get the resource URI\r
- resourceURI = resource->uri();\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "URI of the resource: %s", resourceURI.c_str());\r
-\r
- // Get the resource host address\r
- hostAddress = resource->host();\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "Host address of the resource: %s", hostAddress.c_str());\r
-\r
- std::size_t foundIP =\r
- hostAddress.find(\r
- std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress));\r
-\r
- if(resourceURI == ES_PROV_RES_URI && foundIP!=std::string::npos)\r
- {\r
- m_ocResource = resource;\r
- m_discoveryResponse = true;\r
-\r
- OC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "Found the device with the resource");\r
-\r
- return;\r
- }\r
- else\r
- {\r
- OC_LOG (ERROR, ES_REMOTE_ENROLLEE_RES_TAG, "NOT the intended resource.");\r
- }\r
- }\r
- else\r
- {\r
- OC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "Resource is invalid");\r
- }\r
-\r
- }\r
- catch(std::exception& e)\r
- {\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "Exception in foundResource: %s", e.what());\r
- }\r
- }\r
-\r
-\r
- ESResult RemoteEnrolleeResource::constructResourceObject()\r
- {\r
- if (m_ocResource != nullptr)\r
- {\r
- throw ESBadRequestException("Remote resource is already created");\r
- }\r
-\r
-#ifdef REMOTE_ARDUINO_ENROLEE\r
- //This process will create OCResource with port 55555 which is specific\r
- // to Arduino WiFi enrollee\r
- try\r
- {\r
-\r
- std::vector< std::string > interface =\r
- { DEFAULT_INTERFACE};\r
- std::vector< std::string > resTypes =\r
- { ES_PROV_RES_TYPE};\r
-\r
- OC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "Before OCPlatform::constructResourceObject");\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "m_host = %s",\r
- m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress);\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "ES_PROV_RES_URI = %s", ES_PROV_RES_URI);\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "m_connectivityType = %d",\r
- m_enrolleeNWProvInfo.connType);\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "resTypes = %s",\r
- resTypes.at(0).c_str());\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "interface = %s", interface.at(0).c_str());\r
-\r
- std::string host;\r
- if(m_enrolleeNWProvInfo.needSecuredEasysetup)\r
- {\r
- host.append("coaps://");\r
- }\r
- else\r
- {\r
- host.append("coap://");\r
- }\r
-\r
- if(m_enrolleeNWProvInfo.connType == CT_ADAPTER_IP)\r
- {\r
- // TODO : RemoteEnrollee is current handling easysetup on IP transport.\r
- // WiFiRemoteEnrollee need to extend RemoteEnrollee for providing IP specific\r
- // Enrollee easysetup.\r
-\r
- host.append(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress);\r
- //TODO : If the target Enrollee is not a Arduino Wi-Fi device,\r
- // then the port number will be found during resource discovery instead of\r
- // using 55555\r
- host.append(":55555");\r
- }\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "HOST = %s", host.c_str());\r
-\r
- m_ocResource = OC::OCPlatform::constructResourceObject(host,\r
- ES_PROV_RES_URI,\r
- m_enrolleeNWProvInfo.connType,\r
- true,\r
- resTypes,\r
- interface);\r
- OC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "created OCResource : %s", m_ocResource->uri().c_str());\r
-\r
- return ES_OK;\r
- }\r
- catch (OCException & e)\r
- {\r
- OC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,\r
- "Exception for constructResourceObject : %s", e.reason().c_str());\r
- }\r
-\r
-#else\r
- std::string host("");\r
- std::string query("");\r
-\r
- if (m_enrolleeNWProvInfo.needSecuredEasysetup)\r
- {\r
- host.append("coaps://");\r
- }\r
- else\r
- {\r
- host.append("coap://");\r
- }\r
-\r
- if (m_enrolleeNWProvInfo.connType == CT_ADAPTER_IP)\r
- {\r
- // TODO : RemoteEnrollee is current handling easysetup on IP transport.\r
- // WiFiRemoteEnrollee need to extend RemoteEnrollee for providing IP specific\r
- // Enrollee easysetup.\r
-\r
- host.append(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress);\r
- }\r
-\r
- query.append(ES_BASE_RES_URI);\r
- query.append("?rt=");\r
- query.append(ES_PROV_RES_TYPE);\r
-\r
- OC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "Before OCPlatform::constructResourceObject");\r
-\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "host = %s",\r
- host.c_str());\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "query = %s", query.c_str());\r
- OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "m_connectivityType = %d",\r
- m_enrolleeNWProvInfo.connType);\r
-\r
- m_discoveryResponse = false;\r
- std::function< void (std::shared_ptr<OC::OCResource>) > onDeviceDiscoveredCb =\r
- std::bind(&RemoteEnrolleeResource::onDeviceDiscovered, this,\r
- std::placeholders::_1);\r
- OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT,\r
- onDeviceDiscoveredCb);\r
-\r
- if (result != OCStackResult::OC_STACK_OK)\r
- {\r
- OC_LOG(ERROR,ES_REMOTE_ENROLLEE_RES_TAG,\r
- "Failed to create device using constructResourceObject");\r
- return ES_ERROR;\r
- }\r
-\r
-\r
- ESResult foundResponse = ESDiscoveryTimeout (DISCOVERY_TIMEOUT);\r
-\r
- if (!m_discoveryResponse)\r
- {\r
- OC_LOG(ERROR,ES_REMOTE_ENROLLEE_RES_TAG,\r
- "Failed to create device using constructResourceObject");\r
- return ES_ERROR;\r
- }\r
-\r
- return ES_OK;\r
-#endif\r
- }\r
-\r
- void RemoteEnrolleeResource::provisionEnrollee()\r
-\r
- {\r
- if (m_ocResource == nullptr)\r
- {\r
- throw ESBadRequestException("Resource is not initialized");\r
- }\r
-\r
- OC::QueryParamsMap query;\r
- OC::OCRepresentation rep;\r
-\r
- std::function< OCStackResult(void) > getProvisioingStatus = [&]\r
- { return m_ocResource->get(m_ocResource->getResourceTypes().at(0),\r
- m_ocResource->getResourceInterfaces().at(0), query,\r
- std::function<\r
- void(const HeaderOptions& headerOptions, const OCRepresentation& rep,\r
- const int eCode) >(\r
- std::bind(&RemoteEnrolleeResource::getProvStatusResponse, this,\r
- std::placeholders::_1, std::placeholders::_2,\r
- std::placeholders::_3)));\r
- };\r
-\r
- OCStackResult result = getProvisioingStatus();\r
-\r
- if (result != OCStackResult::OC_STACK_OK)\r
- {\r
- std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<\r
- ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);\r
- m_provStatusCb(provStatus);\r
- return;\r
- }\r
- }\r
-\r
- void RemoteEnrolleeResource::unprovisionEnrollee()\r
- {\r
- if (m_ocResource == nullptr)\r
- {\r
- throw ESBadRequestException("Resource is not initialized");\r
- }\r
-\r
- OCRepresentation provisioningRepresentation;\r
-\r
- provisioningRepresentation.setValue(OC_RSRVD_ES_TNN, "");\r
- provisioningRepresentation.setValue(OC_RSRVD_ES_CD, "");\r
-\r
- m_ocResource->post(provisioningRepresentation, QueryParamsMap(),\r
- std::function<\r
- void(const HeaderOptions& headerOptions, const OCRepresentation& rep,\r
- const int eCode) >(\r
- std::bind(&RemoteEnrolleeResource::checkProvInformationCb, this,\r
- std::placeholders::_1, std::placeholders::_2,\r
- std::placeholders::_3)));\r
- }\r
- }\r
-}\r
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <functional>
+#include <time.h>
+
+#include "RemoteEnrolleeResource.h"
+
+#include "OCPlatform.h"
+#include "ESException.h"
+#include "OCResource.h"
+#include "logger.h"
+
+namespace OIC
+{
+ namespace Service
+ {
+ #define ES_REMOTE_ENROLLEE_RES_TAG "ES_REMOTE_ENROLLEE_RES"
+ #define DISCOVERY_TIMEOUT 5
+
+ static const char ES_BASE_RES_URI[] = "/oic/res";
+ static const char ES_PROV_RES_URI[] = "/oic/prov";
+ static const char ES_PROV_RES_TYPE[] = "oic.r.prov";
+
+ RemoteEnrolleeResource::RemoteEnrolleeResource(EnrolleeNWProvInfo enrolleeNWProvInfo)
+ {
+ m_enrolleeNWProvInfo = enrolleeNWProvInfo;
+ m_discoveryResponse = false;
+ }
+
+ void RemoteEnrolleeResource::checkProvInformationCb(const HeaderOptions& /*headerOptions*/,
+ const OCRepresentation& rep, const int eCode)
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : %s, eCode = %d",
+ rep.getUri().c_str(),
+ eCode);
+
+ if (eCode != 0)
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : Provisioning is failed ");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);
+ m_provStatusCb(provStatus);
+ return;
+ }
+
+ int ps = -1;
+ std::string tnn = "";
+ std::string cd = "";
+
+ rep.getValue(OC_RSRVD_ES_PS, ps);
+ rep.getValue(OC_RSRVD_ES_TNN, tnn);
+ rep.getValue(OC_RSRVD_ES_CD, cd);
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : ps - %d", ps);
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : tnn - %s", tnn.c_str());
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : cd - %s", cd.c_str());
+
+ //Provisioning status check
+ if (ps == ES_PS_PROVISIONING_COMPLETED)
+ {
+ if (tnn != std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ssid))
+ {
+ OC_LOG_V (ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : Network SSID is not the same as the "
+ "SSID provisioned");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_ERROR,
+ ESState::ES_PROVISIONING_ERROR);
+ m_provStatusCb(provStatus);
+ return;
+ }
+
+ if (cd != std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.pwd))
+ {
+ OC_LOG_V (ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : Network PWD is not the same as the "
+ "PWD provisioned");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_ERROR,
+ ESState::ES_PROVISIONING_ERROR);
+ m_provStatusCb(provStatus);
+ return;
+ }
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : Provisioning is success ");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_OK, ESState::ES_PROVISIONING_SUCCESS);
+ m_provStatusCb(provStatus);
+ return;
+ }
+ else
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "checkProvInformationCb : Provisioning is failed ");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);
+ m_provStatusCb(provStatus);
+ return;
+ }
+ }
+
+ void RemoteEnrolleeResource::getProvStatusResponse(const HeaderOptions& /*headerOptions*/,
+ const OCRepresentation& rep, const int eCode)
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : %s, eCode = %d",
+ rep.getUri().c_str(),
+ eCode);
+
+ if (eCode != 0)
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "getProvStatusResponse : Provisioning is failed ");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);
+ m_provStatusCb(provStatus);
+ return;
+ }
+
+ int ps = -1;
+ std::string tnn = "";
+ std::string cd = "";
+
+ rep.getValue(OC_RSRVD_ES_PS, ps);
+ rep.getValue(OC_RSRVD_ES_TNN, tnn);
+ rep.getValue(OC_RSRVD_ES_CD, cd);
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : ps - %d",
+ ps);
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : tnn - %s",
+ tnn.c_str());
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : cd - %s",
+ cd.c_str());
+
+ if (ps == ES_PS_NEED_PROVISIONING) //Indicates the need for provisioning
+ {
+ OCRepresentation provisioningRepresentation;
+
+ provisioningRepresentation.setValue(OC_RSRVD_ES_TNN,
+ std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ssid));
+ provisioningRepresentation.setValue(OC_RSRVD_ES_CD,
+ std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.pwd));
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : ssid - %s",
+ m_enrolleeNWProvInfo.netAddressInfo.WIFI.ssid);
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getProvStatusResponse : pwd - %s",
+ m_enrolleeNWProvInfo.netAddressInfo.WIFI.pwd);
+
+ m_ocResource->put(provisioningRepresentation, QueryParamsMap(),
+ std::function<
+ void(const HeaderOptions& headerOptions,
+ const OCRepresentation& rep, const int eCode) >(
+ std::bind(&RemoteEnrolleeResource::checkProvInformationCb, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)));
+ }
+ else if (ps == ES_PS_PROVISIONING_COMPLETED) //Indicates that provisioning is completed
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "getProvStatusResponse : Provisioning is successful");
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_OK, ESState::ES_PROVISIONED_ALREADY);
+ m_provStatusCb(provStatus);
+ }
+ }
+
+ void RemoteEnrolleeResource::registerProvStatusCallback(ProvStatusCb provStatusCb)
+ {
+ m_provStatusCb = provStatusCb;
+ }
+
+ ESResult RemoteEnrolleeResource::ESDiscoveryTimeout(unsigned short waittime)
+ {
+ struct timespec startTime;
+ startTime.tv_sec=0;
+ startTime.tv_sec=0;
+ struct timespec currTime;
+ currTime.tv_sec=0;
+ currTime.tv_nsec=0;
+
+ ESResult res = ES_OK;
+ #ifdef _POSIX_MONOTONIC_CLOCK
+ int clock_res = clock_gettime(CLOCK_MONOTONIC, &startTime);
+ #else
+ int clock_res = clock_gettime(CLOCK_REALTIME, &startTime);
+ #endif
+
+ if (0 != clock_res)
+ {
+ return ES_ERROR;
+ }
+
+ while (ES_OK == res || m_discoveryResponse == false)
+ {
+ #ifdef _POSIX_MONOTONIC_CLOCK
+ clock_res = clock_gettime(CLOCK_MONOTONIC, &currTime);
+ #else
+ clock_res = clock_gettime(CLOCK_REALTIME, &currTime);
+ #endif
+
+ if (0 != clock_res)
+ {
+ return ES_ERROR;
+ }
+ long elapsed = (currTime.tv_sec - startTime.tv_sec);
+ if (elapsed > waittime)
+ {
+ return ES_OK;
+ }
+ if (m_discoveryResponse)
+ {
+ res = ES_OK;
+ }
+ }
+ return res;
+ }
+
+ void RemoteEnrolleeResource::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
+ {
+ OC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onDeviceDiscovered");
+
+ std::string resourceURI;
+ std::string hostAddress;
+ try
+ {
+ if(resource)
+ {
+ // Get the resource URI
+ resourceURI = resource->uri();
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "URI of the resource: %s", resourceURI.c_str());
+
+ // Get the resource host address
+ hostAddress = resource->host();
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "Host address of the resource: %s", hostAddress.c_str());
+
+ std::size_t foundIP =
+ hostAddress.find(
+ std::string(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress));
+
+ if(resourceURI == ES_PROV_RES_URI && foundIP!=std::string::npos)
+ {
+ m_ocResource = resource;
+ m_discoveryResponse = true;
+
+ OC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "Found the device with the resource");
+
+ return;
+ }
+ else
+ {
+ OC_LOG (ERROR, ES_REMOTE_ENROLLEE_RES_TAG, "NOT the intended resource.");
+ }
+ }
+ else
+ {
+ OC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "Resource is invalid");
+ }
+
+ }
+ catch(std::exception& e)
+ {
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "Exception in foundResource: %s", e.what());
+ }
+ }
+
+
+ ESResult RemoteEnrolleeResource::constructResourceObject()
+ {
+ if (m_ocResource != nullptr)
+ {
+ throw ESBadRequestException("Remote resource is already created");
+ }
+
+#ifdef REMOTE_ARDUINO_ENROLEE
+ //This process will create OCResource with port 55555 which is specific
+ // to Arduino WiFi enrollee
+ try
+ {
+
+ std::vector< std::string > interface =
+ { DEFAULT_INTERFACE};
+ std::vector< std::string > resTypes =
+ { ES_PROV_RES_TYPE};
+
+ OC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "Before OCPlatform::constructResourceObject");
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "m_host = %s",
+ m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress);
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "ES_PROV_RES_URI = %s", ES_PROV_RES_URI);
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "m_connectivityType = %d",
+ m_enrolleeNWProvInfo.connType);
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "resTypes = %s",
+ resTypes.at(0).c_str());
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "interface = %s", interface.at(0).c_str());
+
+ std::string host;
+ if(m_enrolleeNWProvInfo.needSecuredEasysetup)
+ {
+ host.append("coaps://");
+ }
+ else
+ {
+ host.append("coap://");
+ }
+
+ if(m_enrolleeNWProvInfo.connType == CT_ADAPTER_IP)
+ {
+ // TODO : RemoteEnrollee is current handling easysetup on IP transport.
+ // WiFiRemoteEnrollee need to extend RemoteEnrollee for providing IP specific
+ // Enrollee easysetup.
+
+ host.append(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress);
+ //TODO : If the target Enrollee is not a Arduino Wi-Fi device,
+ // then the port number will be found during resource discovery instead of
+ // using 55555
+ host.append(":55555");
+ }
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "HOST = %s", host.c_str());
+
+ m_ocResource = OC::OCPlatform::constructResourceObject(host,
+ ES_PROV_RES_URI,
+ m_enrolleeNWProvInfo.connType,
+ true,
+ resTypes,
+ interface);
+ OC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+ "created OCResource : %s", m_ocResource->uri().c_str());
+
+ return ES_OK;
+ }
+ catch (OCException & e)
+ {
+ OC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
+ "Exception for constructResourceObject : %s", e.reason().c_str());
+ }
+
+#else
+ std::string host("");
+ std::string query("");
+
+ if (m_enrolleeNWProvInfo.needSecuredEasysetup)
+ {
+ host.append("coaps://");
+ }
+ else
+ {
+ host.append("coap://");
+ }
+
+ if (m_enrolleeNWProvInfo.connType == CT_ADAPTER_IP)
+ {
+ // TODO : RemoteEnrollee is current handling easysetup on IP transport.
+ // WiFiRemoteEnrollee need to extend RemoteEnrollee for providing IP specific
+ // Enrollee easysetup.
+
+ host.append(m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress);
+ }
+
+ query.append(ES_BASE_RES_URI);
+ query.append("?rt=");
+ query.append(ES_PROV_RES_TYPE);
+
+ OC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "Before OCPlatform::constructResourceObject");
+
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "host = %s",
+ host.c_str());
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "query = %s", query.c_str());
+ OC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "m_connectivityType = %d",
+ m_enrolleeNWProvInfo.connType);
+
+ m_discoveryResponse = false;
+ std::function< void (std::shared_ptr<OC::OCResource>) > onDeviceDiscoveredCb =
+ std::bind(&RemoteEnrolleeResource::onDeviceDiscovered, this,
+ std::placeholders::_1);
+ OCStackResult result = OC::OCPlatform::findResource("", query, CT_DEFAULT,
+ onDeviceDiscoveredCb);
+
+ if (result != OCStackResult::OC_STACK_OK)
+ {
+ OC_LOG(ERROR,ES_REMOTE_ENROLLEE_RES_TAG,
+ "Failed to create device using constructResourceObject");
+ return ES_ERROR;
+ }
+
+
+ ESResult foundResponse = ESDiscoveryTimeout (DISCOVERY_TIMEOUT);
+
+ if (!m_discoveryResponse)
+ {
+ OC_LOG(ERROR,ES_REMOTE_ENROLLEE_RES_TAG,
+ "Failed to create device using constructResourceObject");
+ return ES_ERROR;
+ }
+
+ return ES_OK;
+#endif
+ }
+
+ void RemoteEnrolleeResource::provisionEnrollee()
+
+ {
+ if (m_ocResource == nullptr)
+ {
+ throw ESBadRequestException("Resource is not initialized");
+ }
+
+ OC::QueryParamsMap query;
+ OC::OCRepresentation rep;
+
+ std::function< OCStackResult(void) > getProvisioingStatus = [&]
+ { return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
+ m_ocResource->getResourceInterfaces().at(0), query,
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&RemoteEnrolleeResource::getProvStatusResponse, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)));
+ };
+
+ OCStackResult result = getProvisioingStatus();
+
+ if (result != OCStackResult::OC_STACK_OK)
+ {
+ std::shared_ptr< ProvisioningStatus > provStatus = std::make_shared<
+ ProvisioningStatus >(ESResult::ES_ERROR, ESState::ES_PROVISIONING_ERROR);
+ m_provStatusCb(provStatus);
+ return;
+ }
+ }
+
+ void RemoteEnrolleeResource::unprovisionEnrollee()
+ {
+ if (m_ocResource == nullptr)
+ {
+ throw ESBadRequestException("Resource is not initialized");
+ }
+
+ OCRepresentation provisioningRepresentation;
+
+ provisioningRepresentation.setValue(OC_RSRVD_ES_TNN, "");
+ provisioningRepresentation.setValue(OC_RSRVD_ES_CD, "");
+
+ m_ocResource->post(provisioningRepresentation, QueryParamsMap(),
+ std::function<
+ void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+ const int eCode) >(
+ std::bind(&RemoteEnrolleeResource::checkProvInformationCb, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)));
+ }
+ }
+}