Add getStatus API in RemoteEnrollee to get provisioning resource properties
authorJihun Ha <jihun.ha@samsung.com>
Tue, 26 Jul 2016 04:12:27 +0000 (13:12 +0900)
committerMadan Lanka <lanka.madan@samsung.com>
Tue, 26 Jul 2016 06:49:09 +0000 (06:49 +0000)
We add a new API to retrieve properties of provisioning resource.
With the API, user can know a provisioning status and last error code from
Enrollee.
Additionally. correct variable name in jniGetConfigurationStatusLister.cpp

Change-Id: Ic7f62d13175700004bc71bf035dd3575297efcd0
Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9707
Reviewed-by: Jongho Park <jh8397.park@samsung.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Madan Lanka <lanka.madan@samsung.com>
service/easy-setup/inc/escommon.h
service/easy-setup/mediator/richsdk/android/jni/JniEsUtils.cpp
service/easy-setup/mediator/richsdk/android/jni/JniEsUtils.h
service/easy-setup/mediator/richsdk/android/jni/JniGetConfigurationStatusListener.cpp [changed mode: 0644->0755]
service/easy-setup/mediator/richsdk/inc/ESRichCommon.h
service/easy-setup/mediator/richsdk/inc/EnrolleeResource.h
service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h
service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp
service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp

index 35ff2e8..c88497d 100755 (executable)
@@ -98,7 +98,8 @@ typedef enum
 {
     WiFi_24G = 0,       /**< 2.4G **/
     WiFi_5G,            /**< 5G **/
-    WiFi_BOTH           /**< 2.4G and 5G **/
+    WiFi_BOTH,          /**< 2.4G and 5G **/
+    WiFi_FREQ_NONE      /**< EOF **/
 } WIFI_FREQ;
 
 /**
index 6664361..e45986e 100755 (executable)
@@ -111,21 +111,6 @@ int convertNativeWifiModeToInt(WIFI_MODE wifiMode)
     }
 }
 
-int convertNativeDeviceProvStateToInt(ESDeviceProvState nativeState)
-{
-    switch (nativeState)
-    {
-        case ESDeviceProvState::ES_PROVISIONING_ERROR:
-            return -1;
-        case ESDeviceProvState::ES_NEED_PROVISIONING:
-            return 0;
-        case ESDeviceProvState::ES_PROVISIONED_ALREADY:
-            return 1;
-        case ESDeviceProvState::ES_PROVISIONING_SUCCESS:
-            return 2;
-    }
-}
-
 int convertNativeDeviceProvResultToInt(ESResult nativeResult)
 {
     switch (nativeResult)
index f356aaa..e966fbd 100755 (executable)
@@ -51,6 +51,5 @@ WIFI_AUTHTYPE getWifiAuthTypeFromInt(int authType);
 WIFI_ENCTYPE getWifiEncTypeFromInt(int encType);
 int convertNativeWifiFreqToInt(WIFI_FREQ wifiFreq);
 int convertNativeWifiModeToInt(WIFI_MODE wifiMode);
-int convertNativeDeviceProvStateToInt(ESDeviceProvState nativeState);
 int convertNativeDeviceProvResultToInt(ESResult nativeResult);
 #endif //__JNI_ES_UTILS_H_
old mode 100644 (file)
new mode 100755 (executable)
index ce13435..5541393
@@ -95,18 +95,18 @@ void JniGetConfigurationStatusListener::getConfigurationStatusCallback (
     }
 
     jclass clazz = env->FindClass("java/util/ArrayList");
-    jobject wifiModeTypes = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
+    jobject wifiModes = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
     jmethodID arraylist_add = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z");
 
-    for (int n=0; n<wifiConf.types.size(); n++)
+    for (int n=0; n<wifiConf.modes.size(); n++)
     {
         jobject value = env->NewObject(g_cls_Integer,
-                                                            g_mid_Integer_ctor,
-                                                            convertNativeWifiModeToInt(static_cast<WIFI_MODE>(wifiConf.types[n])));
-       env->CallBooleanMethod(wifiModeTypes, arraylist_add, value);
+                                        g_mid_Integer_ctor,
+                                        convertNativeWifiModeToInt(static_cast<WIFI_MODE>(wifiConf.modes[n])));
+       env->CallBooleanMethod(wifiModes, arraylist_add, value);
     }
-    if (!wifiModeTypes) {
-        LOGE("JniGetConfigurationStatusListener::getConfigurationStatusCallback Unable to create the wifiModeTypes");
+    if (!wifiModes) {
+        LOGE("JniGetConfigurationStatusListener::getConfigurationStatusCallback Unable to create the wifiModes");
         return ;
     }
 
@@ -114,7 +114,7 @@ void JniGetConfigurationStatusListener::getConfigurationStatusCallback (
     jobject jWiFiConf = NULL;
     jWiFiConf = env->NewObject(g_cls_WiFiConfig,
                                                 g_mid_WiFiConfig_ctor,
-                                                (jobject)wifiModeTypes,
+                                                (jobject)wifiModes,
                                                 (jint)convertNativeWifiFreqToInt(wifiConf.freq));
     if (!jWiFiConf) {
         LOGE("JniGetConfigurationStatusListener::getConfigurationStatusCallback Unable to create the jWiFiConf");
index 8fabe50..4dbc66e 100755 (executable)
@@ -89,6 +89,84 @@ namespace OIC
         } ESResult;
 
         /**
+         * @brief Indicate enrollee and provisioning status. Provisioning status is shown in "provisioning
+         *        status" property in provisioning resource.
+         */
+        typedef enum
+        {
+            /**
+             * Default state of the device
+             */
+            ES_STATE_INIT = 0,
+
+            /**
+            * Status indicating being cnnecting to target network
+            */
+            ES_STATE_CONNECTING_TO_ENROLLER,
+
+            /**
+            * Status indicating successful conection to target network
+            */
+            ES_STATE_CONNECTED_TO_ENROLLER,
+
+            /**
+            * Status indicating failure connection to target network
+            */
+            ES_STATE_CONNECTED_FAIL_TO_ENROLLER,
+
+            /**
+            * Status indicating successful registration to cloud
+            */
+            ES_STATE_REGISTERED_TO_CLOUD,
+
+            /**
+            * Status indicating failure registeration to cloud
+            */
+            ES_STATE_REGISTRRED_FAIL_TO_CLOUD
+        } ProvStatus;
+
+        /**
+         * @brief Indicate last error code to describe a reason of error during easy setup.
+         */
+        typedef enum
+        {
+            /**
+             * Init Error Code
+             */
+            ES_ERRCODE_NO_ERROR = 0,
+
+            /**
+            * Error Code that given WiFi's SSID is not found
+            */
+            ES_ERRCODE_SSID_NOT_FOUND,
+
+            /**
+            * Error Code that given WiFi's Password is wrong
+            */
+            ES_ERRCODE_PW_WRONG,
+
+            /**
+            * Error Code that IP address is not allocated
+            */
+            ES_ERRCODE_IP_NOT_ALLOCATED,
+
+            /**
+            * Error Code that there is no Internet connection
+            */
+            ES_ERRCODE_NO_INTERNETCONNECTION,
+
+            /**
+            * Error Code that Timeout occured
+            */
+            ES_ERRCODE_TIMEOUT,
+
+            /**
+            * Error Code that Unknown error occured
+            */
+            ES_ERRCODE_UNKNOWN
+        } ESErrorCode;
+
+        /**
          * @brief  WIFI Authentication tlype of the Enroller
          */
         typedef enum
@@ -119,7 +197,8 @@ namespace OIC
         {
             WIFI_24G = 0,       /**< 2.4G **/
             WIFI_5G,            /**< 5G **/
-            WIFI_BOTH           /**< 2.4G and 5G **/
+            WIFI_BOTH,          /**< 2.4G and 5G **/
+            WIFI_FREQ_NONE      /**< EOF **/
         } WIFI_FREQ;
 
         /**
@@ -135,6 +214,16 @@ namespace OIC
         } WIFI_MODE;
 
         /**
+         * @brief Properties of provisioning resource. It includes a provisioning status and last
+         *        error code.
+         */
+        typedef struct
+        {
+            ProvStatus provStatus;
+            ESErrorCode lastErrCode;
+        } EnrolleeStatus;
+
+        /**
          * @brief Data structure stored for Cloud server property provisioning
          */
         typedef struct
@@ -191,17 +280,6 @@ namespace OIC
         } WiFiConfig;
 
         /**
-         * @brief Provisioning state in device property provisioning.
-         */
-        typedef enum
-        {
-            ES_PROVISIONING_ERROR = -1,
-            ES_NEED_PROVISIONING,
-            ES_PROVISIONED_ALREADY,
-            ES_PROVISIONING_SUCCESS
-        } ESDeviceProvState;
-
-        /**
          * @brief Provisioning state in cloud server property provisioning.
          */
         typedef enum
@@ -247,6 +325,11 @@ namespace OIC
         public:
             EnrolleeConf()
             {
+                m_devConfig.name = nullptr;
+                m_devConfig.language = nullptr;
+                m_devConfig.country = nullptr;
+                m_wifiConfig.freq = WIFI_FREQ_NONE;
+                m_cloudable = false;
             }
 
             EnrolleeConf(DeviceConfig devConfig, WiFiConfig wifiConfig, bool cloudable) :
@@ -276,9 +359,45 @@ namespace OIC
         };
 
         /**
+         * Status object for getStatus API. This object is given to application
+         * when a response for GET request to provisioning resource at Enrollee is arrived.
+         * It returns a result of the API and requested data delivered in the response which includes
+         * a provisioning status and last error code stored in Enrollee.
+         *
+         * @see EnrolleeStatus
+         */
+        class GetEnrolleeStatus
+        {
+        public:
+            GetEnrolleeStatus()
+            {
+            }
+
+            GetEnrolleeStatus(ESResult result, const EnrolleeStatus& status) :
+                m_result(result), m_enrolleeStatus(status)
+            {
+            }
+
+            ESResult getESResult()
+            {
+                return m_result;
+            }
+
+            const EnrolleeStatus& getEnrolleeStatus()
+            {
+                return m_enrolleeStatus;
+            }
+
+        private:
+            ESResult m_result;
+            EnrolleeStatus m_enrolleeStatus;
+        };
+
+        /**
          * Status object for getConfiguration API. This object is given to application
          * when a response for GET request to provisioning resource at Enrollee is arrived.
-         * It returns a result of the API and requested data delivered in the response
+         * It returns a result of the API and requested data delivered in the response which includes
+         * WiFi configuration and device configuration stored in Enrollee.
          *
          * @see EnrolleeConf
          */
@@ -359,22 +478,27 @@ namespace OIC
         };
 
         /**
-         * Callback function definition for providing Enrollee security status
+         * Callback function definition for providing Enrollee status
+         */
+        typedef function< void(shared_ptr< GetEnrolleeStatus >) > GetStatusCb;
+
+        /**
+         * Callback function definition for providing Enrollee configuration status
          */
         typedef function< void(shared_ptr< GetConfigurationStatus >) > GetConfigurationStatusCb;
 
         /**
-         * Callback function definition for providing Enrollee security status
+         * Callback function definition for providing Enrollee device property provisioning status
          */
         typedef function< void(shared_ptr< DevicePropProvisioningStatus >) > DevicePropProvStatusCb;
 
         /**
-         * Callback function definition for providing Enrollee security status
+         * Callback function definition for providing Enrollee cloud property provisioning status
          */
         typedef function< void(shared_ptr< CloudPropProvisioningStatus >) > CloudPropProvStatusCb;
 
         /**
-         * Callback function definition for providing Enrollee security status
+         * Callback function definition for providing Enrollee security provisioning status
          */
         typedef function< void(shared_ptr<SecProvisioningStatus>) > SecurityProvStatusCb;
 
index 4d2ac10..a2bf981 100755 (executable)
@@ -51,25 +51,31 @@ namespace OIC
 
             ~EnrolleeResource() = default;
 
+            void registerGetStatusCallback (GetStatusCb callback);
             void registerGetConfigurationStatusCallback (GetConfigurationStatusCb callback);
             void registerDevicePropProvStatusCallback (DevicePropProvStatusCb callback);
 
             void getConfiguration();
+            void getStatus();
 
             void provisionEnrollee(const DeviceProp& deviceProp);
 
         private:
             std::shared_ptr< OC::OCResource > m_ocResource;
 
+            GetStatusCb m_getStatusCb;
             GetConfigurationStatusCb m_getConfigurationStatusCb;
             DevicePropProvStatusCb m_devicePropProvStatusCb;
 
         private:
+            void onGetStatusResponse(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                    const int eCode);
             void onGetConfigurationResponse(const HeaderOptions& headerOptions, const OCRepresentation& rep,
                     const int eCode);
             void checkProvInformationCb(const HeaderOptions& headerOptions, const OCRepresentation& rep,
                     const int eCode);
             EnrolleeConf parseEnrolleeConfFromRepresentation(const OCRepresentation& rep);
+            EnrolleeStatus parseEnrolleeStatusFromRepresentation(const OCRepresentation& rep);
         };
     }
 }
index 85f5d38..a4274e6 100755 (executable)
@@ -68,6 +68,17 @@ namespace OIC
 #endif //__WITH_DTLS__
 
             /**
+             * Get an Enrollee's status which includes provisioning status and last error code
+             *
+             * @param callback will give the requested status
+             *
+             * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
+             *
+             * @see GetStatusCb
+             */
+            void getStatus(GetStatusCb callback);
+
+            /**
              * Get an Enrollee's configuration which includes WiFi supported frequency and device name
              *
              * @param callback will give the requested configuration
@@ -130,6 +141,7 @@ namespace OIC
             void onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource);
             void initCloudResource();
 
+            void getStatusHandler (std::shared_ptr< GetEnrolleeStatus > status);
             void getConfigurationStatusHandler (std::shared_ptr< GetConfigurationStatus > status);
             void devicePropProvisioningStatusHandler (std::shared_ptr< DevicePropProvisioningStatus > status);
             void cloudPropProvisioningStatusHandler (std::shared_ptr< CloudPropProvisioningStatus > status);
@@ -145,6 +157,7 @@ namespace OIC
             bool m_discoveryResponse;
 
             SecurityProvStatusCb m_securityProvStatusCb;
+            GetStatusCb m_getStatusCb;
             GetConfigurationStatusCb m_getConfigurationStatusCb;
             SecurityPinCb m_securityPinCb;
             SecProvisioningDbPathCb m_secProvisioningDbPathCb;
index beae978..5aa7fca 100755 (executable)
@@ -63,6 +63,42 @@ namespace OIC
             m_devicePropProvStatusCb(provStatus);
         }
 
+        void EnrolleeResource::onGetStatusResponse(const HeaderOptions& /*headerOptions*/,
+                const OCRepresentation& rep, const int eCode)
+        {
+            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onGetStatusResponse : %s, eCode = %d",
+                    rep.getUri().c_str(), eCode);
+
+            if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED)
+            {
+                ESResult result = ESResult::ES_ERROR;
+
+                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                            "onGetStatusResponse : onGetStatusResponse is failed ");
+
+                if (eCode == OCStackResult::OC_STACK_UNAUTHORIZED_REQ)
+                {
+                    OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                        "Mediator is unauthorized from Enrollee.");
+                    result = ESResult::ES_UNAUTHORIZED;
+                }
+
+                EnrolleeStatus enrolleeStatus = {ES_STATE_INIT, ES_ERRCODE_NO_ERROR};
+                std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus = std::make_shared<
+                        GetEnrolleeStatus >(ESResult::ES_ERROR, enrolleeStatus);
+
+                m_getStatusCb(getEnrolleeStatus);
+            }
+            else
+            {
+                EnrolleeStatus enrolleeStatus = parseEnrolleeStatusFromRepresentation(rep);
+                std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus = std::make_shared<
+                        GetEnrolleeStatus >(ESResult::ES_OK, enrolleeStatus);
+
+                m_getStatusCb(getEnrolleeStatus);
+            }
+        }
+
         void EnrolleeResource::onGetConfigurationResponse(const HeaderOptions& /*headerOptions*/,
                 const OCRepresentation& rep, const int eCode)
         {
@@ -73,7 +109,8 @@ namespace OIC
             {
                 ESResult result  = ESResult::ES_ERROR;
 
-                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,"onGetConfigurationResponse : onGetConfigurationResponse is failed ");
+                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                            "onGetConfigurationResponse : onGetConfigurationResponse is failed ");
 
                 if (eCode == OCStackResult::OC_STACK_UNAUTHORIZED_REQ)
                 {
@@ -97,6 +134,11 @@ namespace OIC
             }
         }
 
+        void EnrolleeResource::registerGetStatusCallback(GetStatusCb callback)
+        {
+            m_getStatusCb = callback;
+        }
+
         void EnrolleeResource::registerGetConfigurationStatusCallback(GetConfigurationStatusCb callback)
         {
             m_getConfigurationStatusCb = callback;
@@ -107,6 +149,39 @@ namespace OIC
             m_devicePropProvStatusCb = callback;
         }
 
+        void EnrolleeResource::getStatus()
+        {
+            if (m_ocResource == nullptr)
+            {
+                throw ESBadRequestException("Resource is not initialized");
+            }
+
+            OC::QueryParamsMap query;
+            OC::OCRepresentation rep;
+
+            std::function< OCStackResult(void) > getStatus = [&]
+            {   return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
+                        DEFAULT_INTERFACE, query, std::function<void(const HeaderOptions& headerOptions,
+                        const OCRepresentation& rep, const int eCode) >(
+                                std::bind(&EnrolleeResource::onGetStatusResponse, this,
+                                        std::placeholders::_1, std::placeholders::_2,
+                                        std::placeholders::_3)));
+            };
+
+            OCStackResult result = getStatus();
+
+            if (result != OCStackResult::OC_STACK_OK)
+            {
+                EnrolleeStatus enrolleeStatus = {ES_STATE_INIT, ES_ERRCODE_NO_ERROR};
+                std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus = std::make_shared<
+                        GetEnrolleeStatus >(ESResult::ES_ERROR, enrolleeStatus);
+
+                m_getStatusCb(getEnrolleeStatus);
+
+                return;
+            }
+        }
+
         void EnrolleeResource::getConfiguration()
         {
             if (m_ocResource == nullptr)
@@ -248,5 +323,25 @@ namespace OIC
             return EnrolleeConf(devConf, wifiConf, cloudable);
         }
 
+        EnrolleeStatus EnrolleeResource::parseEnrolleeStatusFromRepresentation(const OCRepresentation& rep)
+        {
+            OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_RES_TAG, "Enter parseEnrolleeStatusFromRepresentation");
+
+            EnrolleeStatus enrolleeStatus;
+
+            if(rep.hasAttribute(OC_RSRVD_ES_PROVSTATUS))
+            {
+                enrolleeStatus.provStatus = static_cast<ProvStatus>(
+                                                        rep.getValue<int>(OC_RSRVD_ES_PROVSTATUS));
+            }
+
+            if(rep.hasAttribute(OC_RSRVD_ES_LAST_ERRORCODE))
+            {
+                enrolleeStatus.lastErrCode = static_cast<ESErrorCode>(
+                                                        rep.getValue<int>(OC_RSRVD_ES_LAST_ERRORCODE));
+            }
+
+            return enrolleeStatus;
+        }
     }
 }
index 24c9705..89e0964 100755 (executable)
@@ -90,6 +90,15 @@ namespace OIC
             }
         }
 
+        void RemoteEnrollee::getStatusHandler(std::shared_ptr< GetEnrolleeStatus > status)
+        {
+            OIC_LOG(DEBUG,ES_REMOTE_ENROLLEE_TAG,"Entering getStatusHandler");
+
+            OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"getStatusHandler = %d", status->getESResult());
+
+            m_getStatusCb(status);
+        }
+
         void RemoteEnrollee::getConfigurationStatusHandler (
                 std::shared_ptr< GetConfigurationStatus > status)
         {
@@ -288,20 +297,41 @@ namespace OIC
 #endif
         }
 
-        void RemoteEnrollee::getConfiguration(GetConfigurationStatusCb callback)
+        void RemoteEnrollee::getStatus(GetStatusCb callback)
         {
             if(!callback)
             {
                 throw ESInvalidParameterException("Callback is empty");
             }
 
-            m_getConfigurationStatusCb = callback;
+            if (m_enrolleeResource == nullptr)
+            {
+                throw ESBadRequestException ("Device not created");
+            }
+
+            m_getStatusCb = callback;
+
+            GetStatusCb getStatusCb = std::bind(
+                &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
+            m_enrolleeResource->registerGetStatusCallback(getStatusCb);
+            m_enrolleeResource->getStatus();
+
+        }
+
+        void RemoteEnrollee::getConfiguration(GetConfigurationStatusCb callback)
+        {
+            if(!callback)
+            {
+                throw ESInvalidParameterException("Callback is empty");
+            }
 
             if (m_enrolleeResource == nullptr)
             {
                 throw ESBadRequestException ("Device not created");
             }
 
+            m_getConfigurationStatusCb = callback;
+
             GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
                     &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
             m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
index 135715e..c314d6c 100755 (executable)
@@ -84,12 +84,51 @@ void printConfiguration(EnrolleeConf conf)
     cout << "===========================================" << endl;
 }
 
+void printStatus(EnrolleeStatus status)
+{
+    cout << "===========================================" << endl;
+    cout << "\tEnrolleeStatus.provStatus : " << status.provStatus << endl;
+    cout << "\tEnrolleeStatus.lastErrCode : " << status.lastErrCode << endl;
+    cout << "===========================================" << endl;
+}
+
 void provisionSecurity()
 {
     // TODO
 }
 
-void GetConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
+void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
+{
+    if(getEnrolleeStatus->getESResult() != ES_OK)
+    {
+      cout << "getStatus is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "getStatus is success." << endl;
+      printStatus(getEnrolleeStatus->getEnrolleeStatus());
+    }
+}
+
+
+void getStatus()
+{
+    if(!remoteEnrollee)
+        return;
+
+    try
+    {
+        remoteEnrollee->getStatus(getStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during getConfiguration call" << e.reason();
+        return;
+    }
+}
+
+void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
 {
     if(getConfigurationStatus->getESResult() != ES_OK)
     {
@@ -110,7 +149,7 @@ void getConfiguration()
 
     try
     {
-        remoteEnrollee->getConfiguration(GetConfigurationCallback);
+        remoteEnrollee->getConfiguration(getConfigurationCallback);
     }
     catch (OCException &e)
     {
@@ -199,12 +238,14 @@ void provisionCloudProperty()
 void DisplayMenu()
 {
     constexpr int PROVISION_SECURITY = 1;
-    constexpr int GET_CONFIGURATION = 2;
-    constexpr int PROVISION_DEVICE_PROPERTY = 3;
-    constexpr int PROVISION_CLOUD_PROPERTY = 4;
+    constexpr int GET_STATUS = 2;
+    constexpr int GET_CONFIGURATION = 3;
+    constexpr int PROVISION_DEVICE_PROPERTY = 4;
+    constexpr int PROVISION_CLOUD_PROPERTY = 5;
 
     std::cout << "========================================================\n";
     std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee  \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 << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property  \n";
@@ -217,6 +258,9 @@ void DisplayMenu()
         case PROVISION_SECURITY:
             provisionSecurity();
             break;
+        case GET_STATUS:
+            getStatus();
+            break;
         case GET_CONFIGURATION:
             getConfiguration();
             break;