ES Mediator update to align with OCF 1.3 Spec
authorAbhishek Pandey <abhi.siso@samsung.com>
Sat, 9 Sep 2017 13:29:12 +0000 (18:59 +0530)
committerAbhishek Pandey <abhi.siso@samsung.com>
Mon, 11 Sep 2017 06:19:16 +0000 (11:49 +0530)
- 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 <abhi.siso@samsung.com>
service/easy-setup/inc/escommon.h
service/easy-setup/mediator/richsdk/inc/ESRichCommon.h
service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp
service/easy-setup/mediator/richsdk/src/EnrolleeResource.h

index bc3a889..ac92f47 100644 (file)
@@ -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"
index 41715d7..f9a313d 100644 (file)
 
 #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<WIFI_AUTHTYPE>(m_rep.getValue<int>(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<WIFI_ENCTYPE>(m_rep.getValue<int>(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<WIFI_AUTHTYPE> (m_rep.getValue<int>(OC_RSRVD_ES_AUTHTYPE));
+                WIFI_ENCTYPE enctype = static_cast<WIFI_ENCTYPE> (m_rep.getValue<int>(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
                                         <std::vector<int>>(OC_RSRVD_ES_SUPPORTEDWIFIMODE))
+                                {
+                                    modes.push_back(static_cast<WIFI_MODE>(it));
+                                }
+                            }
+                            else // m_OCFServerVersion > 0 for OCF Spec (2048 for OCF 1.0 Spec)
                             {
-                                modes.push_back(static_cast<WIFI_MODE>(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
+                                        <std::vector<std::string>>(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<WIFI_FREQ>(
-                                        rep.getValue<int>(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<WIFI_FREQ>(
+                                            rep.getValue<int>(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
+                                        <std::vector<std::string>>(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<std::string> getSupportedWiFiAuthTypes() const
+            {
+                vector<std::string> swatVector;
+
+                std::vector<OCRepresentation> 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<OCRepresentation>(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<std::vector<std::string>>(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<std::string> getSupportedWiFiEncTypes() const
+            {
+                vector<std::string> swetVector;
+
+                std::vector<OCRepresentation> 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<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+
+                        if(rep.hasAttribute(OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE))
+                        {
+                            /* This property is include only from OCF 1.3 Spec Onwards */
+                            swetVector = rep.getValue<std::vector<std::string>>(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<std::string> 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;
+            }
         };
 
         /**
index a1e35e9..674afcf 100644 (file)
@@ -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<int> connectTypes_int;
             connectTypes_int.clear();
index f345a91..3230729 100644 (file)
@@ -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();
         };
     }
 }