From d95f98bbb0956d5fe41ad10ebd6d6269ad53d366 Mon Sep 17 00:00:00 2001 From: Abhishek Pandey Date: Sat, 9 Sep 2017 18:59:12 +0530 Subject: [PATCH] ES Mediator update to align with OCF 1.3 Spec - Updated mediator logic based on version checking API from OCResource class. - Get Configuration Response parsing updated as per spec version. - provisionProperties updated as per spec version Change-Id: Iad208bbeb08e3dbdb749bf6d280c5e60231164a2 Signed-off-by: Abhishek Pandey --- service/easy-setup/inc/escommon.h | 2 + .../easy-setup/mediator/richsdk/inc/ESRichCommon.h | 263 ++++++++++++++++++++- .../mediator/richsdk/src/EnrolleeResource.cpp | 59 ++++- .../mediator/richsdk/src/EnrolleeResource.h | 3 + 4 files changed, 311 insertions(+), 16 deletions(-) diff --git a/service/easy-setup/inc/escommon.h b/service/easy-setup/inc/escommon.h index bc3a889..ac92f47 100644 --- a/service/easy-setup/inc/escommon.h +++ b/service/easy-setup/inc/escommon.h @@ -48,6 +48,8 @@ extern "C" #define OC_RSRVD_ES_LINKS "links" #define OC_RSRVD_ES_SUPPORTEDWIFIMODE "swmt" #define OC_RSRVD_ES_SUPPORTEDWIFIFREQ "swf" +#define OC_RSRVD_ES_SUPPORTEDWIFIAUTHTYPE "swat" +#define OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE "swet" #define OC_RSRVD_ES_SSID "tnn" #define OC_RSRVD_ES_CRED "cd" #define OC_RSRVD_ES_AUTHTYPE "wat" diff --git a/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h b/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h index 41715d7..f9a313d 100644 --- a/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h +++ b/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h @@ -39,9 +39,13 @@ #include "escommon.h" +#include "logger.h" + using namespace OC; using namespace std; +#define ES_RICH_COMMON_TAG "ES_MEDIATOR_COMMON" + #ifndef WITH_ARDUINO namespace OIC { @@ -355,8 +359,8 @@ namespace OIC /** * Set WiFiConf resource properties to be delivered to Enrollee * - * @param ssid Ssid of the Enroller - * @param pwd Pwd of the Enrolle + * @param ssid SSID of the Enroller + * @param pwd Password of the Enroller * @param authtype Auth type of the Enroller * @param enctype Encryption type of the Enroller * @@ -408,6 +412,7 @@ namespace OIC */ WIFI_AUTHTYPE getAuthType() const { + ///TODO: Recheck logic if this API is used. if(m_rep.hasAttribute(OC_RSRVD_ES_AUTHTYPE)) { return static_cast(m_rep.getValue(OC_RSRVD_ES_AUTHTYPE)); @@ -424,6 +429,7 @@ namespace OIC */ WIFI_ENCTYPE getEncType() const { + ///TODO: Recheck logic if this API is used. if(m_rep.hasAttribute(OC_RSRVD_ES_ENCTYPE)) { return static_cast(m_rep.getValue(OC_RSRVD_ES_ENCTYPE)); @@ -441,8 +447,72 @@ namespace OIC return m_rep; } + /** + * Get OCRepresentation object + * + * Resource Schema for WiFiConf resource is different in older Enrollee following + * OIC Spec compared to newer Enrollee following OCF Spec. This function updates + * the representation as per spec version. + * + * Update representation as per OCF Specification. + */ + void updateOCRepresentation(int specVersion) + { + if(0 == specVersion) // OIC Server does not contain CONTENT FORMAT VERSION + { + // Representation is already stored as per older resource schemas. + return; + } + + // Representation should be updated as per OCF 1.3 Easy Setup resource schemas. + WIFI_AUTHTYPE authtype = static_cast (m_rep.getValue(OC_RSRVD_ES_AUTHTYPE)); + WIFI_ENCTYPE enctype = static_cast (m_rep.getValue(OC_RSRVD_ES_ENCTYPE)); + + m_rep.setValue(OC_RSRVD_ES_AUTHTYPE, getAuthTypeAsString(authtype)); + m_rep.setValue(OC_RSRVD_ES_ENCTYPE, getEncTypeAsString(enctype)); + } + protected: OCRepresentation m_rep; + + private: + std::string getAuthTypeAsString(WIFI_AUTHTYPE authType) const + { + switch(authType) + { + case NONE_AUTH: + return "None"; + case WEP: + return "WEP"; + case WPA_PSK: + return "WPA_PSK"; + case WPA2_PSK: + return "WPA2_PSK"; + default: + return "None"; + } + } + + std::string getEncTypeAsString(WIFI_ENCTYPE encType) const + { + switch(encType) + { + case NONE_ENC: + return "None"; + case WEP_64: + return "WEP_64"; + case WEP_128: + return "WEP_128"; + case TKIP: + return "TKIP"; + case AES: + return "AES"; + case TKIP_AES: + return "TKIP_AES"; + default: + return "None"; + } + } }; /** @@ -557,18 +627,25 @@ namespace OIC * OCRepresentation object corresponding to WiFiConf, DevConf, and CoapCloudConf * resources' representations. */ + EnrolleeConf(const OCRepresentation& rep) : - m_EasySetupRep(rep) + m_EasySetupRep(rep), m_OCFServerVersion(0) + { + } + + EnrolleeConf(const OCRepresentation& rep, const int OCFServerVersion) : + m_EasySetupRep(rep), m_OCFServerVersion(OCFServerVersion) { } EnrolleeConf(const EnrolleeConf& enrolleeConf) : - m_EasySetupRep(enrolleeConf.getEasySetupRep()) + m_EasySetupRep(enrolleeConf.getEasySetupRep()), m_OCFServerVersion(enrolleeConf.getOCFSpecVersion()) { } EnrolleeConf(const EnrolleeConf&& enrolleeConf) : - m_EasySetupRep(std::move(enrolleeConf.getEasySetupRep())) + m_EasySetupRep(std::move(enrolleeConf.getEasySetupRep())), + m_OCFServerVersion(std::move(enrolleeConf.getOCFSpecVersion())) { } @@ -633,10 +710,27 @@ namespace OIC if(rep.hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIMODE)) { - for(auto it : rep.getValue + if(0 == m_OCFServerVersion) + { + OIC_LOG(DEBUG, ES_RICH_COMMON_TAG, "getWiFiModes() with OIC Spec"); + + /* Considering Representation as per OIC Core Spec */ + for(auto it : rep.getValue >(OC_RSRVD_ES_SUPPORTEDWIFIMODE)) + { + modes.push_back(static_cast(it)); + } + } + else // m_OCFServerVersion > 0 for OCF Spec (2048 for OCF 1.0 Spec) { - modes.push_back(static_cast(it)); + OIC_LOG(DEBUG, ES_RICH_COMMON_TAG, "getWiFiModes() with OCF Spec"); + + /* Considering Representation as per OCF 1.0 / 1.x Core Spec */ + for(auto it : rep.getValue + >(OC_RSRVD_ES_SUPPORTEDWIFIMODE)) + { + modes.push_back(getWiFiModeAsEnum(it)); + } } } } @@ -670,8 +764,22 @@ namespace OIC if(rep.hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIFREQ)) { - return static_cast( - rep.getValue(OC_RSRVD_ES_SUPPORTEDWIFIFREQ)); + if(0 == m_OCFServerVersion) + { + OIC_LOG(DEBUG, ES_RICH_COMMON_TAG, "getWiFiFreq() with OIC Spec"); + + /* Considering Representation as per OIC Core Spec */ + return static_cast( + rep.getValue(OC_RSRVD_ES_SUPPORTEDWIFIFREQ)); + } + else // m_OCFServerVersion > 0 for OCF Spec (2048 for OCF 1.0 Spec) + { + OIC_LOG(DEBUG, ES_RICH_COMMON_TAG, "getWiFiFreq() with OCF Spec"); + + /* Considering Representation as per OCF 1.0 / 1.x Core Spec */ + return getWiFiFreqAsEnum(rep.getValue + >(OC_RSRVD_ES_SUPPORTEDWIFIFREQ)); + } } } } @@ -679,6 +787,76 @@ namespace OIC } /** + * Get supported WiFi authentication types by the Enrollee. + * + * @return a set of supported WiFi authentication types of Enrollee. + * + * @see WIFI_FREQ + */ + vector getSupportedWiFiAuthTypes() const + { + vector swatVector; + + std::vector children = m_EasySetupRep.getChildren(); + for(auto child = children.begin(); child != children.end(); ++child) + { + if(child->getUri().find(OC_RSRVD_ES_URI_WIFICONF) != std::string::npos) + { + OCRepresentation rep; + if(child->hasAttribute(OC_RSRVD_REPRESENTATION)) + { + rep = child->getValue(OC_RSRVD_REPRESENTATION); + } + else + { + break; + } + + if(rep.hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIAUTHTYPE)) + { + /* This property is include only from OCF 1.3 Spec Onwards */ + swatVector = rep.getValue>(OC_RSRVD_ES_SUPPORTEDWIFIAUTHTYPE); + break; + } + } + } + return swatVector; + } + + /** + * Get supported WiFi encryption types by the Enrollee. + * + * @return a set of supported WiFi encryption types of Enrollee. + * + * @see WIFI_MODE + */ + vector getSupportedWiFiEncTypes() const + { + vector swetVector; + + std::vector children = m_EasySetupRep.getChildren(); + for(auto child = children.begin(); child != children.end(); ++child) + { + if(child->getUri().find(OC_RSRVD_ES_URI_WIFICONF) != std::string::npos) + { + OCRepresentation rep; + if(child->hasAttribute(OC_RSRVD_REPRESENTATION)) + { + rep = child->getValue(OC_RSRVD_REPRESENTATION); + } + + if(rep.hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE)) + { + /* This property is include only from OCF 1.3 Spec Onwards */ + swetVector = rep.getValue>(OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE); + break; + } + } + } + return swetVector; + } + + /** * Get a provisioning status property of Enrollee. * * @return a provisioning status property of Enrollee @@ -772,8 +950,75 @@ namespace OIC return m_EasySetupRep; } + /** + * Get OCF Specification Version + * + * @return version value + */ + int getOCFSpecVersion() const + { + return m_OCFServerVersion; + } + protected: OCRepresentation m_EasySetupRep; + int m_OCFServerVersion; + + private: + + WIFI_MODE getWiFiModeAsEnum(std::string wifiMode) const + { + if(0 == wifiMode.compare("A")) + { + return WIFI_11A; + } + else if(0 == wifiMode.compare("B")) + { + return WIFI_11B; + } + else if(0 == wifiMode.compare("G")) + { + return WIFI_11G; + } + else if(0 == wifiMode.compare("N")) + { + return WIFI_11N; + } + else if(0 == wifiMode.compare("AC")) + { + return WIFI_11AC; + } + return WiFi_EOF; + } + + WIFI_FREQ getWiFiFreqAsEnum(std::vector wifiFreqList) const + { + bool b_2_4G = false; + bool b_5G = false; + + for (std::string& freq : wifiFreqList) + { + if(0 == freq.compare("2.4G")) + { + b_2_4G = true; + } + else if(0 == freq.compare("5G")) + { + b_5G = true; + } + } + + if(b_2_4G && b_5G) + return WIFI_BOTH; + + if(b_2_4G) + return WIFI_24G; + + if(b_5G) + return WIFI_5G; + + return WIFI_FREQ_NONE; + } }; /** diff --git a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp index a1e35e9..674afcf 100644 --- a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp +++ b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp @@ -32,6 +32,8 @@ namespace OIC namespace Service { #define ES_REMOTE_ENROLLEE_RES_TAG "ES_ENROLLEE_RESOURCE" + #define OCF_CONTENT_FORMAT_VERSION_OPTION_ID 2053 + #define OCF_CONTENT_FORMAT_VERSION_VALUE 2048 EnrolleeResource::EnrolleeResource(std::shared_ptr< OC::OCResource > resource) { @@ -83,7 +85,7 @@ namespace OIC } OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, - "onProvisioningResponse : Provisioning is success. "); + "onProvisioningResponse : Provisioning is success."); std::shared_ptr< DevicePropProvisioningStatus > provStatus = std::make_shared< DevicePropProvisioningStatus >(ESResult::ES_OK); @@ -132,6 +134,8 @@ namespace OIC OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onGetConfigurationResponse : eCode = %d", eCode); + int version = GetOCFServerVersion(); + if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED) { ESResult result = ESResult::ES_ERROR; @@ -146,14 +150,14 @@ namespace OIC result = ESResult::ES_COMMUNICATION_ERROR; } - EnrolleeConf enrolleeConf(rep); + EnrolleeConf enrolleeConf(rep, version); std::shared_ptr< GetConfigurationStatus > getConfigurationStatus = std::make_shared< GetConfigurationStatus >(result, enrolleeConf); m_getConfigurationStatusCb(getConfigurationStatus); } else { - EnrolleeConf enrolleeConf(rep); + EnrolleeConf enrolleeConf(rep, version); std::shared_ptr< GetConfigurationStatus > getConfigurationStatus = std::make_shared< GetConfigurationStatus >(ESResult::ES_OK, enrolleeConf); @@ -195,6 +199,45 @@ namespace OIC m_connectRequestStatusCb(connectRequestStatus); } + int EnrolleeResource::GetOCFServerVersion() + { + OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "GetOCFServerVersion IN"); + + HeaderOptions headerOptions = m_ocResource->getServerHeaderOptions(); + if (headerOptions.size() == 0) + { + OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "No header option exists"); + } + else + { + for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it) + { + if (it->getOptionID() == OCF_CONTENT_FORMAT_VERSION_OPTION_ID) // OPTION_CONTENT_VERSION + { + size_t dataLength = it->getOptionData().length(); + if (dataLength == 0) + { + OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "GetOCFServerVersion: version not found!"); + return 0; + } + + int version = (it->getOptionData().c_str()[0]) * 256; + OIC_LOG_V (INFO, ES_REMOTE_ENROLLEE_RES_TAG, "GetOCFServerVersion: Version [%d]", version); + + if(OCF_CONTENT_FORMAT_VERSION_VALUE == version) + { + OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, + "GetOCFServerVersion: Version matches OCF 1.0"); + } + + return version; + } + } + } + + OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "GetOCFServerVersion OUT version option not found"); + return 0; + } void EnrolleeResource::registerGetStatusCallback( const GetStatusCb callback) @@ -270,7 +313,6 @@ namespace OIC } OC::QueryParamsMap query; - OC::OCRepresentation rep; std::function< OCStackResult(void) > getConfigurationStatus = [&] { @@ -289,6 +331,7 @@ namespace OIC if (result != OCStackResult::OC_STACK_OK) { + OC::OCRepresentation rep; EnrolleeConf enrolleeConf(rep); std::shared_ptr< GetConfigurationStatus > getConfigurationStatus = std::make_shared< GetConfigurationStatus >(ESResult::ES_ERROR, enrolleeConf); @@ -307,8 +350,11 @@ namespace OIC throw ESBadRequestException("Resource is not initialized"); } - OC::QueryParamsMap query; - OC::OCRepresentation provisioningRepresentation = deviceProp.toOCRepresentation(); + int version = GetOCFServerVersion(); + + DeviceProp devicePropCopy(deviceProp); + devicePropCopy.updateOCRepresentation(version); + OC::OCRepresentation provisioningRepresentation = devicePropCopy.toOCRepresentation(); ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, @@ -331,7 +377,6 @@ namespace OIC throw ESBadRequestException("Resource is not initialized"); } - OC::QueryParamsMap query; OC::OCRepresentation requestRepresentation; std::vector connectTypes_int; connectTypes_int.clear(); diff --git a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h index f345a91..3230729 100644 --- a/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h +++ b/service/easy-setup/mediator/richsdk/src/EnrolleeResource.h @@ -95,6 +95,9 @@ namespace OIC void onConnectRequestResponse(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); + + // Determine Specification Version Enrollee follows using header options from discovered resource + int GetOCFServerVersion(); }; } } -- 2.7.4