Add st_things framework for SmartThings Things SDK.
authorHeejin Kim <hj_elena.kim@samsung.com>
Fri, 22 Sep 2017 14:23:23 +0000 (23:23 +0900)
committerHeejin Kim <hj_elena.kim@samsung.com>
Sat, 23 Sep 2017 13:56:47 +0000 (22:56 +0900)
This is a framework soruce code for SmartThings Things SDK.

Framework function
1. Easysetup manager for communication between controller - controlee
2. Data manager for defining and processing resources
3. Security manager related security module and certificate

You can test using st_things sample in /apps/examples/st_things

83 files changed:
framework/Makefile
framework/include/st_things/st_things.h
framework/include/st_things/st_things_types.h
framework/src/st_things/Kconfig [new file with mode: 0644]
framework/src/st_things/Make.defs [new file with mode: 0644]
framework/src/st_things/st_things.c [new file with mode: 0644]
framework/src/st_things/st_things_logger.c [new file with mode: 0644]
framework/src/st_things/st_things_logger.h [new file with mode: 0644]
framework/src/st_things/st_things_representation.c [new file with mode: 0644]
framework/src/st_things/st_things_representation.h [new file with mode: 0644]
framework/src/st_things/st_things_request_handler.c [new file with mode: 0644]
framework/src/st_things/st_things_request_handler.h [new file with mode: 0644]
framework/src/st_things/st_things_request_handler_collection.c [new file with mode: 0644]
framework/src/st_things/st_things_request_handler_collection.h [new file with mode: 0644]
framework/src/st_things/st_things_util.c [new file with mode: 0644]
framework/src/st_things/st_things_util.h [new file with mode: 0644]
framework/src/st_things/things_stack/.gitignore [new file with mode: 0644]
framework/src/st_things/things_stack/.sconsign.dblite [new file with mode: 0644]
framework/src/st_things/things_stack/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/inc/iotivity_config.h [new file with mode: 0644]
framework/src/st_things/things_stack/inc/things_api.h [new file with mode: 0644]
framework/src/st_things/things_stack/inc/things_resource.h [new file with mode: 0644]
framework/src/st_things/things_stack/inc/things_types.h [new file with mode: 0644]
framework/src/st_things/things_stack/port_tinyara.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/cloud_connector.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/cloud_evtpend.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/cloud_manager.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/inc/cloud_connector.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/inc/cloud_evtpend.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/cloud/inc/cloud_manager.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/easysetup.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/easysetup_manager.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/inc/easysetup.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/inc/easysetup_manager.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/inc/es_common.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/inc/resource_handler.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/easy-setup/resource_handler.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/inc/things_common.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/inc/things_data_manager.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/inc/things_req_handler.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/inc/things_security_manager.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/inc/things_server_builder.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/things_data_manager.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/things_req_handler.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/things_resource.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/things_security_manager.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/framework/things_server_builder.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/inc/things_def.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/logging/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/logging/inc/things_logger.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/logging/things_logger.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/memory/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/memory/inc/things_malloc.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/memory/things_malloc.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/security/ssCrypto/include/ss_sha2.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/security/ssCrypto/src/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/security/ssCrypto/src/ss_sha2.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_hashmap.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_list.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_network.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_node.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_ping.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_queue.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_rtos_util.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_string_util.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_thread.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/inc/things_wait_handler.h [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_hashmap.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_list.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_network.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_ping.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_queue.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_rtos_util.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_string_util.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_thread.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/common/utils/things_wait_handler.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/stack/Make.defs [new file with mode: 0644]
framework/src/st_things/things_stack/src/stack/things_rtos_apis.c [new file with mode: 0644]
framework/src/st_things/things_stack/src/stack/things_stack.c [new file with mode: 0644]

index b344b70..3d8c0c3 100644 (file)
@@ -46,6 +46,10 @@ ifeq ($(CONFIG_WIFI_MANAGER), y)
 include src$(DELIM)wifi_manager$(DELIM)Make.defs
 endif
 
+ifeq ($(CONFIG_ST_THINGS), y)
+include src$(DELIM)st_things$(DELIM)Make.defs
+endif
+
 ifeq ($(CONFIG_AUDIO), y)
 include src$(DELIM)tinyalsa$(DELIM)Make.defs
 endif
index dab3cf5..891a05d 100644 (file)
 #include <stdint.h>
 #include <stdbool.h>
 
+#ifdef __ST_THINGS_RTOS__
+#include <st_things/st_things_types.h>
+#else
 #include "st_things_types.h"
+#endif                                                 // __ST_THINGS_RTOS__
 
 #ifdef __cplusplus
 extern "C" {
@@ -49,6 +53,8 @@ extern "C" {
  *            If easy-setup is not done, app can either wait for the user interaction before starting the things stack or
  *            start the things stack directly without waiting for any events(This case is for those things which doesn't
  *            support input capability and for all other unknown cases).
+ *            To use a new json file after initialization, stack should be deinitialized
+ *            and stopped(if its started already).
  * @param[in] json_path Path to Json file which defines a thing. Definition includes the device information,
  *                                       resources and their properties, configuration info for connectivity and easy-setup, etc.
  * @param[out] easysetup_complete Indicates whether easysetup is completed already or not.
@@ -56,15 +62,25 @@ extern "C" {
  * @retval #ST_THINGS_ERROR_NONE Successful
  * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
+ * @retval #ST_THINGS_ERROR_STACK_ALREADY_INITIALIZED Stack already initialized.
+ *         To initialize again, stack should be deinitilized first by calling st_things_deinitialize().
+ * @retval #ST_THINGS_ERROR_STACK_RUNNING Stack is currently running.
+ *         To initialize again, stack should be stopped first by calling st_things_stop()
+ *         and then deinitialized by calling st_things_deinitialize().
  * @since Tizen RT v1.1
  */
 int st_things_initialize(const char *json_path, bool *easysetup_complete);
 
 /**
  * @brief Deinitializes things stack.
+ *        Stack should have been initialized before calling this API.
  * @return @c 0 on success, otherwise a negative error value
  * @retval #ST_THINGS_ERROR_NONE Successful
  * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
+ * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not initialized.
+ *         Initialize the stack by calling st_things_initialize().
+ * @retval #ST_THINGS_ERROR_STACK_RUNNING Stack is currently running.
+ *         Before deinitialize, stack needs to be stopped by calling st_things_stop().
  * @since Tizen RT v1.1
  */
 int st_things_deinitialize(void);
@@ -112,9 +128,13 @@ int st_things_register_request_cb(st_things_get_request_cb get_cb, st_things_set
  *                Onboarding creates an ad-hoc network between the thing and the client for performing easy-setup.
  *            If easy-setup is already done, thing will be connected with the cloud.
  *            Application can know whether easy-setup is done or not through st_things_initialize API.
+ *            Stack should have been initialized before calling this API.
  * @return @c 0 on success, otherwise a negative error value
- * @retval #ST_THINGS_ERROR_NONE Successful
+ * @retval #ST_THINGS_ERROR_NONE Successful.
+ *         It is also used for the case that the stack is started already.
  * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
+ * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not initialized.
+ *         Initialize the stack by calling st_things_initialize().
  * @since Tizen RT v1.1
  */
 int st_things_start(void);
@@ -122,9 +142,14 @@ int st_things_start(void);
 /**
  * @brief Stops things stack.
  *            Removes all the data being used internally and releases all the memory allocated for the stack.
+ *            Stack should have been initialized and started before calling this API.
  * @return @c 0 on success, otherwise a negative error value
  * @retval #ST_THINGS_ERROR_NONE Successful
  * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
+ * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not initialized.
+ *         Initialize the stack by calling st_things_initialize().
+ * @retval #ST_THINGS_ERROR_STACK_NOT_STARTED Stack is not started.
+ *         Start the stack by calling st_things_start().
  * @since Tizen RT v1.1
  */
 int st_things_stop(void);
@@ -134,14 +159,14 @@ int st_things_stop(void);
  * @return @c true to confirm, otherwise @c to deny
  * @since Tizen RT v1.1
  */
-typedef bool (*st_things_reset_confirm_cb)(void);
+typedef bool(*st_things_reset_confirm_cb) (void);
 
 /**
  * @brief Callback for carrying the result of reset.
  * @param[in] is_success Result of Stack-reset. (true : success, false : failure)
  * @since Tizen RT v1.1
  */
-typedef void (*st_things_reset_result_cb)(bool is_success);
+typedef void (*st_things_reset_result_cb) (bool is_success);
 
 /**
  * @brief Callback registration function for Reset-Confirmation and Reset-Result functions.
@@ -162,9 +187,14 @@ int st_things_register_reset_cb(st_things_reset_confirm_cb confirm_cb, st_things
 
 /**
  * @brief Reset all the data related to security and cloud being used in the stack.
+ *        Stack should have been initialized and started before calling this API.
  * @return @c 0 on success, otherwise a negative error value
  * @retval #ST_THINGS_ERROR_NONE Successful
  * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
+ * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not intialized.
+ *         Initialize the stack by calling st_things_initialize().
+ * @retval #ST_THINGS_ERROR_STACK_NOT_STARTED Stack is not started.
+ *         Start the stack by calling st_things_start().
  * @since Tizen RT v1.1
  */
 int st_things_reset(void);
@@ -176,13 +206,13 @@ int st_things_reset(void);
  * @param[in] pin_size Length of the PIN String.
  * @since Tizen RT v1.1
  */
-typedef void (*st_things_pin_generated_cb)(const char *pin_data, const size_t pin_size);
+typedef void (*st_things_pin_generated_cb) (const char *pin_data, const size_t pin_size);
 
 /**
  * @brief Callback for informing the application to close the PIN display.
  * @since Tizen RT v1.1
  */
-typedef void (*st_things_pin_display_close_cb)(void);
+typedef void (*st_things_pin_display_close_cb) (void);
 
 /**
  * @brief Callback registration function for getting randomly generated PIN for the PIN-Based Ownership Transfer Request.
@@ -206,7 +236,7 @@ int st_things_register_pin_handling_cb(st_things_pin_generated_cb generated_cb,
  * @return @c true true in cse of confirmed, otherwise @c false
  * @since Tizen RT v1.1
  */
-typedef bool (*st_things_user_confirm_cb)(void);
+typedef bool(*st_things_user_confirm_cb) (void);
 
 /**
  * @brief Callback registration function for getting user confirmation for MUTUAL VERIFICATION BASED JUST WORK Ownership transfer.
@@ -228,7 +258,7 @@ int st_things_register_user_confirm_cb(st_things_user_confirm_cb confirm_cb);
  * @param[in]  things_status ST Things State
  * @since Tizen RT v1.1
  */
-typedef void (*st_things_status_change_cb)(st_things_status_e things_status);
+typedef void (*st_things_status_change_cb) (st_things_status_e things_status);
 
 /**
  * @brief Callback registration function for getting notified when ST Things state changes.
@@ -247,28 +277,21 @@ int st_things_register_things_status_change_cb(st_things_status_change_cb status
 
 /**
  * @brief Notify the observers of a specific resource.
+ *        Stack should have been initialized and started before calling this API.
  * @param[in]  resource_uri Resource URI of the resource which will be notified to observers.
  * @return @c 0 on success, otherwise a negative error value
  * @retval #ST_THINGS_ERROR_NONE Successful
  * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
+  * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not intialized.
+ *         Initialize the stack by calling st_things_initialize().
+ * @retval #ST_THINGS_ERROR_STACK_NOT_STARTED Stack is not started.
+ *         Start the stack by calling st_things_start().
  * @since Tizen RT v1.1
  */
 int st_things_notify_observers(const char *resource_uri);
 
 /**
- * @brief Send Representation of a specific resource through push service to Samsung Connect client.
- * @param[in]  resource_uri Resource uri for which we want to send push message.
- * @param[in]  rep Representation for resource uri.
- * @return @c 0 on success, otherwise a negative error value
- * @retval #ST_THINGS_ERROR_NONE Successful
- * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed
- * @since Tizen RT v1.1
- */
-int st_things_send_push_message(const char *resource_uri, st_things_representation_s *rep);
-
-/**
  * @brief Create an instance of representation.
  * @remarks To destroy an instance, st_things_destroy_representation_inst() should be used.
  * @return a pointer of the created representation, otherwise a null pointer if the memory is insufficient.
@@ -287,4 +310,4 @@ void st_things_destroy_representation_inst(st_things_representation_s *rep);
 }
 #endif                                                 /* __cplusplus */
 #endif                                                 /* __ST_THINGS_H__ */
-/** @} */// end of SmartThings group
+                /** @} */// end of SmartThings group
index f0b20a0..b14c603 100644 (file)
 /**
  * @ingroup SmartThings
  * @{
- */
+*/
 
 /**
  * @file st_things_types.h
  * @brief Provides structure definition for SmartThings Things SDK
  */
-
 #ifndef __ST_THINGS_TYPES_H__
 #define __ST_THINGS_TYPES_H__
 
  * @since Tizen RT v1.1
  */
 typedef enum {
-       ST_THINGS_ERROR_NONE = 0,                                 /**< Successful */
-       ST_THINGS_ERROR_INVALID_PARAMETER = -1,   /**< Invalid parameter (If parameter is null or empty)*/
-       ST_THINGS_ERROR_OPERATION_FAILED = -2,    /**< Operation Failed */
+       ST_THINGS_ERROR_NONE = 0,                                                  /**< Successful */
+       ST_THINGS_ERROR_INVALID_PARAMETER = -1,                    /**< Invalid parameter (If parameter is null or empty)*/
+       ST_THINGS_ERROR_OPERATION_FAILED = -2,                     /**< Operation Failed */
+       ST_THINGS_ERROR_STACK_NOT_INITIALIZED = -3,                /**< Stack is not yet initialized*/
+       ST_THINGS_ERROR_STACK_ALREADY_INITIALIZED = -4,    /**< Stack is already initialized*/
+       ST_THINGS_ERROR_STACK_NOT_STARTED = -5,                    /**< Stack is not yet started*/
+       ST_THINGS_ERROR_STACK_RUNNING = -6,                                /**< Stack is currently running*/
 } st_things_error_e;
 
 /**
@@ -58,9 +61,6 @@ typedef enum {
        ST_THINGS_STATUS_REGISTERED_TO_CLOUD,                      /**< Publish resource(s) to cloud is complete. Now the Thing is ready to be controlled via Cloud */
        ST_THINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN,    /**< Failed to sign-in to Cloud */
        ST_THINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES     /**< Failed to publish resources to Cloud */
-       /**
-     * @todo More status needs to be added, especially for failure cases like 'incorrect password to connect to target AP'
-     */
 } st_things_status_e;
 
 /**
@@ -79,7 +79,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_str_value)(struct _st_things_representation *rep, const char *key, char **value);
+        bool(*get_str_value) (struct _st_things_representation *rep, const char *key, char **value);
 
        /**
      * @brief API for getting the value of boolean type property with a key.
@@ -89,7 +89,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_bool_value)(struct _st_things_representation *rep, const char *key, bool *value);
+        bool(*get_bool_value) (struct _st_things_representation *rep, const char *key, bool *value);
 
        /**
      * @brief API for getting the value of integer type property with a key.
@@ -99,7 +99,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_int_value)(struct _st_things_representation *rep, const char *key, int64_t *value);
+        bool(*get_int_value) (struct _st_things_representation *rep, const char *key, int64_t *value);
 
        /**
      * @brief API for getting the value of double type property with a key.
@@ -109,7 +109,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_double_value)(struct _st_things_representation *rep, const char *key, double *value);
+        bool(*get_double_value) (struct _st_things_representation *rep, const char *key, double *value);
 
        /**
      * @brief API for getting the value of byte array type property with a key.
@@ -121,7 +121,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_byte_value)(struct _st_things_representation *rep, const char *key, uint8_t **value, size_t *size);
+        bool(*get_byte_value) (struct _st_things_representation *rep, const char *key, uint8_t **value, size_t *size);
 
        /**
      * @brief API for getting the value of object type property with a key.
@@ -133,7 +133,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_object_value)(struct _st_things_representation *rep, const char *key, struct _st_things_representation **value);
+        bool(*get_object_value) (struct _st_things_representation *rep, const char *key, struct _st_things_representation **value);
 
        /**
      * @brief API for setting the value of string type property with a key.
@@ -144,7 +144,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_str_value)(struct _st_things_representation *rep, const char *key, const char *value);
+        bool(*set_str_value) (struct _st_things_representation *rep, const char *key, const char *value);
 
        /**
      * @brief API for setting the value of boolean type property with a key.
@@ -154,7 +154,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_bool_value)(struct _st_things_representation *rep, const char *key, bool value);
+        bool(*set_bool_value) (struct _st_things_representation *rep, const char *key, bool value);
 
        /**
      * @brief API for setting the value of integer type property with a key.
@@ -164,7 +164,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_int_value)(struct _st_things_representation *rep, const char *key, int64_t value);
+        bool(*set_int_value) (struct _st_things_representation *rep, const char *key, int64_t value);
 
        /**
      * @brief API for setting the value of double type property with a key.
@@ -174,7 +174,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_double_value)(struct _st_things_representation *rep, const char *key, double value);
+        bool(*set_double_value) (struct _st_things_representation *rep, const char *key, double value);
 
        /**
      * @brief API for setting the value of byte array type property with a key.
@@ -186,7 +186,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_byte_value)(struct _st_things_representation *rep, const char *key, const uint8_t *value, size_t size);
+        bool(*set_byte_value) (struct _st_things_representation *rep, const char *key, const uint8_t *value, size_t size);
 
        /**
      * @brief API for setting the value of object type property with a key.
@@ -197,7 +197,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_object_value)(struct _st_things_representation *rep, const char *key, const struct _st_things_representation *value);
+        bool(*set_object_value) (struct _st_things_representation *rep, const char *key, const struct _st_things_representation *value);
 
        /**
      * @brief API for getting the value of string array type property with a key.
@@ -209,7 +209,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_str_array_value)(struct _st_things_representation *rep, const char *key, char ***array, size_t *length);
+        bool(*get_str_array_value) (struct _st_things_representation *rep, const char *key, char ***array, size_t *length);
 
        /**
      * @brief API for getting the value of integer array type property with a key.
@@ -221,7 +221,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_int_array_value)(struct _st_things_representation *rep, const char *key, int64_t **array, size_t *length);
+        bool(*get_int_array_value) (struct _st_things_representation *rep, const char *key, int64_t **array, size_t *length);
 
        /**
      * @brief API for getting the value of double array type property with a key.
@@ -233,7 +233,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_double_array_value)(struct _st_things_representation *rep, const char *key, double **array, size_t *length);
+        bool(*get_double_array_value) (struct _st_things_representation *rep, const char *key, double **array, size_t *length);
 
        /**
      * @brief API for getting the value of object array type property with a key.
@@ -246,7 +246,7 @@ typedef struct _st_things_representation {
      * @return @c true if value exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_object_array_value)(struct _st_things_representation *rep, const char *key, struct _st_things_representation ***array, size_t *length);
+        bool(*get_object_array_value) (struct _st_things_representation *rep, const char *key, struct _st_things_representation ***array, size_t *length);
 
        /**
      * @brief API for setting the value of string array type property with a key.
@@ -258,7 +258,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_str_array_value)(struct _st_things_representation *rep, const char *key, const char **array, size_t length);
+        bool(*set_str_array_value) (struct _st_things_representation *rep, const char *key, const char **array, size_t length);
 
        /**
      * @brief API for setting the value of integer array type property with a key.
@@ -270,7 +270,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_int_array_value)(struct _st_things_representation *rep, const char *key, const int64_t *array, size_t length);
+        bool(*set_int_array_value) (struct _st_things_representation *rep, const char *key, const int64_t *array, size_t length);
 
        /**
      * @brief API for setting the value of double array type property with a key.
@@ -282,7 +282,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_double_array_value)(struct _st_things_representation *rep, const char *key, const double *array, size_t length);
+        bool(*set_double_array_value) (struct _st_things_representation *rep, const char *key, const double *array, size_t length);
 
        /**
      * @brief API for setting the value of object array type property with a key.
@@ -294,7 +294,7 @@ typedef struct _st_things_representation {
      * @return @c true if setting value is successful, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*set_object_array_value)(struct _st_things_representation *rep, const char *key, const struct _st_things_representation **array, size_t length);
+        bool(*set_object_array_value) (struct _st_things_representation *rep, const char *key, const struct _st_things_representation **array, size_t length);
 
 } st_things_representation_s;
 
@@ -315,7 +315,7 @@ typedef struct _st_things_get_request_message {
      * @return @c true if query exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_query_value)(struct _st_things_get_request_message *req_msg, const char *key, char **value);
+        bool(*get_query_value) (struct _st_things_get_request_message *req_msg, const char *key, char **value);
 
        /**
      * @brief API for checking whether the request has a specific property key or not.
@@ -324,7 +324,7 @@ typedef struct _st_things_get_request_message {
      * @return @c true if the property key exists, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*has_property_key)(struct _st_things_get_request_message *req_msg, const char *key);
+        bool(*has_property_key) (struct _st_things_get_request_message *req_msg, const char *key);
 
 } st_things_get_request_message_s;
 
@@ -345,7 +345,7 @@ typedef struct _st_things_set_request_message {
      * @return @c true if query exist, otherwise @c false
      * @since Tizen RT v1.1
      */
-       bool (*get_query_value)(struct _st_things_set_request_message *req_msg, const char *key, char **value);
+        bool(*get_query_value) (struct _st_things_set_request_message *req_msg, const char *key, char **value);
 
 } st_things_set_request_message_s;
 
diff --git a/framework/src/st_things/Kconfig b/framework/src/st_things/Kconfig
new file mode 100644 (file)
index 0000000..af562ba
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# For a description of the syntax of this configuration file,
+# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
+#
+
+config ST_THINGS
+       bool "SmartThings Things Management"
+       default n
+       select ENABLE_IOTIVITY
+       select ENABLE_IOTIVITY_SECURED
+       select ENABLE_IOTIVITY_CLOUD
+       select NETUTILS_WIFI
+       select WIFI_MANAGER
+       select WPA_SUPPLICANT
+       select SCSC_WLAN
+       select NETUTILS_JSON
+       depends on FS_ROMFS
+       ---help---
+               SmartThings Things Management for applications to use and control devices
diff --git a/framework/src/st_things/Make.defs b/framework/src/st_things/Make.defs
new file mode 100644 (file)
index 0000000..cd4b853
--- /dev/null
@@ -0,0 +1,111 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+THINGS_LIB_DIR = $(TOPDIR)/../framework/src/st_things
+THINGS_STACK_DIR = $(TOPDIR)/../framework/src/st_things/things_stack
+IOTIVITY_RELEASE=${shell echo $(CONFIG_IOTIVITY_RELEASE_VERSION) | sed 's/"//g'}
+IOTIVITY_BASE_DIR = $(TOPDIR)/../external/iotivity/iotivity_$(IOTIVITY_RELEASE)
+
+CSRCS += st_things.c st_things_util.c st_things_request_handler.c st_things_request_handler_collection.c st_things_representation.c st_things_logger.c 
+
+CFLAGS += -D__TIZENRT__
+CFLAGS += -D__TINYARA__
+CFLAGS += -D__ST_THINGS_RTOS__
+CFLAGS += -DUSE_LOG_NO_NEWLINE
+CFLAGS += -std=c99
+CFLAGS += -w
+
+####################################
+# LIBS
+####################################
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/cloud/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/easy-setup/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/framework/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/logging/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/memory/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/security/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/utils/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/stack
+CFLAGS += -I$(THINGS_STACK_DIR)/inc
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/security/ssCrypto/include
+CFLAGS += -I$(THINGS_STACK_DIR)/src/common/framework/inc
+
+
+#
+# THINGS STACK
+#
+CFLAGS += -DWITH_POSIX -DIP_ADAPTER
+CFLAGS += -DWITH_BWT
+#CFLAGS += -D_EXCLUDE_TEST_KEY_
+
+include $(THINGS_STACK_DIR)/Make.defs
+include $(THINGS_STACK_DIR)/src/stack/Make.defs
+include $(THINGS_STACK_DIR)/src/common/utils/Make.defs
+include $(THINGS_STACK_DIR)/src/common/framework/Make.defs
+include $(THINGS_STACK_DIR)/src/common/easy-setup/Make.defs
+include $(THINGS_STACK_DIR)/src/common/cloud/Make.defs
+include $(THINGS_STACK_DIR)/src/common/security/ssCrypto/src/Make.defs
+include $(THINGS_STACK_DIR)/src/common/logging/Make.defs
+include $(THINGS_STACK_DIR)/src/common/memory/Make.defs
+
+####################################
+# IOTIVITY
+####################################
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/c_common
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/connectivity/api
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/connectivity/common/inc
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/logger/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/security/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/security/include/internal
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/stack/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/extlibs/mbedtls/mbedtls/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/c_common/oic_malloc/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/c_common/oic_string/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/c_common/ocrandom/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/c_common/oic_time/include
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/connectivity/api
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/service/notification/src/common/
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/service/notification/include/
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/service/notification/src/provider/
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/resource-directory/include/
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/connectivity/lib/libcoap-4.1.1/include/
+CFLAGS += -I$(IOTIVITY_BASE_DIR)/resource/csdk/stack/include/internal/
+
+
+ifeq ($(CONFIG_IOTIVITY_ROUTING),"EP")
+CFLAGS += -DROUTING_EP
+else
+CFLAGS += -DROUTING_GW
+endif
+
+ifeq ($(CONFIG_ENABLE_IOTIVITY_SECURED),y)
+CFLAGS += -D__WITH_DTLS__
+CFLAGS += -D__ST_THINGS_RTOS_LOCAL_SECURED__
+endif
+
+ifeq ($(CONFIG_ENABLE_IOTIVITY_CLOUD),y)
+CFLAGS += -DWITH_CLOUD
+CFLAGS += -D__WITH_TLS__
+CFLAGS += -D__SECURED__
+CFLAGS += -DTCP_ADAPTER
+CFLAGS += -D__ST_THINGS_RTOS_CLOUD__
+endif
+
+DEPPATH += --dep-path src/st_things
+VPATH += :src/st_things
diff --git a/framework/src/st_things/st_things.c b/framework/src/st_things/st_things.c
new file mode 100644 (file)
index 0000000..9be054a
--- /dev/null
@@ -0,0 +1,587 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __ST_THINGS_RTOS__
+#include <st_things/st_things.h>
+#else
+#include "st_things.h"
+#endif                                                 // __ST_THINGS_RTOS__
+#include "st_things_request_handler.h"
+#include "st_things_representation.h"
+#include "st_things_logger.h"
+
+#include "things_api.h"
+#include "things_types.h"
+#include "things_resource.h"
+#include "ocpayload.h"
+#include "octypes.h"
+
+static st_things_reset_confirm_cb g_handle_reset_confirm_cb = NULL;
+static st_things_reset_result_cb g_handle_reset_result_cb = NULL;
+
+static st_things_pin_generated_cb g_handle_pin_generated_cb = NULL;
+static st_things_pin_display_close_cb g_handle_pin_display_close_cb = NULL;
+
+static st_things_user_confirm_cb g_handle_user_confirm_cb = NULL;
+
+static st_things_status_change_cb g_handle_things_status_change_cb = NULL;
+
+typedef enum {
+       STACK_NOT_INITIALIZED = 0,
+       STACK_INITIALIZED,
+       STACK_STARTED
+} stack_status_e;
+
+static stack_status_e g_stack_status = STACK_NOT_INITIALIZED;
+
+ /**
+ * This callback will be invoked by DA Stack with the result of reset.
+ * Result will be passed to the application through its registered callback.
+ */
+void get_reset_result_cb(int result)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       ST_LOG_V(ST_DEBUG, "Result of reset is %d", result);
+       bool res = (result == 1) ? true : false;
+       if (NULL != g_handle_reset_result_cb) {
+               g_handle_reset_result_cb(res);
+       }
+       ST_LOG_EXIT(ST_INFO);
+}
+
+ /**
+ * This callback will be registered with the DA Stack to get the request for user's confirmation for reset.
+ * Application's callback will be invoked to get the user's opinion.
+ */
+int get_reset_confirm_cb(things_reset_result_func_type *func_carrier, things_es_enrollee_reset_e reset_type)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == g_handle_reset_confirm_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return 0;
+       }
+
+       if (RST_NEED_CONFIRM == reset_type) {
+               // Invoke application's callback to get user's confirmation and pass the result to DA Stack.
+               bool confirm = g_handle_reset_confirm_cb();
+               ST_LOG_V(ST_DEBUG, "User's confirmation for reset : %s", confirm ? "true" : "false");
+               if (confirm) {
+                       things_return_user_opinion_for_reset(1);
+               } else {
+                       things_return_user_opinion_for_reset(0);
+               }
+       } else if (RST_AUTO_RESET == reset_type) {
+               ST_LOG(ST_DEBUG, "Reset will start automatically");
+               things_return_user_opinion_for_reset(1);
+       } else {
+               ST_LOG_V(ST_ERROR, "reset_type(%d) is invalid", reset_type);
+               ST_LOG_EXIT(ST_INFO);
+               return 0;
+       }
+
+       // Set the callback through this function's value-result paramter with DA Stack to get the result of reset.
+       *func_carrier = get_reset_result_cb;
+
+       ST_LOG_EXIT(ST_INFO);
+       return 1;
+}
+
+ /**
+ * This callback will be registered with the DA Stack to recieve easy-setup events.
+ * The status will be passed to the application through the callback registered by the application.
+ */
+void get_things_status_cb(things_es_enrollee_state_e state)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       ST_LOG_V(ST_DEBUG, "Received event for easy-setup state change (%d)", state);
+       bool handled = true;
+       st_things_status_e status = ST_THINGS_STATUS_INIT;
+       switch (state) {
+       case ES_STATE_INIT:
+               status = ST_THINGS_STATUS_INIT;
+               break;
+       case ES_STATE_CONNECTING_TO_ENROLLER:
+               status = ST_THINGS_STATUS_CONNECTING_TO_AP;
+               break;
+       case ES_STATE_CONNECTED_TO_ENROLLER:
+               status = ST_THINGS_STATUS_CONNECTED_TO_AP;
+               break;
+       case ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER:
+               status = ST_THINGS_STATUS_CONNECTING_TO_AP_FAILED;
+               break;
+       case ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD:
+               status = ST_THINGS_STATUS_REGISTERING_TO_CLOUD;
+               break;
+       case ES_STATE_FAILED_TO_REGISTER_TO_CLOUD:
+               status = ST_THINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN;
+               break;
+       case ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD:
+               status = ST_THINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES;
+               break;
+       case ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD:
+               status = ST_THINGS_STATUS_REGISTERED_TO_CLOUD;
+               break;
+       default:
+               ST_LOG(ST_DEBUG, "This state is ignored");
+               handled = false;
+               break;
+       }
+
+       if (handled && NULL != g_handle_things_status_change_cb) {
+               g_handle_things_status_change_cb(status);
+       }
+       ST_LOG_EXIT(ST_INFO);
+}
+
+ /**
+ * DA Stack invokes this callback for providing ownership transfer states.
+ */
+void ownership_transfer_state_cb(const char *addr, uint16_t port, const char *uuid, int event)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       ST_LOG_V(ST_DEBUG, "Received event for ownership-transfer state change (%d)", event);
+       (void)addr;
+       (void)port;
+       (void)uuid;
+
+       if (NULL == g_handle_things_status_change_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return;
+       }
+
+       switch (event) {
+       case 1:                                 // OTM Started
+               g_handle_things_status_change_cb(ST_THINGS_STATUS_ES_STARTED);
+               break;
+       case 2:                                 // OTM Done
+               g_handle_things_status_change_cb(ST_THINGS_STATUS_ES_DONE);
+               break;
+       case 3:                                 // OTM Error
+               g_handle_things_status_change_cb(ST_THINGS_STATUS_ES_FAILED_ON_OWNERSHIP_TRANSFER);
+               break;
+       }
+       ST_LOG_EXIT(ST_INFO);
+}
+
+ /**
+ * Callback for getting users confirmation for MUTUAL VERIFICATION BASED JUST WORK Ownership transfer
+ */
+int get_user_confirm_cb(void)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == g_handle_user_confirm_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return 0;
+       }
+
+       bool confirm = g_handle_user_confirm_cb();
+       ST_LOG_V(ST_DEBUG, "User's confirmation for MUTUAL VERIFICATION BASED JUST WORK Ownership-transfer : %s", confirm ? "true" : "false");
+
+       ST_LOG_EXIT(ST_INFO);
+       return confirm ? 1 : 0;
+}
+
+ /**
+ * Callback for getting the pin for random pin based ownership transfer.
+ */
+void generated_pin_cb(char *pin_data, size_t pin_size)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL != g_handle_pin_generated_cb) {
+               g_handle_pin_generated_cb(pin_data, pin_size);
+       }
+       ST_LOG_EXIT(ST_INFO);
+}
+
+ /**
+ * Callback for getting the close pin display request after random pin based ownership transfer.
+ */
+void close_pin_display_cb(void)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL != g_handle_pin_display_close_cb) {
+               g_handle_pin_display_close_cb();
+       }
+       ST_LOG_EXIT(ST_INFO);
+}
+
+int st_things_initialize(const char *json_path, bool *easysetup_complete)
+{
+       ST_LOG_ENTRY(ST_INFO);
+
+       if (STACK_NOT_INITIALIZED != g_stack_status) {
+               int ret_val = ST_THINGS_ERROR_OPERATION_FAILED;
+               switch (g_stack_status) {
+               case STACK_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack initialized already.");
+                       ret_val = ST_THINGS_ERROR_STACK_ALREADY_INITIALIZED;
+                       break;
+               case STACK_STARTED:
+                       ST_LOG(ST_ERROR, "Stack is currently running.");
+                       ret_val = ST_THINGS_ERROR_STACK_RUNNING;
+                       break;
+               default:
+                       ST_LOG_V(ST_ERROR, "Invalid stack state: %d.", g_stack_status);
+                       break;
+               }
+
+               ST_LOG_EXIT(ST_INFO);
+               return ret_val;
+       }
+
+       if (NULL == json_path) {
+               ST_LOG(ST_ERROR, "Json file path is NULL");
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       ST_LOG_V(ST_DEBUG, "JSON file path: %s", json_path);
+
+       int result = 0;
+       if (1 != (result = things_initialize_stack(json_path, easysetup_complete))) {
+               ST_LOG_V(ST_ERROR, "things_initialize_stack failed (result:%d)", result);
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_OPERATION_FAILED;
+       }
+
+       g_stack_status = STACK_INITIALIZED;
+
+       ST_LOG_V(ST_DEBUG, "Is EasySetup completed : %s", (*easysetup_complete) ? "true" : "false");
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_deinitialize(void)
+{
+       ST_LOG_ENTRY(ST_INFO);
+
+       if (STACK_INITIALIZED != g_stack_status) {
+               int ret_val = ST_THINGS_ERROR_OPERATION_FAILED;
+               switch (g_stack_status) {
+               case STACK_NOT_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is not initialized.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_INITIALIZED;
+                       break;
+               case STACK_STARTED:
+                       ST_LOG(ST_ERROR, "Stack is currently running. Stop the stack before deinitializing it.");
+                       ret_val = ST_THINGS_ERROR_STACK_RUNNING;
+                       break;
+               default:
+                       ST_LOG_V(ST_ERROR, "Invalid stack state: %d.", g_stack_status);
+                       break;
+               }
+
+               ST_LOG_EXIT(ST_INFO);
+               return ret_val;
+       }
+
+       int result = 0;
+       if (1 != (result = things_deinitialize_stack())) {
+               ST_LOG_V(ST_ERROR, "things_deinitialize_stack failed (result:%d)", result);
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_OPERATION_FAILED;
+       }
+
+       g_stack_status = STACK_NOT_INITIALIZED;
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_start(void)
+{
+       ST_LOG_INIT();
+       ST_LOG_ENTRY(ST_INFO);
+
+       if (STACK_INITIALIZED != g_stack_status) {
+               int ret_val = ST_THINGS_ERROR_OPERATION_FAILED;
+               switch (g_stack_status) {
+               case STACK_NOT_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is not initialized.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_INITIALIZED;
+                       break;
+               case STACK_STARTED:
+                       ST_LOG(ST_DEBUG, "Stack started already.");
+                       ret_val = ST_THINGS_ERROR_NONE;
+                       break;
+               default:
+                       ST_LOG_V(ST_ERROR, "Invalid stack state: %d.", g_stack_status);
+                       break;
+               }
+
+               ST_LOG_EXIT(ST_INFO);
+               return ret_val;
+       }
+
+       int result = 0;
+
+       // Register callback for reset confirmation.
+       if (1 != (result = things_register_confirm_reset_start_func(get_reset_confirm_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_confirm_reset_start_func failed (result:%d)", result);
+               goto error;
+       }
+       // Register callback for easy-setup status.
+       if (1 != (result = things_register_easysetup_state_func(get_things_status_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_easysetup_state_func failed (result:%d)", result);
+               goto error;
+       }
+       // Register callback for receiving the Security Ownership Transfer state changes.
+       if (1 != (result = things_register_otm_event_handler(ownership_transfer_state_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_otm_event_handler failed (result:%d)", result);
+               goto error;
+       }
+       // Register callback for receiving request during ownership transfer for getting confirmation from user.
+       if (1 != (result = things_register_user_confirm_func(get_user_confirm_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_user_confirm_func failed (result:%d)", result);
+               goto error;
+       }
+       // Register callback for receiving the pin generated for ownership transfer.
+       if (1 != (result = things_register_pin_generated_func(generated_pin_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_pin_generated_func failed (result:%d)", result);
+               goto error;
+       }
+       // Register callback to receiving request for closing the PIN display.
+       if (1 != (result = things_register_pin_display_close_func(close_pin_display_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_pin_display_close_func failed (result:%d)", result);
+               goto error;
+       }
+       // Register callback to handle GET and POST requests.
+       if (1 != (result = things_register_handle_request_func(handle_get_request_cb, handle_set_request_cb))) {
+               ST_LOG_V(ST_ERROR, "things_register_handle_request_func failed (result:%d)", result);
+               goto error;
+       }
+       // Start DA Stack.
+       if (1 != (result = things_start_stack())) {
+               ST_LOG_V(ST_ERROR, "things_start_stack failed (result:%d)", result);
+               goto error;
+       }
+
+       g_stack_status = STACK_STARTED;
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+
+ error:
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_OPERATION_FAILED;
+}
+
+int st_things_stop(void)
+{
+       ST_LOG_ENTRY(ST_INFO);
+
+       if (STACK_STARTED != g_stack_status) {
+               int ret_val = ST_THINGS_ERROR_OPERATION_FAILED;
+               switch (g_stack_status) {
+               case STACK_NOT_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is not initialized.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_INITIALIZED;
+                       break;
+               case STACK_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is not started.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_STARTED;
+                       break;
+               default:
+                       ST_LOG_V(ST_ERROR, "Invalid stack state: %d.", g_stack_status);
+                       break;
+               }
+
+               ST_LOG_EXIT(ST_INFO);
+               return ret_val;
+       }
+
+       int result = 0;
+
+       // Terminate DA Stack.
+       if (1 != (result = things_stop())) {
+               ST_LOG_V(ST_ERROR, "things_stop failed (result:%d)", result);
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_OPERATION_FAILED;
+       }
+
+       g_stack_status = STACK_INITIALIZED;
+
+       ST_LOG_EXIT(ST_INFO);
+       ST_LOG_DEINIT();
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_register_request_cb(st_things_get_request_cb get_cb, st_things_set_request_cb set_cb)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == get_cb || NULL == set_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       ST_LOG_EXIT(ST_INFO);
+       return register_request_handler_cb(get_cb, set_cb);
+}
+
+int st_things_register_reset_cb(st_things_reset_confirm_cb confirm_cb, st_things_reset_result_cb result_cb)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == confirm_cb || NULL == result_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       g_handle_reset_confirm_cb = confirm_cb;
+       g_handle_reset_result_cb = result_cb;
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_reset(void)
+{
+       ST_LOG_ENTRY(ST_INFO);
+
+       if (STACK_STARTED != g_stack_status) {
+               int ret_val = ST_THINGS_ERROR_OPERATION_FAILED;
+               switch (g_stack_status) {
+               case STACK_NOT_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is not initialized. Before reset, stack should be initialized and started.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_INITIALIZED;
+                       break;
+               case STACK_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is initialized but not started.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_STARTED;
+                       break;
+               default:
+                       ST_LOG_V(ST_ERROR, "Invalid stack state: %d.", g_stack_status);
+                       break;
+               }
+
+               ST_LOG_EXIT(ST_INFO);
+               return ret_val;
+       }
+
+       int result = 0;
+       if (1 != (result = things_reset(NULL, RST_AUTO_RESET))) {
+               ST_LOG_V(ST_ERROR, "things_reset failed (result:%d)", result);
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_OPERATION_FAILED;
+       }
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_register_pin_handling_cb(st_things_pin_generated_cb generated_cb, st_things_pin_display_close_cb close_cb)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == generated_cb || NULL == close_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       g_handle_pin_generated_cb = generated_cb;
+       g_handle_pin_display_close_cb = close_cb;
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_register_user_confirm_cb(st_things_user_confirm_cb confirm_cb)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == confirm_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       g_handle_user_confirm_cb = confirm_cb;
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_register_things_status_change_cb(st_things_status_change_cb status_cb)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       if (NULL == status_cb) {
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       g_handle_things_status_change_cb = status_cb;
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+int st_things_notify_observers(const char *resource_uri)
+{
+       ST_LOG_ENTRY(ST_INFO);
+
+       if (STACK_STARTED != g_stack_status) {
+               int ret_val = ST_THINGS_ERROR_OPERATION_FAILED;
+               switch (g_stack_status) {
+               case STACK_NOT_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is not initialized. Before notifying observers, stack should be initialized and started.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_INITIALIZED;
+                       break;
+               case STACK_INITIALIZED:
+                       ST_LOG(ST_ERROR, "Stack is initialized but not started.");
+                       ret_val = ST_THINGS_ERROR_STACK_NOT_STARTED;
+                       break;
+               default:
+                       ST_LOG_V(ST_ERROR, "Invalid stack state: %d.", g_stack_status);
+                       break;
+               }
+
+               ST_LOG_EXIT(ST_INFO);
+               return ret_val;
+       }
+
+       if (NULL == resource_uri || 1 > strlen(resource_uri)) {
+               ST_LOG(ST_ERROR, "The resource URI is invalid");
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       int result = 0;
+       if (1 != (result = things_notify_observers(resource_uri))) {
+               ST_LOG_V(ST_ERROR, "things_notify_observers failed (result:%d)", result);
+               ST_LOG_EXIT(ST_INFO);
+               return ST_THINGS_ERROR_OPERATION_FAILED;
+       }
+
+       ST_LOG_EXIT(ST_INFO);
+       return ST_THINGS_ERROR_NONE;
+}
+
+st_things_representation_s *st_things_create_representation_inst()
+{
+       ST_LOG_ENTRY(ST_INFO);
+       st_things_representation_s *rep = create_representation_inst();
+       ST_LOG_EXIT(ST_INFO);
+       return rep;
+}
+
+void st_things_destroy_representation_inst(st_things_representation_s *rep)
+{
+       ST_LOG_ENTRY(ST_INFO);
+       destroy_representation_inst(rep);
+       ST_LOG_EXIT(ST_INFO);
+}
diff --git a/framework/src/st_things/st_things_logger.c b/framework/src/st_things/st_things_logger.c
new file mode 100644 (file)
index 0000000..6d87dc3
--- /dev/null
@@ -0,0 +1,123 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include "st_things_logger.h"
+#include "string.h"
+
+#ifndef __TIZEN__
+static const uint16_t LINE_BUFFER_SIZE = 255;
+static const char *LEVEL[] __attribute__ ((unused)) = {
+"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
+
+static char *p_version = NULL;
+
+void st_things_log_init()
+{
+       /* Initialize p_version variable */
+       p_version = NULL;
+}
+
+void st_things_log_shutdown()
+{
+       /* Free the memory allocated for p_version */
+       free(p_version);
+}
+
+void st_things_log_set_version(char *version)
+{
+       if (NULL == version) {
+               return;
+       }
+
+       if (NULL != p_version) {
+               free(p_version);
+       }
+
+       /* Allocate memory for p_version and set the version information */
+       p_version = (char *)malloc(strlen(version) + 1);
+       if (NULL == p_version) {
+               printf("Error while allocating memory for version");
+               return;
+       }
+       memset(p_version, 0, strlen(version) + 1);
+       strncpy(p_version, version, strlen(version));
+}
+
+/**
+ * Output a log string with the specified priority level.
+ * Only defined for Linux and Android
+ *
+ * @param level  - ST_DEBUG, ST_INFO, ST_WARNING, ST_ERROR, ST_FATAL
+ * @param tag    - Module name
+ * @param log_str - log string
+ */
+void st_things_log(st_things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *log_str)
+{
+       if (!log_str || !tag) {
+               return;
+       }
+
+       struct timeval tv;
+       time_t now_time = 0;
+       struct tm *now_tm = NULL;
+       char tm_buf[64] = { 0 };
+
+       gettimeofday(&tv, NULL);
+       now_time = tv.tv_sec;
+       now_tm = localtime(&now_time);
+       strftime(tm_buf, sizeof tm_buf, "%m/%d %H:%M:%S", now_tm);
+
+       if (p_version) {
+               printf("[%s %s] %s %s %s %d %s\n", tm_buf, p_version, LEVEL[level], tag, func_name, line_num, log_str);
+       } else {
+               printf("[%s] %s %s %s %d %s\n", tm_buf, LEVEL[level], tag, func_name, line_num, log_str);
+       }
+}
+
+/**
+ * Output a variable argument list log string with the specified priority level.
+ * Only defined for Linux and Android
+ *
+ * @param level  - ST_DEBUG, ST_INFO, ST_WARNING, ST_ERROR, ST_FATAL
+ * @param tag    - Module name
+ * @param format - variadic log string
+ */
+void st_things_log_v(st_things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *format, ...)
+{
+       if (!format || !tag) {
+               return;
+       }
+
+       /* Using Variable arguments to extract each argument and passing it st_things_log API */
+       char buffer[MAX_LOG_V_BUFFER_SIZE] = { 0 };
+       va_list args;
+       va_start(args, format);
+       vsnprintf(buffer, sizeof buffer - 1, format, args);
+       va_end(args);
+       st_things_log(level, tag, func_name, line_num, buffer);
+}
+#endif                                                 //#ifndef __TIZEN__
diff --git a/framework/src/st_things/st_things_logger.h b/framework/src/st_things/st_things_logger.h
new file mode 100644 (file)
index 0000000..c5b36d0
--- /dev/null
@@ -0,0 +1,127 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef __ST_THINGS_LOGGER_H__
+#define __ST_THINGS_LOGGER_H__
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef __TIZEN__
+#include <dlog.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif                                                 /* __cplusplus */
+
+/* Log Value Macro's */
+#define ST_THINGS_FUNC_ENTRY "IN"
+#define ST_THINGS_FUNC_EXIT "OUT"
+#define ST_THINGS_MEMORY_ERROR "Memory Error"
+#define ST_THINGS_INVALID_PARAM "Invalid Parameter"
+#define ST_THINGS_TAG "ST_THINGS_SDK"
+
+// Max buffer size used in variable argument log function
+#define MAX_LOG_V_BUFFER_SIZE (256)
+
+// Log levels
+#ifdef __TIZEN__
+       typedef enum {
+               ST_DEBUG = DLOG_DEBUG,
+               ST_INFO = DLOG_INFO,
+               ST_WARNING = DLOG_WARN,
+               ST_ERROR = DLOG_ERROR,
+               ST_FATAL = DLOG_FATAL
+       } st_things_log_level_e;
+#endif
+
+#ifndef __TIZEN__                              /* Linux */
+       typedef enum {
+               ST_DEBUG,
+               ST_INFO,
+               ST_WARNING,
+               ST_ERROR,
+               ST_FATAL
+       } st_things_log_level_e;
+
+ /**
+  * Initialize the logger.
+  */
+       void st_things_log_init();
+
+ /**
+  * Called to Free dyamically allocated resources used with custom logging.
+  * Not necessary if default logging is used
+  */
+       void st_things_log_shutdown();
+
+ /**
+  * Set the Version.
+  */
+       void st_things_log_set_version(char *version);
+
+ /**
+  * Output a log string with the specified priority level.
+  * Only defined for Linux and Android
+  *
+  * @param level   - ST_DEBUG, ST_INFO, ST_WARNING, ST_ERROR, ST_FATAL
+  * @param tag     - Module name
+  * @param log_str - log string
+  */
+       void st_things_log(st_things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *log_str);
+
+ /**
+  * Output a variable argument list log string with the specified priority level.
+  * @param level  - ST_DEBUG, ST_INFO, ST_WARNING, ST_ERROR, ST_FATAL
+  * @param tag    - Module name
+  * @param format - variadic log string
+  */
+       void st_things_log_v(st_things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *format, ...);
+#endif                                                 //#ifndef __TIZEN__
+
+#ifdef FEATURE_LOGGING
+#ifdef __TIZEN__
+#define ST_LOG_INIT()
+#define ST_LOG_DEINIT()
+#define ST_LOG(level, log_str) dlog_print(level, ST_THINGS_TAG, "%s : %s(%d) > " log_str, __FILE__, __FUNCTION__, __LINE__)
+#define ST_LOG_V(level, fmt, ...) dlog_print(level, ST_THINGS_TAG, "%s : %s(%d) > " fmt, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define ST_LOG_ENTRY(level) dlog_print(level, ST_THINGS_TAG, "%s : %s(%d) > " ST_THINGS_FUNC_ENTRY, __FILE__, __FUNCTION__, __LINE__)
+#define ST_LOG_EXIT(level) dlog_print(level, ST_THINGS_TAG, "%s : %s(%d) > " ST_THINGS_FUNC_EXIT, __FILE__, __FUNCTION__, __LINE__)
+#else                                                  /* Linux */
+#define ST_LOG_INIT()   st_things_log_init()
+#define ST_LOG_DEINIT()   st_things_log_shutdown()
+#define ST_LOG(level, log_str)  st_things_log((level), ST_THINGS_TAG, __FUNCTION__, __LINE__, (log_str))
+#define ST_LOG_V(level, fmt, ...)   st_things_log_v((level), ST_THINGS_TAG, __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
+#define ST_LOG_ENTRY(level) st_things_log((level), ST_THINGS_TAG, __FUNCTION__, __LINE__, (ST_THINGS_FUNC_ENTRY))
+#define ST_LOG_EXIT(level) st_things_log((level), ST_THINGS_TAG, __FUNCTION__, __LINE__, (ST_THINGS_FUNC_EXIT))
+#endif
+#else                                                  //DISABLE LOGGING
+#define ST_LOG_INIT()
+#define ST_LOG_DEINIT()
+#define ST_LOG(level, log_str)
+#define ST_LOG_V(level, fmt, ...)
+#define ST_LOG_ENTRY(level)
+#define ST_LOG_EXIT(level)
+#endif                                                 // FEATURE_LOGGING
+
+#ifdef __cplusplus
+}
+#endif                                                 /* __cplusplus */
+#endif                                                 /* __ST_THINGS_LOGGER_H__ */
diff --git a/framework/src/st_things/st_things_representation.c b/framework/src/st_things/st_things_representation.c
new file mode 100644 (file)
index 0000000..f2bca53
--- /dev/null
@@ -0,0 +1,413 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "st_things_representation.h"
+#include "st_things_util.h"
+#include "st_things_logger.h"
+#include "ocpayload.h"
+
+bool get_str_value(struct _st_things_representation *rep, const char *key, char **value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       return OCRepPayloadGetPropString((OCRepPayload *) rep->payload, key, value);
+}
+
+bool get_bool_value(struct _st_things_representation *rep, const char *key, bool *value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       return OCRepPayloadGetPropBool((OCRepPayload *) rep->payload, key, value);
+}
+
+bool get_int_value(struct _st_things_representation *rep, const char *key, int64_t *value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       return OCRepPayloadGetPropInt((OCRepPayload *)rep->payload, key, value);
+}
+
+bool get_double_value(struct _st_things_representation *rep, const char *key, double *value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       return OCRepPayloadGetPropDouble((OCRepPayload *) rep->payload, key, value);
+}
+
+bool get_byte_value(struct _st_things_representation *rep, const char *key, uint8_t **value, size_t *size)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+       RET_FALSE_IF_PARAM_IS_NULL(size);
+
+       OCByteString byte_value = { NULL, 0 };
+       if (!OCRepPayloadGetPropByteString((OCRepPayload *)rep->payload, key, &byte_value)) {
+               return false;
+       }
+
+       (*size) = byte_value.len;
+       (*value) = byte_value.bytes;
+
+       return true;
+}
+
+bool get_object_value(struct _st_things_representation *rep, const char *key, struct _st_things_representation **value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       OCRepPayload *payload = NULL;
+       bool result = OCRepPayloadGetPropObject(rep->payload, key, &payload);
+       if (result) {
+               *value = create_representation_inst_internal(payload);
+               if (NULL == *value) {
+                       ST_LOG(ST_ERROR, "Failed to create representation for value.");
+                       OCRepPayloadDestroy(payload);
+                       return false;
+               }
+       }
+       return result;
+}
+
+bool set_str_value(struct _st_things_representation *rep, const char *key, const char *value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       return OCRepPayloadSetPropString(rep->payload, key, value);
+}
+
+bool set_bool_value(struct _st_things_representation *rep, const char *key, bool value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+
+       return OCRepPayloadSetPropBool(rep->payload, key, value);
+}
+
+bool set_int_value(struct _st_things_representation *rep, const char *key, int64_t value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+
+       return OCRepPayloadSetPropInt(rep->payload, key, value);
+}
+
+bool set_double_value(struct _st_things_representation *rep, const char *key, double value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+
+       return OCRepPayloadSetPropDouble(rep->payload, key, value);
+}
+
+bool set_byte_value(struct _st_things_representation *rep, const char *key, const uint8_t *value, size_t size)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+       RET_FALSE_IF_PARAM_EXPR_IS_TRUE(size < 1);
+
+       OCByteString bVal = { (uint8_t *) /*To resolve a build warning */ value, size };
+       return OCRepPayloadSetPropByteString(rep->payload, key, bVal);
+}
+
+bool set_object_value(struct _st_things_representation *rep, const char *key, const struct _st_things_representation *value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+       RET_FALSE_IF_PARAM_IS_NULL(value->payload);
+
+       return OCRepPayloadSetPropObject(rep->payload, key, value->payload);
+}
+
+bool get_str_array_value(struct _st_things_representation *rep, const char *key, char ***array, size_t *length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_IS_NULL(length);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+       bool ret = OCRepPayloadGetStringArray(rep->payload, key, array, dimensions);
+       if (true == ret) {
+               *length = calcDimTotal(dimensions);
+       }
+
+       return ret;
+}
+
+bool get_int_array_value(struct _st_things_representation *rep, const char *key, int64_t **array, size_t *length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_IS_NULL(length);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+       bool ret = OCRepPayloadGetIntArray(rep->payload, key, array, dimensions);
+       if (true == ret) {
+               *length = calcDimTotal(dimensions);
+       }
+
+       return ret;
+}
+
+bool get_double_array_value(struct _st_things_representation *rep, const char *key, double **array, size_t *length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_IS_NULL(length);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+       bool ret = OCRepPayloadGetDoubleArray(rep->payload, key, array, dimensions);
+       if (true == ret) {
+               *length = calcDimTotal(dimensions);
+       }
+
+       return ret;
+}
+
+bool get_object_array_value(struct _st_things_representation *rep, const char *key, struct _st_things_representation ***array, size_t *length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_IS_NULL(length);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+       OCRepPayload **children = NULL;
+       bool ret = OCRepPayloadGetPropObjectArray(rep->payload, key, &children, dimensions);
+       if (!ret) {
+               return false;
+       }
+
+       *length = calcDimTotal(dimensions);
+       *array = (struct _st_things_representation **)util_calloc((*length), sizeof(struct _st_things_representation *));
+       if (NULL == *array) {
+               ST_LOG(ST_ERROR, "Failed to allocate memory for object array value.");
+               for (size_t index = 0; index < *length; index++) {
+                       OCPayloadDestroy((OCPayload *) children[index]);
+               }
+               util_free(children);
+               return false;
+       }
+
+       for (size_t index = 0; index < *length; index++) {
+               if (NULL == children[index]) {
+                       ST_LOG_V(ST_ERROR, "Payload at index(%d) is NULL.", index);
+               } else {
+                       (*array)[index] = create_representation_inst_internal(children[index]);
+                       if (NULL == (*array)[index]) {
+                               ST_LOG(ST_ERROR, "Failed to create a representation for object array value.");
+                       }
+               }
+
+               if (NULL == (*array)[index]) {
+                       for (size_t sub_index = 0; sub_index < index; sub_index++) {
+                               destroy_representation_inst_internal((*array)[sub_index], true);
+                       }
+                       util_free(*array);
+                       *array = NULL;
+                       *length = 0;
+
+                       for (size_t sub_index = index; sub_index < *length; sub_index++) {
+                               OCPayloadDestroy((OCPayload *) children[sub_index]);
+                       }
+                       util_free(children);
+                       return false;
+               }
+       }
+
+       util_free(children);
+       return true;
+}
+
+bool set_str_array_value(struct _st_things_representation *rep, const char *key, const char **array, size_t length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_EXPR_IS_TRUE(length < 1);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+       return OCRepPayloadSetStringArray(rep->payload, key, array, dimensions);
+}
+
+bool set_int_array_value(struct _st_things_representation *rep, const char *key, const int64_t *array, size_t length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_EXPR_IS_TRUE(length < 1);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+       return OCRepPayloadSetIntArray(rep->payload, key, array, dimensions);
+}
+
+bool set_double_array_value(struct _st_things_representation *rep, const char *key, const double *array, size_t length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_EXPR_IS_TRUE(length < 1);
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+       return OCRepPayloadSetDoubleArray(rep->payload, key, array, dimensions);
+}
+
+bool set_object_array_value(struct _st_things_representation *rep, const char *key, const struct _st_things_representation **array, size_t length)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rep);
+       RET_FALSE_IF_PARAM_IS_NULL(rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_PARAM_IS_NULL(array);
+       RET_FALSE_IF_PARAM_EXPR_IS_TRUE(length < 1);
+
+       OCRepPayload **value_payload = NULL;
+       value_payload = (OCRepPayload **) util_malloc(length * sizeof(OCRepPayload *));
+       if (NULL == value_payload) {
+               ST_LOG(ST_ERROR, "Failed to allocate memory for object array value.");
+               return false;
+       }
+
+       for (size_t i = 0; i < length; i++) {
+               if (NULL == array[i]) {
+                       ST_LOG_V(ST_ERROR, "array[%d] is NULL.", i);
+                       util_free(value_payload);
+                       return false;
+               }
+               if (NULL == array[i]->payload) {
+                       ST_LOG_V(ST_ERROR, "array[%d]->payload is NULL.", i);
+                       util_free(value_payload);
+                       return false;
+               }
+               value_payload[i] = array[i]->payload;
+       }
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+       bool res = OCRepPayloadSetPropObjectArray(rep->payload, key, (const OCRepPayload **)value_payload, dimensions);
+       util_free(value_payload);
+
+       return res;
+}
+
+st_things_representation_s *create_representation_inst_internal(OCRepPayload *payload)
+{
+       st_things_representation_s *rep = (st_things_representation_s *) util_malloc(sizeof(st_things_representation_s));
+       RET_VAL_IF_NULL(rep, "Failed to allocate memory for representation.", NULL);
+
+       rep->get_str_value = &get_str_value;
+       rep->get_bool_value = &get_bool_value;
+       rep->get_int_value = &get_int_value;
+       rep->get_double_value = &get_double_value;
+       rep->get_byte_value = &get_byte_value;
+       rep->get_object_value = &get_object_value;
+
+       rep->set_str_value = &set_str_value;
+       rep->set_bool_value = &set_bool_value;
+       rep->set_int_value = &set_int_value;
+       rep->set_double_value = &set_double_value;
+       rep->set_byte_value = &set_byte_value;
+       rep->set_object_value = &set_object_value;
+
+       rep->get_str_array_value = &get_str_array_value;
+       rep->get_int_array_value = &get_int_array_value;
+       rep->get_double_array_value = &get_double_array_value;
+       rep->get_object_array_value = &get_object_array_value;
+
+       rep->set_str_array_value = &set_str_array_value;
+       rep->set_int_array_value = &set_int_array_value;
+       rep->set_double_array_value = &set_double_array_value;
+       rep->set_object_array_value = &set_object_array_value;
+
+       if (NULL != payload) {
+               ST_LOG(ST_DEBUG, "Setting the given payload in the representation.");
+               rep->payload = payload;
+       } else {
+               ST_LOG(ST_DEBUG, "Creating a new payload and setting it in the representation.");
+               rep->payload = OCRepPayloadCreate();
+               if (NULL == rep->payload) {
+                       ST_LOG(ST_ERROR, "Failed to create payload for representation.");
+                       destroy_representation_inst_internal(rep, false);
+                       return NULL;
+               }
+       }
+
+       return rep;
+}
+
+st_things_representation_s *create_representation_inst(void)
+{
+       return create_representation_inst_internal(NULL);
+}
+
+void destroy_representation_inst_internal(st_things_representation_s *rep, bool destroy_payload)
+{
+       RET_IF_PARAM_IS_NULL(rep);
+
+       ST_LOG_V(ST_DEBUG, "Destroy payload: %s.", destroy_payload ? "Yes" : "No");
+
+       // Payload will be de-allocated for the following cases.
+       // 1. For request representations(created at this API layer).
+       // 2. For all representations created by the application.
+       // DA Stack will de-allocate the payload for other cases.
+       // 1. For response representations.
+       if (destroy_payload) {
+               OCPayloadDestroy((OCPayload *) (rep->payload));
+       }
+
+       util_free(rep);
+}
+
+void destroy_representation_inst(st_things_representation_s *rep)
+{
+       destroy_representation_inst_internal(rep, true);
+}
diff --git a/framework/src/st_things/st_things_representation.h b/framework/src/st_things/st_things_representation.h
new file mode 100644 (file)
index 0000000..68efae0
--- /dev/null
@@ -0,0 +1,37 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef __ST_THINGS_REPRESENTATION_H__
+#define __ST_THINGS_REPRESENTATION_H__
+
+#ifdef __ST_THINGS_RTOS__
+#include <st_things/st_things_types.h>
+#else
+#include "st_things_types.h"
+#endif // __ST_THINGS_RTOS__
+#include "octypes.h"
+
+st_things_representation_s* create_representation_inst(void);
+
+st_things_representation_s* create_representation_inst_internal(OCRepPayload *payload);
+
+void destroy_representation_inst(st_things_representation_s *rep);
+
+void destroy_representation_inst_internal(st_things_representation_s *rep, bool destroy_payload);
+
+#endif // __ST_THINGS_REPRESENTATION_H__
diff --git a/framework/src/st_things/st_things_request_handler.c b/framework/src/st_things/st_things_request_handler.c
new file mode 100644 (file)
index 0000000..f38125b
--- /dev/null
@@ -0,0 +1,1157 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "st_things_request_handler.h"
+#include "st_things_request_handler_collection.h"
+#include "st_things_representation.h"
+#include "st_things_util.h"
+#include "st_things_logger.h"
+
+#include "things_api.h"
+#include "octypes.h"
+#include "ocpayload.h"
+
+#define BOOL_ID 0
+#define INT_ID 1
+#define DOUBLE_ID 2
+#define STRING_ID 3
+#define OBJECT_ID 4
+#define BYTE_ID 5
+#define INT_ARRAY_ID 6
+#define DOUBLE_ARRAY_ID 7
+#define STRING_ARRAY_ID 8
+#define OBJECT_ARRAY_ID 9
+
+#define IS_READABLE(var) (1 & var)
+#define IS_WRITABLE(var) (2 & var)
+
+#define PROPERTY_KEY_DELIMITER ';'
+#define KEY_VALUE_SEPARATOR '='
+
+static st_things_get_request_cb g_handle_get_req_cb = NULL;
+static st_things_set_request_cb g_handle_set_req_cb = NULL;
+
+bool get_query_value_internal(const char *query, const char *key, char **value, bool *found)
+{
+       RET_FALSE_IF_EXPR_IS_TRUE((NULL == query || strlen(query) < 1), "Invalid query.");
+       RET_FALSE_IF_EXPR_IS_TRUE((NULL == key || strlen(key) < 1), "Invalid key.");
+       RET_FALSE_IF_PARAM_IS_NULL(value);
+
+       *value = NULL;
+       if (NULL != found) {
+               *found = false;
+       }
+
+       int query_len = strlen(query);
+       int key_len = strlen(key);
+       char *p_buff = NULL, *p_origin = NULL;
+       char *p_ptr = NULL;
+
+       p_origin = p_buff = (char *)util_malloc(query_len + 1);
+       if (NULL == p_origin) {
+               ST_LOG(ST_ERROR, "Failed to allocate memory to get a specific value from query.");
+               return false;
+       }
+
+       memset(p_buff, 0, query_len + 1);
+       memcpy(p_buff, query, query_len);
+
+       p_ptr = strtok(p_buff, QUERY_DELIMITER);
+       if (NULL == p_ptr) {
+               ST_LOG(ST_ERROR, "Failed to tokenize the query.");
+               util_free(p_origin);
+               return false;
+       }
+
+       bool res = false;
+       while (p_ptr != NULL) {
+               if (strncmp(p_ptr, key, key_len) == 0) {
+                       ST_LOG_V(ST_DEBUG, "Key(%s) exists in query parameter(%s).", key, query);
+                       if (NULL != found) {
+                               *found = true;
+                       }
+
+                       *value = util_clone_string(p_ptr + key_len + 1);
+                       if (NULL == *value) {
+                               ST_LOG(ST_ERROR, "Failed to clone the query value.");
+                               util_free(p_origin);
+                       } else {
+                               res = true;
+                       }
+                       break;
+               }
+
+               p_ptr = strtok(NULL, QUERY_DELIMITER);
+       }
+
+       if (NULL == p_ptr) {
+               ST_LOG_V(ST_DEBUG, "Key(%s) doesn't exist in query(%s).", key, query);
+       }
+
+       util_free(p_origin);
+
+       return res;
+}
+
+bool get_query_value_for_get_req(struct _st_things_get_request_message *req_msg, const char *key, char **value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg);
+       return get_query_value_internal(req_msg->query, key, value, NULL);
+}
+
+bool get_query_value_for_post_req(struct _st_things_set_request_message *req_msg, const char *key, char **value)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg);
+       return get_query_value_internal(req_msg->query, key, value, NULL);
+}
+
+bool is_property_key_exist(struct _st_things_get_request_message *req_msg, const char *key)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg);
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg->property_key);
+       RET_FALSE_IF_EXPR_IS_TRUE(strlen(req_msg->property_key) < 1, "Property key in request message is empty.");
+       RET_FALSE_IF_PARAM_IS_NULL(key);
+       RET_FALSE_IF_EXPR_IS_TRUE(strlen(key) < 1, "Key is empty.");
+
+       int key_len = strlen(key);
+       bool exist = false;
+       char *key_ptr = req_msg->property_key;
+       while (NULL != key_ptr && !exist) {
+               key_ptr = strstr(key_ptr, key);
+               if (NULL == key_ptr) {
+                       break;
+               }
+               // The following logic ensures that the key is a complete key and not a substring of another key.
+               // Check whether a delimeter immediately follows the key.
+               if (PROPERTY_KEY_DELIMITER != key_ptr[key_len]) {
+                       key_ptr += key_len;
+                       continue;
+               }
+               // If key is not at the begining, then check whether there is a delimiter immediately before the key.
+               if (key_ptr != req_msg->property_key && PROPERTY_KEY_DELIMITER != key_ptr[-1]) {
+                       key_ptr += key_len;
+                       continue;
+               }
+
+               exist = true;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Key(%s) exist?: %s.", key, exist ? "Yes" : "No");
+       return exist;
+}
+
+static bool get_resource_types(things_resource_s *rsrc, char ***res_types, int *count)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rsrc);
+       RET_FALSE_IF_PARAM_IS_NULL(res_types);
+       RET_FALSE_IF_PARAM_IS_NULL(count);
+
+       int rt_count = rsrc->things_get_num_of_res_types(rsrc);
+       ST_LOG_V(ST_DEBUG, "Resource(%s) has %d resource type(s).", rsrc->uri, rt_count);
+       RET_FALSE_IF_EXPR_IS_TRUE(rt_count < 1, "No resource types in resource.");
+
+       char **types = (char **)util_calloc(rt_count, sizeof(char *));
+       RET_FALSE_IF_NULL(types, "Failed to allocate memory for resource types.");
+
+       bool result = true;
+       const char *res_type;
+       for (int i = 0; i < rt_count; i++) {
+               res_type = rsrc->things_get_res_type(rsrc, i);
+               if (NULL == res_type || strlen(res_type) < 1) {
+                       ST_LOG_V(ST_ERROR, "Resource type at index(%d) is invalid.", i);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+
+               types[i] = util_clone_string(res_type);
+               if (NULL == types[i]) {
+                       ST_LOG_V(ST_ERROR, "Failed to clone resource type(%s).", res_type);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+       }
+
+       if (result) {
+               *count = rt_count;
+               *res_types = types;
+       }
+
+       return result;
+}
+
+static bool get_interface_types(things_resource_s *rsrc, char ***if_types, int *count)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rsrc);
+       RET_FALSE_IF_PARAM_IS_NULL(if_types);
+       RET_FALSE_IF_PARAM_IS_NULL(count);
+
+       int if_count = rsrc->things_get_num_of_inf_types(rsrc);
+       ST_LOG_V(ST_DEBUG, "Resource(%s) has %d interface type(s).", rsrc->uri, if_count);
+       RET_FALSE_IF_EXPR_IS_TRUE(if_count < 1, "No interface types in resource.");
+
+       char **types = (char **)util_calloc(if_count, sizeof(char *));
+       RET_VAL_IF_NULL(types, "Failed to allocate memory for inteface types.", false);
+
+       bool result = true;
+       const char *if_type = NULL;
+       for (int i = 0; i < if_count; i++) {
+               if_type = rsrc->things_get_inf_type(rsrc, i);
+               if (NULL == if_type || strlen(if_type) < 1) {
+                       ST_LOG_V(ST_ERROR, "Interface type at index(%d) is invalid.", i);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+
+               types[i] = util_clone_string(if_type);
+               if (NULL == types[i]) {
+                       ST_LOG_V(ST_ERROR, "Failed to clone inteface type(%s).", if_type);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+       }
+
+       if (result) {
+               *count = if_count;
+               *if_types = types;
+       }
+
+       return result;
+}
+
+ /*
+  * Adds the common properties of resource such as 'rt', 'if'.
+  * 'links' property will be added in the response payload for collection resources.
+  * If it fails for any reason, the resp_payload which is partially updated by this function will not be reset.
+  * The caller of this method will have to release the payload and return an error response to the client.
+  */
+bool add_common_props(things_resource_s *rsrc, bool collection, OCRepPayload *resp_payload)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rsrc);
+       RET_FALSE_IF_PARAM_IS_NULL(resp_payload);
+
+       // Set resource types.
+       int rt_count = 0;
+       char **res_types = NULL;
+       if (!get_resource_types(rsrc, &res_types, &rt_count)) {
+               ST_LOG_V(ST_ERROR, "Failed to get the resource types of the given resource(%s).", rsrc->uri);
+               return false;
+       }
+
+       for (int i = 0; i < rt_count; i++) {
+               if (!OCRepPayloadAddResourceTypeAsOwner(resp_payload, res_types[i])) {
+                       ST_LOG(ST_ERROR, "Failed to add the resource type in the response payload.");
+                       // Release memory allocated for resource types.
+                       util_free_str_array(res_types, rt_count);
+                       return false;
+               }
+       }
+
+       // Set interface types.
+       int if_count = 0;
+       char **if_types = NULL;
+       if (!get_interface_types(rsrc, &if_types, &if_count)) {
+               ST_LOG_V(ST_ERROR, "Failed to get the interface types of the given resource(%s).", rsrc->uri);
+               return false;
+       }
+
+       for (int i = 0; i < if_count; i++) {
+               if (!OCRepPayloadAddInterfaceAsOwner(resp_payload, if_types[i])) {
+                       ST_LOG(ST_ERROR, "Failed to add the interface type in the response payload.");
+                       // Release memory allocated for interface types.
+                       util_free_str_array(if_types, if_count);
+                       return false;
+               }
+       }
+
+       // Set "links"(only for collection).
+       if (collection) {
+               size_t count = 0;
+               OCRepPayload **links = NULL;
+               if (!form_collection_links(rsrc, &links, &count)) {
+                       ST_LOG_V(ST_ERROR, "Failed to form links for the given collection resource(%s).", rsrc->uri);
+                       return false;
+               }
+
+               ST_LOG(ST_DEBUG, "Formed links for collection.");
+               size_t dimensions[MAX_REP_ARRAY_DEPTH] = { count, 0, 0 };
+               bool result = OCRepPayloadSetPropObjectArrayAsOwner(resp_payload, OC_RSRVD_LINKS, links, dimensions);
+               if (!result) {
+                       ST_LOG(ST_ERROR, "Failed to add the links in the response payload.");
+                       for (size_t i = 0; i < count && NULL != links[i]; i++) {
+                               OCRepPayloadDestroy(links[i]);
+                       }
+                       util_free(links);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+// To get the properties of a resource based on either resource type or resource uri.
+static bool get_supported_properties(const char *res_type, const char *res_uri, int *count, things_attribute_info_s ***properties, bool *destroy_props)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(count);
+       RET_FALSE_IF_PARAM_IS_NULL(properties);
+       RET_FALSE_IF_PARAM_IS_NULL(destroy_props);
+
+       *destroy_props = false;
+
+       // Get the properties based on resource type.
+       if (NULL != res_type && strlen(res_type) > 0) {
+               int res = things_get_attributes_by_resource_type(res_type, count, properties);
+               ST_LOG_V(ST_DEBUG, "Get attributes by resource type(%s): %s.", res_type, (1 == res) ? "Success" : "Failed");
+               return res ? true : false;
+       }
+       // Get the properties based on resource uri.
+       if (NULL != res_uri && strlen(res_uri) > 0) {
+               int type_count = 0;
+               char **res_types = NULL;
+               // 1. Get the resource types.
+               if (!things_get_resource_type(res_uri, &type_count, &res_types)) {
+                       ST_LOG_V(ST_ERROR, "Failed to get the resource types based on resource uri(%s).", res_uri);
+                       return false;
+               }
+
+               if (type_count < 1 || NULL == res_types) {
+                       ST_LOG_V(ST_ERROR, "No resource types for the given resource(%s).", res_uri);
+                       return false;
+               }
+
+               ST_LOG_V(ST_DEBUG, "Resource(%s) has %d resource type(s).", res_uri, type_count);
+
+               // 2. Get the properties for each resource type.
+               int *prop_count = NULL;
+               things_attribute_info_s ***props = NULL;
+               props = (things_attribute_info_s ***) util_calloc(type_count, sizeof(things_attribute_info_s **));
+               if (NULL == props) {
+                       ST_LOG(ST_ERROR, "Failed to allocate memory for resource properties.");
+                       return false;
+               }
+               prop_count = (int *)util_calloc(type_count, sizeof(int));
+               if (NULL == props) {
+                       ST_LOG(ST_ERROR, "Failed to allocate memory for resource properties.");
+                       util_free(props);
+                       return false;
+               }
+
+               for (int index = 0; index < type_count; index++) {
+                       if (!things_get_attributes_by_resource_type(res_types[index], &prop_count[index], &props[index])) {
+                               ST_LOG_V(ST_ERROR, "Failed to get the properties of resource type (%s).", res_types[index]);
+                               util_free(prop_count);
+                               util_free(props);
+                               *count = 0;
+                               *properties = NULL;
+                               return false;
+                       }
+                       ST_LOG_V(ST_DEBUG, "Number of properties of resource type(%s): %d.", res_types[index], prop_count[index]);
+                       *count += prop_count[index];
+               }
+
+               ST_LOG_V(ST_DEBUG, "Total number of properties: %d.", *count);
+
+               *properties = (things_attribute_info_s **) util_calloc(*count, sizeof(things_attribute_info_s *));
+               if (NULL == *properties) {
+                       ST_LOG(ST_ERROR, "Failed to allocate memory for resource properties.");
+                       util_free(prop_count);
+                       util_free(props);
+                       *count = 0;
+                       return false;
+               }
+
+               int cur_index = 0;
+               for (int index = 0; index < type_count; index++) {
+                       if (NULL == props[index]) {
+                               ST_LOG_V(ST_ERROR, "Resource type(%s) doesn't have any properties.", res_types[index]);
+                               util_free(prop_count);
+                               util_free(props);
+                               *count = 0;
+                               return false;
+                       }
+
+                       for (int sub_index = 0; sub_index < prop_count[index]; sub_index++) {
+                               things_attribute_info_s *prop = *(props[index] + sub_index);
+                               if (NULL == prop) {
+                                       ST_LOG(ST_ERROR, "NULL Property.");
+                                       util_free(prop_count);
+                                       util_free(props);
+                                       *count = 0;
+                                       return false;
+                               }
+                               // If this prop is already added, then ignore it and decrement the total count by 1.
+                               bool exist = false;
+                               for (int i = 0; i < cur_index; i++) {
+                                       if (0 == strncmp(((*properties)[i])->key, prop->key, strlen(prop->key))) {
+                                               ST_LOG_V(ST_DEBUG, "Property(%s) is already added in the request message.", prop->key);
+                                               exist = true;
+                                               break;
+                                       }
+                               }
+                               if (exist) {
+                                       (*count)--;
+                               } else {
+                                       (*properties)[cur_index++] = prop;
+                               }
+                       }
+               }
+
+               *destroy_props = true;
+               util_free(prop_count);
+               util_free(props);
+       } else {
+               ST_LOG(ST_ERROR, "Resource type and URI are invalid.");
+               return false;
+       }
+
+       return true;
+}
+
+static void remove_query_parameter(char *query, char *key)
+{
+       RET_IF_EXPR_IS_TRUE((NULL == query || strlen(query) < 1), "Invalid parameter: query.");
+       RET_IF_EXPR_IS_TRUE((NULL == key || strlen(key) < 1), "Invalid parameter: key.");
+
+       int key_len = strlen(key);
+       char *pos1 = strstr(query, key);
+       if (NULL == pos1 || (KEY_VALUE_SEPARATOR != pos1[key_len])) {   // Key should exist and its next char should be '='.
+               ST_LOG(ST_ERROR, "Key doesn't exist in query.");
+               return;
+       }
+
+       char *pos2 = strstr(pos1, QUERY_DELIMITER);
+       if (NULL != pos2) {
+               pos2++;                                 // Increment the pointer to make it point the first character in the next key
+               while ((*pos1++ = *pos2++)) ;
+       } else{                                         // Given key is the last in the query.
+               if (pos1 != query) {
+                       pos1--;                         // Decrement the pointer to remove the leading query delimiter
+               }
+
+               *pos1 = '\0';
+       }
+}
+
+static void add_property_key_in_get_req_msg(st_things_get_request_message_s *req_msg, char *prop_key)
+{
+       RET_IF_PARAM_IS_NULL(req_msg);
+       RET_IF_PARAM_IS_NULL(req_msg->property_key);
+       RET_IF_PARAM_IS_NULL(prop_key);
+
+       strncat(req_msg->property_key, prop_key, strlen(prop_key));
+       int prop_len = strlen(req_msg->property_key);
+       req_msg->property_key[prop_len] = PROPERTY_KEY_DELIMITER;
+       req_msg->property_key[prop_len + 1] = '\0';
+}
+
+static bool add_property_in_post_req_msg(st_things_set_request_message_s *req_msg, OCRepPayload *req_payload, things_attribute_info_s *prop)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg);
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg->rep);
+       RET_FALSE_IF_PARAM_IS_NULL(req_msg->rep->payload);
+       RET_FALSE_IF_PARAM_IS_NULL(req_payload);
+       RET_FALSE_IF_PARAM_IS_NULL(prop);
+
+       OCRepPayload *resp_payload = req_msg->rep->payload;
+
+       ST_LOG_V(ST_DEBUG, "Property Key is %s", prop->key);
+       ST_LOG_V(ST_DEBUG, "Property type is %d", prop->type);
+
+       // Based on the property type, call appropriate methods to copy
+       // the property from request payload to request representation.
+       bool result = false;
+       switch (prop->type) {
+       case BOOL_ID:
+               {
+                       bool value = false;
+                       if (OCRepPayloadGetPropBool(req_payload, prop->key, &value)) {
+                               result = OCRepPayloadSetPropBool(resp_payload, prop->key, value);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the boolean value of '%s' in request message.", prop->key);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the boolean value of '%s' for request message.", prop->key);
+                       }
+               }
+               break;
+       case INT_ID:
+               {
+                       int64_t value = 0;
+                       if (OCRepPayloadGetPropInt(req_payload, prop->key, &value)) {
+                               result = OCRepPayloadSetPropInt(resp_payload, prop->key, value);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the integer value of '%s' in request message", prop->key);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the integer value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case DOUBLE_ID:
+               {
+                       double value = 0.0;
+                       if (OCRepPayloadGetPropDouble(req_payload, prop->key, &value)) {
+                               result = OCRepPayloadSetPropDouble(resp_payload, prop->key, value);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the double value of '%s' in request message", prop->key);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the double value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case STRING_ID:
+               {
+                       char *value = NULL;
+                       if (OCRepPayloadGetPropString(req_payload, prop->key, &value)) {
+                               result = OCRepPayloadSetPropStringAsOwner(resp_payload, prop->key, value);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the string value of '%s' in request message", prop->key);
+                                       util_free(value);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the string value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case OBJECT_ID:
+               {
+                       OCRepPayload *value = NULL;
+                       if (OCRepPayloadGetPropObject(req_payload, prop->key, &value)) {
+                               result = OCRepPayloadSetPropObjectAsOwner(resp_payload, prop->key, value);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the object value of '%s' in request message", prop->key);
+                                       OCRepPayloadDestroy(value);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the object value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case BYTE_ID:
+               {
+                       OCByteString *byte_value = (OCByteString *) util_calloc(1, sizeof(OCByteString));
+                       if (NULL == byte_value) {
+                               ST_LOG_V(ST_ERROR, "Failed to allocate memory for byte string value of '%s' in request message", prop->key);
+                               break;
+                       }
+
+                       if (OCRepPayloadGetPropByteString(req_payload, prop->key, byte_value)) {
+                               result = OCRepPayloadSetPropByteStringAsOwner(resp_payload, prop->key, byte_value);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the byte string value of '%s' in request message", prop->key);
+                                       util_free(byte_value->bytes);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the byte string value of '%s' for request message", prop->key);
+                       }
+
+                       if (!result) {
+                               util_free(byte_value);
+                       }
+               }
+               break;
+       case INT_ARRAY_ID:
+               {
+                       int64_t *value = NULL;
+                       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+                       if (OCRepPayloadGetIntArray(req_payload, prop->key, &value, dimensions)) {
+                               result = OCRepPayloadSetIntArrayAsOwner(resp_payload, prop->key, value, dimensions);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the integer array value of '%s' in request message", prop->key);
+                                       util_free(value);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the integer array value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case DOUBLE_ARRAY_ID:
+               {
+                       double *value = NULL;
+                       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+                       if (OCRepPayloadGetDoubleArray(req_payload, prop->key, &value, dimensions)) {
+                               result = OCRepPayloadSetDoubleArrayAsOwner(resp_payload, prop->key, value, dimensions);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the double array value of '%s' in request message", prop->key);
+                                       util_free(value);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the double array value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case STRING_ARRAY_ID:
+               {
+                       char **value = NULL;
+                       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+                       if (OCRepPayloadGetStringArray(req_payload, prop->key, &value, dimensions)) {
+                               result = OCRepPayloadSetStringArrayAsOwner(resp_payload, prop->key, value, dimensions);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the string array value of '%s' in request message", prop->key);
+                                       size_t len = calcDimTotal(dimensions);
+                                       util_free_str_array(value, len);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the string array value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       case OBJECT_ARRAY_ID:
+               {
+                       OCRepPayload **value = NULL;
+                       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+                       if (OCRepPayloadGetPropObjectArray(req_payload, prop->key, &value, dimensions)) {
+                               result = OCRepPayloadSetPropObjectArrayAsOwner(resp_payload, prop->key, value, dimensions);
+                               if (!result) {
+                                       ST_LOG_V(ST_ERROR, "Failed to set the object array value of '%s' in request message", prop->key);
+                                       size_t len = calcDimTotal(dimensions);
+                                       for (size_t index = 0; index < len; index++) {
+                                               OCRepPayloadDestroy(value[index]);
+                                       }
+                                       util_free(value);
+                               }
+                       } else {
+                               ST_LOG_V(ST_ERROR, "Failed to get the object array value of '%s' for request message", prop->key);
+                       }
+               }
+               break;
+       default:
+               ST_LOG_V(ST_ERROR, "Invalid property type (%d).", prop->type);
+               break;
+       }
+
+       return result;
+}
+
+static void destroy_req_msg_inst_for_get(st_things_get_request_message_s *req_msg)
+{
+       RET_IF_PARAM_IS_NULL(req_msg);
+
+       util_free(req_msg->resource_uri);
+       util_free(req_msg->query);
+       util_free(req_msg->property_key);
+
+       req_msg->query = NULL;
+       req_msg->resource_uri = NULL;
+       req_msg->property_key = NULL;
+       req_msg->get_query_value = NULL;
+       req_msg->has_property_key = NULL;
+
+       util_free(req_msg);
+}
+
+static void destroy_req_msg_inst_for_post(st_things_set_request_message_s *req_msg, bool destroy_payload)
+{
+       RET_IF_PARAM_IS_NULL(req_msg);
+
+       util_free(req_msg->resource_uri);
+       util_free(req_msg->query);
+
+       if (NULL != req_msg->rep) {
+               destroy_representation_inst_internal(req_msg->rep, destroy_payload);
+       }
+
+       req_msg->resource_uri = NULL;
+       req_msg->query = NULL;
+       req_msg->rep = NULL;
+       req_msg->get_query_value = NULL;
+
+       util_free(req_msg);
+}
+
+static st_things_get_request_message_s *create_req_msg_inst_for_get(const char *res_uri, const char *query)
+{
+       st_things_get_request_message_s *req_msg = (st_things_get_request_message_s *) util_malloc(sizeof(st_things_get_request_message_s));
+       RET_VAL_IF_NULL(req_msg, "Failed to allocate memory for GET request message.", NULL);
+
+       req_msg->resource_uri = util_clone_string(res_uri);
+       RET_VAL_IF_NULL(req_msg->resource_uri, "Failed to clone the resource uri.", NULL);
+
+       if (NULL != query && strlen(query) > 1) {
+               req_msg->query = util_clone_string(query);
+       } else {
+               req_msg->query = NULL;
+       }
+       req_msg->property_key = NULL;
+       req_msg->get_query_value = &get_query_value_for_get_req;
+       req_msg->has_property_key = &is_property_key_exist;
+       return req_msg;
+}
+
+static st_things_set_request_message_s *create_req_msg_inst_for_post(const char *res_uri, const char *query, OCRepPayload *req_payload)
+{
+       st_things_set_request_message_s *req_msg = (st_things_set_request_message_s *) util_malloc(sizeof(st_things_set_request_message_s));
+       RET_VAL_IF_NULL(req_msg, "Failed to allocate memory for SET request message.", NULL);
+
+       req_msg->resource_uri = util_clone_string(res_uri);
+       RET_VAL_IF_NULL(req_msg->resource_uri, "Failed to clone the resource uri.", NULL);
+
+       if (NULL != query && strlen(query) > 1) {
+               req_msg->query = util_clone_string(query);
+       } else {
+               req_msg->query = NULL;
+       }
+
+       req_msg->rep = create_representation_inst_internal(req_payload);
+       if (NULL == req_msg->rep) {
+               ST_LOG(ST_ERROR, "Failed to create representation for SET request message.");
+               destroy_req_msg_inst_for_post(req_msg, false);
+               return NULL;
+       }
+
+       req_msg->get_query_value = &get_query_value_for_post_req;
+       return req_msg;
+}
+
+ /*
+  * Helper method to get the response from application for GET requests.
+  * The 'resp_payload' parameter will be used to get the response.
+  * Common properties of the resource such as rt, if and links will not be set by this method.
+  */
+bool handle_get_req_helper(const char *res_uri, const char *query, OCRepPayload *resp_payload)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(resp_payload);
+       RET_FALSE_IF_NULL(g_handle_get_req_cb, "Request callback for GET is NULL.");
+
+       // Setup the request message.
+       st_things_get_request_message_s *req_msg = create_req_msg_inst_for_get(res_uri, query);
+       RET_FALSE_IF_NULL(req_msg, "Failed to create request message for GET.");
+
+       /* Based on the resource type of the request (specified in the query parameters like rt=oic.r.switch.binary) and
+          interface type in the query parameter, add proper set of property keys in the request message.
+          Application's response representation should include
+          only those properties which are present in the request message. */
+       char *res_type = NULL;
+       int count = 0;
+       bool destroy_props = false;
+       struct things_attribute_info_s **properties = NULL;
+
+       // Get resource type from query parameter
+       if (NULL != query && strlen(query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(query, OC_RSRVD_RESOURCE_TYPE, &res_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the resource type from query parameter(%s).", query);
+                       destroy_req_msg_inst_for_get(req_msg);
+                       return false;
+               }
+       }
+       // Get supported set of properties based on resource type query parameter.
+       // If resource type is not available, then get the properties based on resource uri.
+       bool res = get_supported_properties(res_type, res_uri, &count, &properties, &destroy_props);
+       if (!res) {
+               ST_LOG(ST_ERROR, "Failed to get the resource properties based on its type or uri.");
+               destroy_req_msg_inst_for_get(req_msg);
+               util_free(res_type);
+               return false;
+       }
+       // Calculate the length of all property keys
+       int total_length_of_prop_keys = 0;
+       for (int index = 0; index < count; index++) {
+               if (NULL != properties[index]) {
+                       total_length_of_prop_keys += strlen(properties[index]->key);
+               }
+       }
+       total_length_of_prop_keys += count;     // For delimiter
+       total_length_of_prop_keys += 1; // For null character
+
+       // Allocate memory for holding property keys with delimiters
+       req_msg->property_key = (char *)util_calloc(total_length_of_prop_keys, sizeof(char));
+       if (!req_msg->property_key) {
+               ST_LOG(ST_ERROR, "Failed to allocate memory for property key in GET request message.");
+               if (destroy_props) {
+                       util_free(properties);
+               }
+               destroy_req_msg_inst_for_get(req_msg);
+               util_free(res_type);
+               return false;
+       }
+       // Get interface type from query parameter.
+       char *if_type = NULL;
+       if (NULL != query && strlen(query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(query, OC_RSRVD_INTERFACE, &if_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the interface type from query parameter(%s).", query);
+                       if (destroy_props) {
+                               util_free(properties);
+                       }
+                       destroy_req_msg_inst_for_get(req_msg);
+                       util_free(res_type);
+                       return false;
+               }
+       }
+
+       bool handled = false;
+       if (NULL != if_type && strlen(if_type) > 0) {
+               ST_LOG_V(ST_DEBUG, "Interface type is (%s).", if_type);
+               if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_READ, strlen(OC_RSRVD_INTERFACE_READ))) {
+                       // Add all the attributes which are readable.
+                       for (int index = 0; index < count; index++) {
+                               if (NULL != properties[index] && IS_READABLE(properties[index]->rw)) {
+                                       add_property_key_in_get_req_msg(req_msg, properties[index]->key);
+                               }
+                       }
+                       handled = true;
+               } else if (0 == strncmp(if_type, ST_THINGS_RSRVD_INTERFACE_READWRITE, strlen(ST_THINGS_RSRVD_INTERFACE_READWRITE))) {
+                       // Add all the attributes which are readable and writable.
+                       for (int index = 0; index < count; index++) {
+                               if (NULL != properties[index] && IS_READABLE(properties[index]->rw) && IS_WRITABLE(properties[index]->rw)) {
+                                       add_property_key_in_get_req_msg(req_msg, properties[index]->key);
+                               }
+                       }
+                       handled = true;
+               }
+       }
+
+       if (!handled) {                         // For all other cases, add all the property keys.
+               for (int index = 0; index < count; index++) {
+                       if (NULL != properties[index]) {
+                               add_property_key_in_get_req_msg(req_msg, properties[index]->key);
+                       }
+               }
+       }
+       // Remove 'rt' and 'if' from query parameters
+       if (NULL != query && strlen(query) > 0) {
+               remove_query_parameter(req_msg->query, OC_RSRVD_RESOURCE_TYPE);
+               remove_query_parameter(req_msg->query, OC_RSRVD_INTERFACE);
+       }
+       // Setup the response representation for application. This representation will be handed over to the application.
+       st_things_representation_s *things_resp_rep = create_representation_inst_internal(resp_payload);
+       if (NULL != things_resp_rep) {
+               res = g_handle_get_req_cb(req_msg, things_resp_rep);
+               ST_LOG_V(ST_DEBUG, "The result of application's callback : %s.", res ? "true" : "false");
+               destroy_representation_inst_internal(things_resp_rep, false);
+       } else {
+               ST_LOG(ST_ERROR, "Failed to create response representation.");
+               res = false;
+       }
+
+       destroy_req_msg_inst_for_get(req_msg);
+       if (destroy_props) {
+               util_free(properties);
+       }
+       util_free(res_type);
+       util_free(if_type);
+
+       return res;
+}
+
+static int handle_get_req_on_single_rsrc(things_resource_s *single_rsrc)
+{
+       RET_VAL_IF_PARAM_IS_NULL(single_rsrc, 0);
+
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_VAL_IF_NULL(resp_rep, "Failed to create response representation.", 0);
+
+       bool result = OCRepPayloadSetUri(resp_rep->payload, single_rsrc->uri);
+       if (!result) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", single_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return 0;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource uri(%s) is set in the response payload.", single_rsrc->uri);
+
+       // Set the common properties in the payload (Only for baseline interface).
+       char *if_type = NULL;
+       if (NULL != single_rsrc->query && strlen(single_rsrc->query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(single_rsrc->query, OC_RSRVD_INTERFACE, &if_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the interface type from query parameter(%s).", single_rsrc->query);
+                       things_release_representation_inst(resp_rep);
+                       return 0;
+               }
+       }
+
+       if (NULL == if_type || strlen(if_type) < 1 || !strncmp(if_type, OC_RSRVD_INTERFACE_DEFAULT, strlen(OC_RSRVD_INTERFACE_DEFAULT))) {
+               if (!add_common_props(single_rsrc, false, resp_rep->payload)) {
+                       ST_LOG(ST_ERROR, "Failed to add the common properties in response payload.");
+                       things_release_representation_inst(resp_rep);
+                       util_free(if_type);
+                       return 0;
+               }
+               ST_LOG(ST_DEBUG, "Added common properties in response payload.");
+       }
+       // Get the resource's properties from the application.
+       result = handle_get_req_helper(single_rsrc->uri, single_rsrc->query, resp_rep->payload);
+       if (!result) {
+               things_release_representation_inst(resp_rep);
+               util_free(if_type);
+               return 0;
+       }
+       // Set the response representation in the resource.
+       single_rsrc->things_set_representation(single_rsrc, resp_rep);
+
+       util_free(if_type);
+       return 1;
+}
+
+ /*
+  * Helper method to get the response from application for POST requests.
+  * The 'resp_payload' parameter will be used to get the response.
+  * Common properties of the resource such as rt, if and links will not be set by this method.
+  */
+bool handle_post_req_helper(const char *res_uri, const char *query, OCRepPayload *req_payload, OCRepPayload *resp_payload)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(req_payload);
+       RET_FALSE_IF_PARAM_IS_NULL(resp_payload);
+       RET_FALSE_IF_NULL(g_handle_set_req_cb, "Request callback for SET is NULL.");
+
+       // Setup the response representation for application. This representation will be handed over to the application.
+       st_things_representation_s *things_resp_rep = create_representation_inst_internal(resp_payload);
+       RET_FALSE_IF_NULL(things_resp_rep, "Failed to create response representation.");
+
+       // Setup the request message.
+       st_things_set_request_message_s *req_msg = create_req_msg_inst_for_post(res_uri, query, NULL);
+       if (NULL == req_msg) {
+               ST_LOG(ST_ERROR, "Failed to create the request message for SET.");
+               destroy_representation_inst_internal(things_resp_rep, false);
+               return false;
+       }
+
+       /* Based on the resource type of the request (specified in the query parameters like rt=oic.r.switch.binary) and
+          interface type in the query parameter, add proper set of properties in the request representation.
+          Application's response representation should include
+          only the properties present in the request representation. */
+
+       char *res_type = NULL;
+       int count = 0;
+       bool destroy_props = false;
+       struct things_attribute_info_s **properties = NULL;
+
+       // Get resource type from query parameter
+       if (NULL != query && strlen(query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(query, OC_RSRVD_RESOURCE_TYPE, &res_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the resource type from query parameter(%s).", query);
+                       destroy_representation_inst_internal(things_resp_rep, false);
+                       destroy_req_msg_inst_for_post(req_msg, true);
+                       return false;
+               }
+       }
+       // Get necessary set of properties.
+       bool res = get_supported_properties(res_type, res_uri, &count, &properties, &destroy_props);
+       if (!res) {
+               ST_LOG(ST_ERROR, "Failed to get the resource properties based on its type or uri.");
+               destroy_representation_inst_internal(things_resp_rep, false);
+               destroy_req_msg_inst_for_post(req_msg, true);
+               util_free(res_type);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Total number of supported properties: %d.", count);
+
+       res = true;
+       // Check whether the request has all mandatory properties.
+       for (int index = 0; index < count; index++) {
+               if (NULL == properties[index]) {
+                       ST_LOG_V(ST_ERROR, "Property at index(%d) is NULL.", index);
+                       res = false;
+                       break;
+               }
+
+               if (properties[index]->mandatory) {
+                       if (OCRepPayloadIsNull(req_payload, properties[index]->key)) {
+                               ST_LOG_V(ST_ERROR, "Mandatory property (%s) is not present in the request.", properties[index]->key);
+                               res = false;
+                               break;
+                       }
+               }
+       }
+
+       if (!res) {
+               if (destroy_props) {
+                       util_free(properties);
+               }
+               destroy_representation_inst_internal(things_resp_rep, false);
+               destroy_req_msg_inst_for_post(req_msg, true);
+               util_free(res_type);
+               return false;
+       }
+
+       for (int index = 0; index < count; index++) {
+               if (NULL != properties[index] && IS_WRITABLE(properties[index]->rw)) {
+                       res = add_property_in_post_req_msg(req_msg, req_payload, properties[index]);
+                       if (!res) {
+                               break;
+                       }
+               }
+       }
+
+       if (res) {
+               // Remove 'rt' and 'if' from query parameters.
+               remove_query_parameter(req_msg->query, OC_RSRVD_RESOURCE_TYPE);
+               remove_query_parameter(req_msg->query, OC_RSRVD_INTERFACE);
+
+               res = g_handle_set_req_cb(req_msg, things_resp_rep);
+               ST_LOG_V(ST_DEBUG, "The result of application's callback : %s", res ? "true" : "false");
+       } else {
+               ST_LOG(ST_ERROR, "Failed to add properties in request message.");
+       }
+
+       if (destroy_props) {
+               util_free(properties);
+       }
+       destroy_req_msg_inst_for_post(req_msg, true);
+       destroy_representation_inst_internal(things_resp_rep, false);
+       util_free(res_type);
+       return true;
+}
+
+static int handle_post_req_on_single_rsrc(things_resource_s *single_rsrc)
+{
+       RET_VAL_IF_PARAM_IS_NULL(single_rsrc, 0);
+
+       // Retrieve the request representation. This representation will hold all the input properties of post request.
+       // Payload in this representation will be used to form the request message which will be given to the application.
+       struct things_representation_s *req_rep = NULL;
+       bool rep_exist = single_rsrc->things_get_representation(single_rsrc, &req_rep);
+       if (!rep_exist || NULL == req_rep || NULL == req_rep->payload) {
+               ST_LOG(ST_ERROR, "Empty payload in POST request.");
+               return 0;                               // TODO: When a post request comes with empty payload, how do we handle?
+       }
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       // The payload which is passed as a parameter will be updated with the common properties.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_VAL_IF_NULL(resp_rep, "Failed to create response representation.", 0);
+
+       if (!OCRepPayloadSetUri(resp_rep->payload, single_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", single_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return 0;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource uri(%s) is set in the response payload.", single_rsrc->uri);
+
+       // Get interface type from query parameter
+       char *if_type = NULL;
+       if (NULL != single_rsrc->query && strlen(single_rsrc->query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(single_rsrc->query, OC_RSRVD_INTERFACE, &if_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the interface type from query parameter(%s).", single_rsrc->query);
+                       things_release_representation_inst(resp_rep);
+                       return 0;
+               }
+       }
+       // Set the common properties in the payload (Only for baseline interface).
+       // The payload which is passed as a parameter will be updated with the common properties.
+       if (NULL == if_type || !strncmp(if_type, OC_RSRVD_INTERFACE_DEFAULT, strlen(OC_RSRVD_INTERFACE_DEFAULT))) {
+               if (!add_common_props(single_rsrc, false, resp_rep->payload)) {
+                       ST_LOG(ST_ERROR, "Failed to add the common properties in response payload.");
+                       things_release_representation_inst(resp_rep);
+                       util_free(if_type);
+                       return 0;
+               }
+               ST_LOG(ST_DEBUG, "Added common properties in response payload.");
+       }
+       // Give the request properties to application and get the response back.
+       bool res = handle_post_req_helper(single_rsrc->uri, single_rsrc->query, req_rep->payload, resp_rep->payload);
+       if (res) {
+               // Set the response representation in the resource.
+               single_rsrc->things_set_representation(single_rsrc, resp_rep);
+       } else {
+               things_release_representation_inst(resp_rep);
+       }
+       util_free(if_type);
+       return res ? 1 : 0;
+}
+
+int handle_get_request_cb(struct things_resource_s *resource)
+{
+       ST_LOG(ST_DEBUG, "Received a GET request callback");
+
+       RET_VAL_IF_PARAM_IS_NULL(resource, 0);
+       RET_VAL_IF_NULL(g_handle_get_req_cb, "Request callback for GET is NULL.", 0);
+       RET_VAL_IF_EXPR_IS_TRUE((NULL == resource->uri || strlen(resource->uri) < 1), "Resource URI is invalid", 0);
+
+       int result = 0;
+       bool collection = things_is_collection_resource(resource->uri);
+
+       ST_LOG_V(ST_DEBUG, "Resource URI : %s (%s resource)", resource->uri, collection ? "collection" : "single");
+       ST_LOG_V(ST_DEBUG, "Query Parameter: %s", resource->query);
+
+       if (collection) {
+               result = handle_get_req_on_collection_rsrc(resource);
+       } else {
+               result = handle_get_req_on_single_rsrc(resource);
+       }
+
+       if (result) {
+               ST_LOG_V(ST_DEBUG, "Handled GET request for %s resource successfully.", collection ? "collection" : "single");
+       } else {
+               ST_LOG_V(ST_DEBUG, "Failed to handle the GET request for %s resource.", collection ? "collection" : "single");
+       }
+
+       return result;
+}
+
+int handle_set_request_cb(struct things_resource_s *resource)
+{
+       ST_LOG(ST_DEBUG, "Received a SET request callback");
+
+       RET_VAL_IF_PARAM_IS_NULL(resource, 0);
+       RET_VAL_IF_NULL(g_handle_set_req_cb, "Request callback for SET is NULL", 0);
+       RET_VAL_IF_EXPR_IS_TRUE((NULL == resource->uri || strlen(resource->uri) < 1), "Resource URI is invalid", 0);
+
+       int result = 0;
+       bool collection = things_is_collection_resource(resource->uri);
+
+       ST_LOG_V(ST_DEBUG, "Resource URI : %s (%s resource)", resource->uri, collection ? "collection" : "single");
+       ST_LOG_V(ST_DEBUG, "Query Parameter: %s", resource->query);
+
+       if (collection) {
+               result = handle_post_req_on_collection_rsrc(resource);
+       } else {
+               result = handle_post_req_on_single_rsrc(resource);
+       }
+
+       if (result) {
+               ST_LOG_V(ST_DEBUG, "Handled SET request for %s resource successfully.", collection ? "collection" : "single");
+       } else {
+               ST_LOG_V(ST_DEBUG, "Failed to handle the SET request for %s resource.", collection ? "collection" : "single");
+       }
+
+       return result;
+}
+
+int register_request_handler_cb(st_things_get_request_cb get_cb, st_things_set_request_cb set_cb)
+{
+       if (NULL == get_cb) {
+               ST_LOG(ST_ERROR, "Request callback for GET is NULL.");
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == set_cb) {
+               ST_LOG(ST_ERROR, "Request callback for SET is NULL.");
+               return ST_THINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       g_handle_get_req_cb = get_cb;
+       g_handle_set_req_cb = set_cb;
+
+       return ST_THINGS_ERROR_NONE;
+}
diff --git a/framework/src/st_things/st_things_request_handler.h b/framework/src/st_things/st_things_request_handler.h
new file mode 100644 (file)
index 0000000..f25bb88
--- /dev/null
@@ -0,0 +1,48 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef __ST_THINGS_REQUEST_HANDLER_H__
+#define __ST_THINGS_REQUEST_HANDLER_H__
+
+#ifdef __ST_THINGS_RTOS__
+#include <st_things/st_things.h>
+#else
+#include "st_things.h"
+#endif                                                 // __ST_THINGS_RTOS__
+#include "things_resource.h"
+#include "octypes.h"
+
+#define ST_THINGS_RSRVD_INTERFACE_READWRITE "oic.if.rw"
+#define ST_THINGS_RSRVD_INTERFACE_SENSOR "oic.if.s"
+#define ST_THINGS_RSRVD_INTERFACE_ACTUATOR "oic.if.a"
+
+bool get_query_value_internal(const char *query, const char *key, char **value, bool *found);
+
+bool add_common_props(things_resource_s *rsrc, bool collection, OCRepPayload *resp_payload);
+
+bool handle_get_req_helper(const char *res_uri, const char *query, OCRepPayload *resp_payload);
+
+bool handle_post_req_helper(const char *res_uri, const char *query, OCRepPayload *req_payload, OCRepPayload *resp_payload);
+
+int handle_get_request_cb(struct things_resource_s *resource);
+
+int handle_set_request_cb(struct things_resource_s *resource);
+
+int register_request_handler_cb(st_things_get_request_cb get_cb, st_things_set_request_cb set_cb);
+
+#endif                                                 // __ST_THINGS_REQUEST_HANDLER_H__
diff --git a/framework/src/st_things/st_things_request_handler_collection.c b/framework/src/st_things/st_things_request_handler_collection.c
new file mode 100644 (file)
index 0000000..8589b9a
--- /dev/null
@@ -0,0 +1,1065 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "st_things_request_handler_collection.h"
+#include "st_things_request_handler.h"
+#include "st_things_logger.h"
+#include "st_things_util.h"
+
+#include "things_api.h"
+#include "ocpayload.h"
+
+static bool get_resource_types2(things_resource_info_s * rsrc, char ***res_types, int *count)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rsrc);
+       RET_FALSE_IF_PARAM_IS_NULL(res_types);
+       RET_FALSE_IF_PARAM_IS_NULL(count);
+
+       int rt_count = rsrc->rt_cnt;
+       ST_LOG_V(ST_DEBUG, "Resource(%s) has %d resource type(s).", rsrc->uri, rt_count);
+       RET_FALSE_IF_EXPR_IS_TRUE(rt_count < 1, "No resource types in resource.");
+
+       char **types = (char **)util_calloc(rt_count, sizeof(char *));
+       RET_VAL_IF_NULL(types, "Failed to allocate memory for resource types.", false);
+
+       bool result = true;
+       const char *res_type = NULL;
+       for (int i = 0; i < rt_count; i++) {
+               res_type = rsrc->resource_types[i];
+               if (NULL == res_type || strlen(res_type) < 1) {
+                       ST_LOG_V(ST_ERROR, "Resource type at index(%d) is invalid.", i);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+
+               types[i] = util_clone_string(res_type);
+               if (NULL == types[i]) {
+                       ST_LOG_V(ST_ERROR, "Failed to clone resource type(%s).", res_type);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+       }
+
+       if (result) {
+               *count = rt_count;
+               *res_types = types;
+       }
+
+       return result;
+}
+
+static bool get_interface_types2(things_resource_info_s *rsrc, char ***if_types, int *count)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(rsrc);
+       RET_FALSE_IF_PARAM_IS_NULL(if_types);
+       RET_FALSE_IF_PARAM_IS_NULL(count);
+
+       int if_count = rsrc->if_cnt;
+       ST_LOG_V(ST_DEBUG, "Resource(%s) has %d interface type(s).", rsrc->uri, if_count);
+       RET_FALSE_IF_EXPR_IS_TRUE(if_count < 1, "No interface types in resource.");
+
+       char **types = (char **)util_calloc(if_count, sizeof(char *));
+       RET_VAL_IF_NULL(types, "Failed to allocate memory for inteface types.", false);
+
+       bool result = true;
+       const char *if_type = NULL;
+       for (int i = 0; i < if_count; i++) {
+               if_type = rsrc->interface_types[i];
+               if (NULL == if_type || strlen(if_type) < 1) {
+                       ST_LOG_V(ST_ERROR, "Interface type at index(%d) is invalid.", i);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+
+               types[i] = util_clone_string(if_type);
+               if (NULL == types[i]) {
+                       ST_LOG_V(ST_ERROR, "Failed to clone inteface type(%s).", if_type);
+                       util_free_str_array(types, i);
+                       result = false;
+                       break;
+               }
+       }
+
+       if (result) {
+               *count = if_count;
+               *if_types = types;
+       }
+
+       return result;
+}
+
+ /*
+  * Sample format of "links" representation:-
+  *   [
+  *       {
+  *           "href": , // Resource URI
+  *           "rt": [],
+  *           "if": []
+  *       },
+  *       {
+  *           "href": , // Resource URI
+  *           "rt": [],
+  *           "if": []
+  *       }
+  *   ]
+  */
+bool form_collection_links(things_resource_s *collection_rsrc, OCRepPayload ***links, size_t *count)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+       RET_FALSE_IF_PARAM_IS_NULL(links);
+       RET_FALSE_IF_PARAM_IS_NULL(count);
+
+       int num_of_children = 0;
+       things_resource_info_s **children = NULL;
+       if (!things_get_child_resources(collection_rsrc->uri, &num_of_children, &children)) {
+               ST_LOG_V(ST_ERROR, "Failed to get child resources of collection resource(%s).", collection_rsrc->uri);
+               return false;
+       }
+
+       if (0 == num_of_children || NULL == children) {
+               ST_LOG_V(ST_ERROR, "Collection resource(%s) has no children.", collection_rsrc->uri);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Collection resource(%s) has %d children.", collection_rsrc->uri, num_of_children);
+
+       // Allocate memory for the "links" in the response payload.
+       OCRepPayload **link_arr = (OCRepPayload **) util_calloc(num_of_children, sizeof(OCRepPayload *));
+       if (NULL == link_arr) {
+               ST_LOG(ST_ERROR, "Failed to allocate memory for links in collection.");
+               return false;
+       }
+
+       bool result = true;
+       int rt_count = 0;
+       int if_count = 0;
+       char **res_types = NULL;
+       char **if_types = NULL;
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
+       for (int index = 0; index < num_of_children; index++) {
+               if (NULL == children[index]->uri || strlen(children[index]->uri)) {
+                       ST_LOG_V(ST_ERROR, "Resource URI of child resource at index(%d) is invalid.", index);
+                       result = false;
+                       break;
+               }
+
+               link_arr[index] = OCRepPayloadCreate();
+               if (NULL == link_arr[index]) {
+                       ST_LOG(ST_ERROR, "Failed to allocate memory for links in collection.");
+                       result = false;
+                       break;
+               }
+               // Set the resource URI.
+               if (!OCRepPayloadSetPropString(link_arr[index], OC_RSRVD_HREF, children[index]->uri)) {
+                       ST_LOG_V(ST_ERROR, "Failed to set the URI of child(%s) for links in collection(%s).", children[index]->uri, collection_rsrc->uri);
+                       result = false;
+                       break;
+               }
+
+               ST_LOG_V(ST_DEBUG, "Child resource uri(%s) is set in the response payload.", children[index]->uri);
+
+               // Set the resource types.
+               if (!get_resource_types2(children[index], &res_types, &rt_count)) {
+                       ST_LOG_V(ST_ERROR, "Failed to get the resource types of a child(%s) for links in collection.", children[index]->uri);
+                       result = false;
+                       break;
+               }
+               dimensions[0] = rt_count;
+               result = OCRepPayloadSetStringArrayAsOwner(link_arr[index], OC_RSRVD_RESOURCE_TYPE, res_types, dimensions);
+               if (!result) {
+                       ST_LOG_V(ST_ERROR, "Failed to set the resource types of child(%s) for links in collection.", children[index]->uri);
+                       result = false;
+                       break;
+               }
+               res_types = NULL;
+
+               ST_LOG_V(ST_DEBUG, "Resource types of child resource(%s) are set in the response payload.", children[index]->uri);
+
+               // Set the interface types.
+               if (!get_interface_types2(children[index], &if_types, &if_count)) {
+                       ST_LOG_V(ST_ERROR, "Failed to get the interface types of child(%s) for links in collection.", children[index]->uri);
+                       result = false;
+                       break;
+               }
+               dimensions[0] = if_count;
+               result = OCRepPayloadSetStringArrayAsOwner(link_arr[index], OC_RSRVD_INTERFACE, if_types, dimensions);
+               if (!result) {
+                       ST_LOG_V(ST_ERROR, "Failed to set the interface types of child(%s) for links in collection.", children[index]->uri);
+                       result = false;
+                       break;
+               }
+               if_types = NULL;
+
+               ST_LOG_V(ST_DEBUG, "Interface types of child resource(%s) are set in the response payload.", children[index]->uri);
+       }
+
+       if (result) {
+               *count = num_of_children;
+               *links = link_arr;
+       } else {
+               // Release memory allocated for resource types.
+               if (res_types != NULL) {
+                       util_free_str_array(res_types, rt_count);
+               }
+               // Release memory allocated for interface types.
+               if (if_types != NULL) {
+                       util_free_str_array(if_types, if_count);
+               }
+
+               for (int i = 0; i < num_of_children && NULL != link_arr[i]; i++) {
+                       OCRepPayloadDestroy(link_arr[i]);
+               }
+               util_free(link_arr);
+
+               *count = 0;
+               *links = NULL;
+       }
+
+       return result;
+}
+
+ /*
+  * Response for links list can directly be sent without dependency on application
+  * because the response will include only the common properties of all the child resources.
+  *
+  * Sample response representation:-
+  *
+  *   {
+  *       // Child resources' common properties
+  *       "links":
+  *       [
+  *           {
+  *               "href": , // Resource URI
+  *               "rt": [],
+  *               "if": []
+  *           },
+  *           {
+  *               "href": , // Resource URI
+  *               "rt": [],
+  *               "if": []
+  *           }
+  *       ]
+  *   }
+  */
+static bool handle_get_req_on_collection_linkslist(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *payload = resp_rep->payload;
+       if (NULL == payload) {
+               ST_LOG(ST_ERROR, "Payload in response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Get the "links".
+       size_t count = 0;
+       OCRepPayload **links = NULL;
+       bool result = false;
+       if (form_collection_links(collection_rsrc, &links, &count)) {
+               size_t dimensions[MAX_REP_ARRAY_DEPTH] = { count, 0, 0 };
+               result = OCRepPayloadSetPropObjectArrayAsOwner(payload, OC_RSRVD_LINKS, links, dimensions);
+               if (!result) {
+                       ST_LOG(ST_ERROR, "Failed to add the links in the response payload.");
+                       for (size_t i = 0; i < count && NULL != links[i]; i++) {
+                               OCRepPayloadDestroy(links[i]);
+                       }
+                       util_free(links);
+               }
+       } else {
+               ST_LOG(ST_ERROR, "Failed to form links for collection.");
+       }
+
+       if (result) {
+               collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+       } else {
+               things_release_representation_inst(resp_rep);
+       }
+
+       return result;
+}
+
+ /*
+  * Sample response representation:-
+  *
+  *   {
+  *       "href": ,
+  *
+  *       // Collection resource's common properties
+  *       "rt":[],
+  *       "if":[],
+  *       "links":
+  *       [
+  *           {
+  *               "href": , // Resource URI
+  *               "rt": [],
+  *               "if": []
+  *           },
+  *           {
+  *               "href": , // Resource URI
+  *               "rt": [],
+  *               "if": []
+  *           }
+  *       ]
+  *
+  *       // Collection resource's properties
+  *       "ps":,
+  *       "lec":,
+  *   }
+  */
+static bool handle_get_req_on_collection_baseline(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *resp_payload = resp_rep->payload;
+       if (NULL == resp_payload) {
+               ST_LOG(ST_ERROR, "Payload in response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Set collection resource's URI.
+       if (!OCRepPayloadSetUri(resp_payload, collection_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", collection_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource URI(%s) is set in the response payload.", collection_rsrc->uri);
+
+       // Set collection resource's common properties (rt, if & links).
+       bool result = add_common_props(collection_rsrc, true, resp_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to add the common properties in response representation.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG(ST_DEBUG, "Common properties are added in the response payload.");
+
+       // Get the properties of the collection resource from application.
+       result = handle_get_req_helper(collection_rsrc->uri, collection_rsrc->query, resp_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to get the resource properties from application.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+
+       return true;
+}
+
+ /*
+  * Linked list of payload(OCRepPayload) of each and every resources.
+  * First object in the payload is collection resource.
+  *
+  * Sample response representation:-
+  *
+  *   {
+  *       "href": ,
+  *       "rep":
+  *       {
+  *           // Collection resource's common properties
+  *           "rt":[],
+  *           "if":[],
+  *           "links":[],
+  *
+  *           // Collection resource's properties
+  *           "ps":,
+  *           "lec":,
+  *       }
+  *   },
+  *   {
+  *       "href": ,
+  *       "rep":
+  *       {
+  *           // Child resource's common properties
+  *           "rt":[],
+  *           "if":[],
+  *
+  *           // Child resource's properties
+  *           "prop1":,
+  *           "prop2":,
+  *       }
+  *   }
+  */
+static bool handle_get_req_on_collection_batch(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *payload_head = resp_rep->payload;
+       if (NULL == payload_head) {
+               ST_LOG(ST_ERROR, "Payload in response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Handle collection resource.
+       // Set collection resource's URI.
+       if (!OCRepPayloadSetUri(payload_head, collection_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", collection_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource URI(%s) is set in the response payload.", collection_rsrc->uri);
+
+       OCRepPayload *rep_payload = OCRepPayloadCreate();
+       if (NULL == rep_payload) {
+               ST_LOG(ST_ERROR, "Failed to create response payload for 'rep'.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Set collection resource's common properties (rt, if & links).
+       bool result = add_common_props(collection_rsrc, true, rep_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to add collection's common properties in response payload.");
+               OCRepPayloadDestroy(rep_payload);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG(ST_DEBUG, "Collection's common properties are added in the response payload.");
+
+       // Get the properties of the collection resource from application.
+       result = handle_get_req_helper(collection_rsrc->uri, collection_rsrc->query, rep_payload);
+       if (!result) {
+               ST_LOG_V(ST_DEBUG, "Failed to get the collection resource(%s) properties from application.", collection_rsrc->uri);
+               ST_LOG(ST_DEBUG, "Corresponding payload in response will be empty.");
+       }
+
+       result = OCRepPayloadSetPropObjectAsOwner(payload_head, OC_RSRVD_REPRESENTATION, rep_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to set 'rep' for collection in response payload.");
+               OCRepPayloadDestroy(rep_payload);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       rep_payload = NULL;
+
+       // Handle child resources.
+       int num_of_children = 0;
+       things_resource_info_s **children = NULL;
+       if (!things_get_child_resources(collection_rsrc->uri, &num_of_children, &children)) {
+               ST_LOG(ST_ERROR, "Failed to get child resources.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       if (0 == num_of_children || NULL == children) {
+               ST_LOG(ST_ERROR, "No child resource(s).");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Collection resource(%s) has %d child resource(s).", collection_rsrc->uri, num_of_children);
+
+       result = true;
+       int rt_count = 0;
+       int if_count = 0;
+       char **res_types = NULL;
+       char **if_types = NULL;
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
+       OCRepPayload *payload = payload_head;
+       OCRepPayload *child_payload = NULL;
+       for (int index = 0; index < num_of_children; index++) {
+               if (NULL == children[index]) {
+                       ST_LOG_V(ST_ERROR, "Child at index(%d) is NULL.", index);
+                       result = false;
+                       break;
+               }
+
+               child_payload = OCRepPayloadCreate();
+               if (NULL == child_payload) {
+                       ST_LOG(ST_ERROR, "Failed to create payload for child.");
+                       result = false;
+                       break;
+               }
+               // Set child resource's URI.
+               if (!OCRepPayloadSetUri(child_payload, children[index]->uri)) {
+                       ST_LOG_V(ST_ERROR, "Failed to set the child resource uri(%s) in response representation.", children[index]->uri);
+                       result = false;
+                       break;
+               }
+               // Set child resource's representation (common properties and resource properties).
+               rep_payload = OCRepPayloadCreate();
+               if (NULL == rep_payload) {
+                       ST_LOG(ST_ERROR, "Failed to create payload for child.");
+                       result = false;
+                       break;
+               }
+               // Set the resource types.
+               if (!get_resource_types2(children[index], &res_types, &rt_count)) {
+                       ST_LOG(ST_ERROR, "Failed to get the resource types of child.");
+                       result = false;
+                       break;
+               }
+               dimensions[0] = rt_count;
+               if (!OCRepPayloadSetStringArrayAsOwner(rep_payload, OC_RSRVD_RESOURCE_TYPE, res_types, dimensions)) {
+                       ST_LOG(ST_ERROR, "Failed to set the resource types of child in response representation.");
+                       result = false;
+                       break;
+               }
+               res_types = NULL;
+
+               // Set the interface types.
+               if (!get_interface_types2(children[index], &if_types, &if_count)) {
+                       ST_LOG(ST_ERROR, "Failed to get the interface types of child.");
+                       result = false;
+                       break;
+               }
+               dimensions[0] = if_count;
+               if (!OCRepPayloadSetStringArrayAsOwner(rep_payload, OC_RSRVD_INTERFACE, if_types, dimensions)) {
+                       ST_LOG(ST_ERROR, "Failed to set the inteface types of child in response representation.");
+                       result = false;
+                       break;
+               }
+               if_types = NULL;
+
+               // First interface supported by the resource is the default inteface.
+               // Form a query with the first interface.
+               char **child_if_types = children[index]->interface_types;
+               if (NULL == child_if_types) {
+                       ST_LOG(ST_ERROR, "Child resource doesn't have any interface.");
+                       result = false;
+                       break;
+               }
+               char *if_type = child_if_types[0];
+               if (NULL == if_type) {
+                       ST_LOG(ST_ERROR, "First interface of child resource is NULL.");
+                       result = false;
+                       break;
+               }
+
+               char *prefix = "if=";
+               char *query = (char *)util_malloc(strlen(if_type) + strlen(prefix) + 1);
+               if (NULL == query) {
+                       ST_LOG(ST_ERROR, "Failed to create query for child.");
+                       result = false;
+                       break;
+               }
+
+               strncat(query, prefix, strlen(prefix));
+               strncat(query, if_type, strlen(if_type));
+
+               // Get the properties of the child resource from application.
+               result = handle_get_req_helper(children[index]->uri, query, rep_payload);
+               if (!result) {
+                       ST_LOG_V(ST_DEBUG, "Failed to get the child resource(%s) properties from application.", children[index]->uri);
+                       ST_LOG(ST_DEBUG, "Corresponding payload in response will be empty.");
+               }
+
+               if (!OCRepPayloadSetPropObjectAsOwner(child_payload, OC_RSRVD_REPRESENTATION, rep_payload)) {
+                       ST_LOG(ST_ERROR, "Failed to set the child representation in response representation.");
+                       util_free(query);
+                       result = false;
+                       break;
+               }
+
+               rep_payload = NULL;
+
+               util_free(query);
+
+               payload->next = child_payload;
+               payload = child_payload;
+       }
+
+       if (!result) {
+               if (NULL != res_types) {
+                       util_free_str_array(res_types, rt_count);
+               }
+
+               if (NULL != if_types) {
+                       util_free_str_array(if_types, if_count);
+               }
+
+               OCRepPayloadDestroy(child_payload);
+               OCRepPayloadDestroy(rep_payload);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+
+       return true;
+}
+
+ /*
+  * Handles GET request for colletion resources on "read-only", "read-write", "actuator" and "sensor" interfaces.
+  * Common properties will not be added.
+  */
+static bool handle_get_req_on_collection_common(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *resp_payload = resp_rep->payload;
+       if (NULL == resp_payload) {
+               ST_LOG(ST_ERROR, "Payload is response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       if (!OCRepPayloadSetUri(resp_payload, collection_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", collection_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource URI(%s) is set in the response payload.", collection_rsrc->uri);
+
+       // Get the resource's properties from the application.
+       bool result = handle_get_req_helper(collection_rsrc->uri, collection_rsrc->query, resp_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to get the resource properties from application.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Set the response representation in the resource.
+       collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+       return true;
+}
+
+int handle_get_req_on_collection_rsrc(things_resource_s *collection_rsrc)
+{
+       RET_VAL_IF_PARAM_IS_NULL(collection_rsrc, 0);
+
+       // Get interface type from query parameter
+       char *if_type = NULL;
+       if (NULL != collection_rsrc->query && strlen(collection_rsrc->query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(collection_rsrc->query, OC_RSRVD_INTERFACE, &if_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the interface type from query parameter(%s).", collection_rsrc->query);
+                       return 0;
+               }
+       }
+       // If interface is not available in the query parameter, then "oic.if.ll" will be taken as the default interface.
+       // Reasons:-
+       // 1. Default collection request handler in iotivity stack(occollection.c)
+       // takes "links list" as the default interface to serve collection resource requests.
+       // 2. Underlying stack adds "oic.if.ll" to all collection resources.
+       if (NULL == if_type) {
+               if_type = util_clone_string(OC_RSRVD_INTERFACE_LL);
+               RET_VAL_IF_NULL(if_type, "Failed to clone interface type.", 0);
+       }
+
+       ST_LOG_V(ST_DEBUG, "This GET request will be handled on %s inteface.", if_type);
+
+       bool result = false;
+       if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_DEFAULT, strlen(OC_RSRVD_INTERFACE_DEFAULT))) {
+               result = handle_get_req_on_collection_baseline(collection_rsrc);
+       } else if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_LL, strlen(OC_RSRVD_INTERFACE_LL))) {
+               result = handle_get_req_on_collection_linkslist(collection_rsrc);
+       } else if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {
+               result = handle_get_req_on_collection_batch(collection_rsrc);
+       } else {
+               result = handle_get_req_on_collection_common(collection_rsrc);
+       }
+
+       util_free(if_type);
+
+       return result ? 1 : 0;
+}
+
+ /*
+  * POST request and response schema is same as the GET response schema.
+  */
+static bool handle_post_req_on_collection_baseline(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Retrieve the request representation. This representation will hold all the input properties of post request.
+       // Payload in this representation will be used to form the request message which will be given to the application.
+       struct things_representation_s *req_rep = NULL;
+       bool rep_exist = collection_rsrc->things_get_representation(collection_rsrc, &req_rep);
+       if (!rep_exist || NULL == req_rep || NULL == req_rep->payload) {
+               ST_LOG(ST_ERROR, "Empty payload in POST request.");
+               return false;                   // TODO: When a post request comes with empty payload, how do we handle?
+       }
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *resp_payload = resp_rep->payload;
+       if (NULL == resp_payload) {
+               ST_LOG(ST_ERROR, "Payload in response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Set collection resource's URI.
+       if (!OCRepPayloadSetUri(resp_payload, collection_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", collection_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource URI(%s) is set in the response payload.", collection_rsrc->uri);
+
+       // Set collection resource's common properties (rt, if, & links).
+       bool result = add_common_props(collection_rsrc, true, resp_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to add the common properties in response payload.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG(ST_DEBUG, "Common properties are added in the response payload.");
+
+       // Give the properties of the collection resource to application and get the response.
+       result = handle_post_req_helper(collection_rsrc->uri, collection_rsrc->query, req_rep->payload, resp_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to set the resource properties.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+
+       return true;
+}
+
+ /*
+  * POST request and response schema is same as the GET response schema.
+  */
+static bool handle_post_req_on_collection_batch(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Retrieve the request representation. This representation will hold all the input properties of post request.
+       // Payload in this representation will be used to form the request message which will be given to the application.
+       struct things_representation_s *req_rep = NULL;
+       bool rep_exist = collection_rsrc->things_get_representation(collection_rsrc, &req_rep);
+       if (!rep_exist || NULL == req_rep || NULL == req_rep->payload) {
+               ST_LOG(ST_ERROR, "Empty payload in POST request.");
+               return false;                   // TODO: When a post request comes with empty payload, how do we handle?
+       }
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *payload_head = resp_rep->payload;
+       if (NULL == payload_head) {
+               ST_LOG(ST_ERROR, "Payload in response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Handle collection resource.
+       // Set collection resource's URI.
+       if (!OCRepPayloadSetUri(payload_head, collection_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", collection_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource URI(%s) is set in the response payload.", collection_rsrc->uri);
+
+       OCRepPayload *rep_payload = OCRepPayloadCreate();
+       if (NULL == rep_payload) {
+               ST_LOG(ST_ERROR, "Failed to create payload for response representation.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Set collection resource's common properties (rt, if, & links).
+       bool result = add_common_props(collection_rsrc, true, rep_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to add collection's common properties in response payload.");
+               OCRepPayloadDestroy(rep_payload);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG(ST_DEBUG, "Collection's common properties are added in the response payload.");
+
+       // Get the properties of the collection resource from application.
+       result = handle_post_req_helper(collection_rsrc->uri, collection_rsrc->query, req_rep->payload, rep_payload);
+       if (!result) {
+               ST_LOG_V(ST_DEBUG, "Failed to get the collection resource(%s) properties from application.", collection_rsrc->uri);
+               ST_LOG(ST_DEBUG, "Corresponding payload in response will be empty.");
+       }
+
+       result = OCRepPayloadSetPropObjectAsOwner(payload_head, OC_RSRVD_REPRESENTATION, rep_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to set the representation for collection in response payload.");
+               OCRepPayloadDestroy(rep_payload);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       rep_payload = NULL;
+
+       // Handle child resources.
+       result = true;
+       int num_of_children = 0;
+       things_resource_info_s **children = NULL;
+       if (!things_get_child_resources(collection_rsrc->uri, &num_of_children, &children)) {
+               ST_LOG(ST_ERROR, "Failed to get child resources.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       if (0 == num_of_children || NULL == children) {
+               ST_LOG(ST_ERROR, "No child resource(s).");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Collection resource(%s) has %d child resource(s).", collection_rsrc->uri, num_of_children);
+
+       int rt_count = 0;
+       int if_count = 0;
+       char **res_types = NULL;
+       char **if_types = NULL;
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
+       OCRepPayload *child_head = NULL;
+       OCRepPayload *prev_payload = NULL;      // Represents the previous payload in the linked list.
+       OCRepPayload *payload = NULL;   // Represents the current payload in loop.
+       for (int index = 0; index < num_of_children; index++) {
+               if (NULL == children[index]) {
+                       ST_LOG_V(ST_ERROR, "Child at index(%d) is NULL.", index);
+                       result = false;
+                       break;
+               }
+
+               payload = OCRepPayloadCreate();
+               if (NULL == payload) {
+                       ST_LOG(ST_ERROR, "Failed to create payload for child.");
+                       result = false;
+                       break;
+               }
+               // Set child resource's URI.
+               if (!OCRepPayloadSetUri(payload, children[index]->uri)) {
+                       ST_LOG_V(ST_ERROR, "Failed to set the child resource uri(%s) in response representation.", children[index]->uri);
+                       result = false;
+                       break;
+               }
+               // Set child resource's representation (common properties and resource properties).
+               rep_payload = OCRepPayloadCreate();
+               if (NULL == rep_payload) {
+                       ST_LOG(ST_ERROR, "Failed to create payload for child.");
+                       result = false;
+                       break;
+               }
+               // Set the resource types.
+               if (!get_resource_types2(children[index], &res_types, &rt_count)) {
+                       ST_LOG(ST_ERROR, "Failed to get the resource types of child.");
+                       result = false;
+                       break;
+               }
+               dimensions[0] = rt_count;
+               if (!OCRepPayloadSetStringArrayAsOwner(rep_payload, OC_RSRVD_RESOURCE_TYPE, res_types, dimensions)) {
+                       ST_LOG(ST_ERROR, "Failed to set the resource types of child in response representation.");
+                       result = false;
+                       break;
+               }
+               res_types = NULL;
+
+               // Set the interface types.
+               if (!get_interface_types2(children[index], &if_types, &if_count)) {
+                       ST_LOG(ST_ERROR, "Failed to get the interface types of child.");
+                       result = false;
+                       break;
+               }
+               dimensions[0] = if_count;
+               if (!OCRepPayloadSetStringArrayAsOwner(rep_payload, OC_RSRVD_INTERFACE, if_types, dimensions)) {
+                       ST_LOG(ST_ERROR, "Failed to set the inteface types of child in response representation.");
+                       result = false;
+                       break;
+               }
+               if_types = NULL;
+
+               // First interface supported by the resource is the default inteface.
+               // Form a query with the first interface.
+               char **child_if_types = children[index]->interface_types;
+               if (NULL == child_if_types) {
+                       ST_LOG(ST_ERROR, "Child resource doesn't have any interface.");
+                       result = false;
+                       break;
+               }
+               char *if_type = child_if_types[0];
+               if (NULL == if_type) {
+                       ST_LOG(ST_ERROR, "First interface of child resource is NULL.");
+                       result = false;
+                       break;
+               }
+
+               char *prefix = "if=";
+               char *query = (char *)util_malloc(strlen(if_type) + strlen(prefix) + 1);
+               if (NULL == query) {
+                       ST_LOG(ST_ERROR, "Failed to create query for child.");
+                       result = false;
+                       break;
+               }
+
+               strncat(query, prefix, strlen(prefix));
+               strncat(query, if_type, strlen(if_type));
+
+               // Get the properties of the child resource from application.
+               result = handle_post_req_helper(children[index]->uri, query, req_rep->payload, rep_payload);
+               if (!result) {
+                       ST_LOG_V(ST_DEBUG, "Failed to get the child resource(%s) properties from application.", children[index]->uri);
+                       ST_LOG(ST_DEBUG, "Corresponding payload in response will be empty.");
+               }
+
+               if (!OCRepPayloadSetPropObjectAsOwner(payload, OC_RSRVD_REPRESENTATION, rep_payload)) {
+                       ST_LOG(ST_ERROR, "Failed to set the child representation in response representation.");
+                       result = false;
+                       break;
+               }
+
+               rep_payload = NULL;
+
+               if (NULL != prev_payload) {
+                       prev_payload->next = payload;
+               } else {
+                       child_head = payload;
+               }
+               prev_payload = payload;
+               payload = NULL;
+
+               util_free(query);
+       }
+
+       if (!result) {
+               if (NULL != res_types) {
+                       util_free_str_array(res_types, rt_count);
+               }
+
+               if (NULL != if_types) {
+                       util_free_str_array(if_types, if_count);
+               }
+
+               OCRepPayloadDestroy(rep_payload);
+               OCRepPayloadDestroy(payload);
+               OCRepPayloadDestroy(child_head);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       payload_head->next = child_head;
+       collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+       return true;
+}
+
+ /*
+  * Handles POST request for colletion resources on "read-write" and "actuator" interfaces.
+  * Request and response neither include the common properties of collection resource
+  * nor the child resources' properties which means both request and response includes only
+  * the collection resource's properties.
+  */
+static bool handle_post_req_on_collection_common(things_resource_s *collection_rsrc)
+{
+       RET_FALSE_IF_PARAM_IS_NULL(collection_rsrc);
+
+       // Retrieve the request representation. This representation will hold all the input properties of post request.
+       // Payload in this representation will be used to form the request message which will be given to the application.
+       struct things_representation_s *req_rep = NULL;
+       bool rep_exist = collection_rsrc->things_get_representation(collection_rsrc, &req_rep);
+       if (!rep_exist || NULL == req_rep || NULL == req_rep->payload) {
+               ST_LOG(ST_ERROR, "Empty payload in POST request.");
+               return false;                   // TODO: When a post request comes with empty payload, how do we handle?
+       }
+       // Setup the response representation. This representation will be handed over to the underlying stack.
+       things_representation_s *resp_rep = things_create_representation_inst(NULL);
+       RET_FALSE_IF_NULL(resp_rep, "Failed to create response representation.");
+
+       OCRepPayload *resp_payload = resp_rep->payload;
+       if (NULL == resp_payload) {
+               ST_LOG(ST_ERROR, "Payload is response representation is NULL.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       if (!OCRepPayloadSetUri(resp_payload, collection_rsrc->uri)) {
+               ST_LOG_V(ST_ERROR, "Failed to set the resource uri(%s) in response payload.", collection_rsrc->uri);
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+
+       ST_LOG_V(ST_DEBUG, "Resource URI(%s) is set in the response payload.", collection_rsrc->uri);
+
+       // Give the properties of the collection resource to application and get the response.
+       bool result = handle_post_req_helper(collection_rsrc->uri, collection_rsrc->query,
+                                                                                req_rep->payload, resp_payload);
+       if (!result) {
+               ST_LOG(ST_ERROR, "Failed to set the resource properties.");
+               things_release_representation_inst(resp_rep);
+               return false;
+       }
+       // Set the response representation in the resource.
+       collection_rsrc->things_set_representation(collection_rsrc, resp_rep);
+
+       return true;
+}
+
+int handle_post_req_on_collection_rsrc(things_resource_s *collection_rsrc)
+{
+       RET_VAL_IF_PARAM_IS_NULL(collection_rsrc, 0);
+
+       // Get interface type from query parameter.
+       char *if_type = NULL;
+       if (NULL != collection_rsrc->query && strlen(collection_rsrc->query) > 0) {
+               bool found = false;
+               bool result = get_query_value_internal(collection_rsrc->query, OC_RSRVD_INTERFACE, &if_type, &found);
+               if (found && !result) { // If query is present but API returns false.
+                       ST_LOG_V(ST_ERROR, "Failed to get the interface type from query parameter(%s).", collection_rsrc->query);
+                       return 0;
+               }
+       }
+       // If interface is not available in the query parameter, then "oic.if.baseline" will be taken as the default interface.
+       if (NULL == if_type) {
+               if_type = util_clone_string(OC_RSRVD_INTERFACE_DEFAULT);
+               RET_VAL_IF_NULL(if_type, "Failed to clone interface type.", 0);
+       }
+
+       ST_LOG_V(ST_DEBUG, "This SET request will be handled on %s inteface.", if_type);
+
+       bool result = false;
+       if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_DEFAULT, strlen(OC_RSRVD_INTERFACE_DEFAULT))) {
+               result = handle_post_req_on_collection_baseline(collection_rsrc);
+       } else if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {
+               result = handle_post_req_on_collection_batch(collection_rsrc);
+       } else if (0 == strncmp(if_type, ST_THINGS_RSRVD_INTERFACE_READWRITE, strlen(ST_THINGS_RSRVD_INTERFACE_READWRITE))) {
+               result = handle_post_req_on_collection_common(collection_rsrc);
+       } else if (0 == strncmp(if_type, ST_THINGS_RSRVD_INTERFACE_ACTUATOR, strlen(ST_THINGS_RSRVD_INTERFACE_ACTUATOR))) {
+               result = handle_post_req_on_collection_common(collection_rsrc);
+       } else {
+               result = false;
+       }
+
+       util_free(if_type);
+
+       return result ? 1 : 0;
+}
diff --git a/framework/src/st_things/st_things_request_handler_collection.h b/framework/src/st_things/st_things_request_handler_collection.h
new file mode 100644 (file)
index 0000000..08378c4
--- /dev/null
@@ -0,0 +1,31 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef __ST_THINGS_REQUEST_HANDLER_COLLECTION_H__
+#define __ST_THINGS_REQUEST_HANDLER_COLLECTION_H__
+
+#include "things_resource.h"
+#include "octypes.h"
+
+bool form_collection_links(things_resource_s* collection_rsrc, OCRepPayload*** links, size_t* count);
+
+int handle_get_req_on_collection_rsrc(things_resource_s* collection_rsrc);
+
+int handle_post_req_on_collection_rsrc(things_resource_s* collection_rsrc);
+
+#endif // __ST_THINGS_REQUEST_HANDLER_COLLECTION_H__
diff --git a/framework/src/st_things/st_things_util.c b/framework/src/st_things/st_things_util.c
new file mode 100644 (file)
index 0000000..b1dda0e
--- /dev/null
@@ -0,0 +1,65 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "st_things_util.h"
+
+void *util_malloc(size_t size)
+{
+       RET_NULL_IF_PARAM_EXPR_IS_TRUE(size < 1);
+
+       return malloc(size);
+}
+
+void *util_calloc(size_t num, size_t size)
+{
+       RET_NULL_IF_PARAM_EXPR_IS_TRUE(num < 1);
+       RET_NULL_IF_PARAM_EXPR_IS_TRUE(size < 1);
+
+       return calloc(num, size);
+}
+
+void util_free(void *ptr)
+{
+       free(ptr);
+}
+
+char *util_clone_string(const char *str)
+{
+       RET_NULL_IF_PARAM_IS_NULL(str);
+
+       int len = strlen(str);
+       char *dest_str = (char *)util_malloc(sizeof(char) *len + 1);
+       if (NULL != dest_str) {
+               strncpy(dest_str, str, len + 1);
+       } else {
+               ST_LOG(ST_ERROR, "Memory allocation failed.");
+       }
+
+       return dest_str;
+}
+
+void util_free_str_array(char **ptr, size_t size)
+{
+       RET_IF_PARAM_IS_NULL(ptr);
+       RET_IF_PARAM_EXPR_IS_TRUE(size < 1);
+
+       for (size_t index = 0; index < size; index++) {
+               free(ptr[index]);
+       }
+       free(ptr);
+}
diff --git a/framework/src/st_things/st_things_util.h b/framework/src/st_things/st_things_util.h
new file mode 100644 (file)
index 0000000..2347d75
--- /dev/null
@@ -0,0 +1,135 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef __ST_THINGS_UTIL_H__
+#define __ST_THINGS_UTIL_H__
+
+#include <string.h>
+#include <stdlib.h>
+#include "st_things_logger.h"
+
+#define RET_IF_PARAM_IS_NULL(var) \
+       do { \
+               if (NULL == (var)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #var " is NULL."); \
+                       return; \
+               } \
+       } while (0)
+
+#define RET_NULL_IF_PARAM_IS_NULL(var) \
+       do { \
+               if (NULL == (var)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #var " is NULL."); \
+                       return NULL; \
+               } \
+       } while (0)
+
+#define RET_FALSE_IF_PARAM_IS_NULL(var) \
+       do { \
+               if (NULL == (var)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #var " is NULL."); \
+                       return false; \
+               } \
+       } while (0)
+
+#define RET_VAL_IF_PARAM_IS_NULL(var, ret_val) \
+       do { \
+               if (NULL == (var)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #var " is NULL."); \
+                       return (ret_val); \
+               } \
+       } while (0)
+
+#define RET_VAL_IF_NULL(var, msg, ret_val) \
+       do { \
+               if (NULL == (var)) { \
+                       ST_LOG(ST_ERROR, msg); \
+                       return (ret_val); \
+               } \
+       } while (0)
+
+#define RET_FALSE_IF_NULL(var, msg) \
+       do { \
+               if (NULL == (var)) { \
+                       ST_LOG(ST_ERROR, msg); \
+                       return false; \
+               } \
+       } while (0)
+
+#define RET_IF_PARAM_EXPR_IS_TRUE(expr) \
+       do { \
+               if ((expr)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #expr); \
+                       return; \
+               } \
+       } while (0)
+
+#define RET_NULL_IF_PARAM_EXPR_IS_TRUE(expr) \
+       do { \
+               if ((expr)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #expr); \
+                       return NULL; \
+               } \
+       } while (0)
+
+#define RET_FALSE_IF_PARAM_EXPR_IS_TRUE(expr) \
+       do { \
+               if ((expr)) { \
+                       ST_LOG(ST_ERROR, "Invalid Parameter: " #expr); \
+                       return false; \
+               } \
+       } while (0)
+
+#define RET_IF_EXPR_IS_TRUE(expr, msg) \
+       do { \
+               if ((expr)) { \
+                       ST_LOG(ST_ERROR, msg); \
+                       return; \
+               } \
+       } while (0)
+
+#define RET_FALSE_IF_EXPR_IS_TRUE(expr, msg) \
+       do { \
+               if ((expr)) { \
+                       ST_LOG(ST_ERROR, msg); \
+                       return false; \
+               } \
+       } while (0)
+
+#define RET_VAL_IF_EXPR_IS_TRUE(expr, msg, ret_val) \
+       do { \
+               if ((expr)) { \
+                       ST_LOG(ST_ERROR, msg); \
+                       return (ret_val); \
+               } \
+       } while (0)
+
+void *util_malloc(size_t size);
+
+void *util_calloc(size_t num, size_t size);
+
+void util_free(void *ptr);
+
+char *util_clone_string(const char *str);
+
+/**
+* Destroys the array items and the array.
+*/
+void util_free_str_array(char **ptr, size_t size);
+
+#endif                                                 // __ST_THINGS_UTIL_H__
diff --git a/framework/src/st_things/things_stack/.gitignore b/framework/src/st_things/things_stack/.gitignore
new file mode 100644 (file)
index 0000000..7923644
--- /dev/null
@@ -0,0 +1,5 @@
+*.o
+*.os
+*.pyc
+*.a
+*.so
diff --git a/framework/src/st_things/things_stack/.sconsign.dblite b/framework/src/st_things/things_stack/.sconsign.dblite
new file mode 100644 (file)
index 0000000..962e77e
Binary files /dev/null and b/framework/src/st_things/things_stack/.sconsign.dblite differ
diff --git a/framework/src/st_things/things_stack/Make.defs b/framework/src/st_things/things_stack/Make.defs
new file mode 100644 (file)
index 0000000..426d5fb
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += port_tinyara.c
+
+DEPPATH += --dep-path src/st_things/things_stack
+VPATH += :src/st_things/things_stack
\ No newline at end of file
diff --git a/framework/src/st_things/things_stack/inc/iotivity_config.h b/framework/src/st_things/things_stack/inc/iotivity_config.h
new file mode 100644 (file)
index 0000000..397d324
--- /dev/null
@@ -0,0 +1,64 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef IOTIVITY_CONFIG_H__
+#define IOTIVITY_CONFIG_H__
+
+#include <tinyara/config.h>
+
+#define HAVE_ARPA_INET_H 1
+
+#define HAVE_FCNTL_H 1
+
+#define HAVE_GRP_H 1
+
+#define HAVE_NETDB_H 1
+
+#define HAVE_NETINET_IN_H 1
+
+#define HAVE_PTHREAD_H 1
+
+#define HAVE_PWD_H 1
+
+#define HAVE_STDLIB_H 1
+
+#define HAVE_STRING_H 1
+
+#define HAVE_STRINGS_H 1
+
+#define HAVE_SYS_SOCKET_H 1
+
+#define HAVE_SYS_STAT_H 1
+
+#define HAVE_SYS_TIME_H 1
+
+#define HAVE_SYS_TYPES_H 1
+
+#define HAVE_SYS_UNISTD_H 1
+
+#define HAVE_SYSLOG_H 1
+
+#define HAVE_TIME_H 1
+
+#define HAVE_UNISTD_H 1
+
+#define HAVE_UUID_UUID_H 1
+
+#include "platform_features.h"
+
+#endif                                                 // IOTIVITY_CONFIG_H__
diff --git a/framework/src/st_things/things_stack/inc/things_api.h b/framework/src/st_things/things_stack/inc/things_api.h
new file mode 100644 (file)
index 0000000..53f2911
--- /dev/null
@@ -0,0 +1,117 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_API_H_
+#define _THINGS_API_H_
+
+#include <stdint.h>
+#include "things_types.h"
+#include "things_resource.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif                                                 // __cplusplus
+
+#define TYPE_INT_64 "int64"
+#define TYPE_BOOL   "boolean"
+#define TYPE_DOUBLE "double"
+#define TYPE_STRING "string"
+#define TYPE_BYTE    "byte"
+
+#define MAX_IPADDR           (16)
+#define OIC_UUID_STRING_SIZE (37)
+
+const char *things_get_sw_version();
+const char *things_get_device_id_string();
+int things_set_device_name(int dev_num, char *name);
+
+int things_initialize_stack(const char *json_path, bool *easysetup_completed);
+int things_deinitialize_stack();
+int things_start_stack();
+
+typedef void (*things_reset_result_func_type)(int result);
+
+typedef int (*things_reset_confirm_func_type)(things_reset_result_func_type *func_carrier, things_es_enrollee_reset_e reset_type);
+
+int things_register_confirm_reset_start_func(things_reset_confirm_func_type func);
+
+int things_return_user_opinion_for_reset(int b_reset_start);
+
+int things_reset(void *remote_owner, things_es_enrollee_reset_e reset_type);
+
+int things_stop(void);
+
+typedef int (*things_handle_request_func_type)(struct things_resource_s *p_resource);
+int things_register_handle_request_func(things_handle_request_func_type get_func, things_handle_request_func_type set_func);
+
+typedef int (*things_update_dev_prov_data_func_type)(es_dev_conf_prov_data_s *p_dev_prov_data);
+
+int things_register_update_dev_prov_data_func(things_update_dev_prov_data_func_type func);
+
+typedef int (*things_stop_soft_ap_func_type)(int value);
+
+int things_register_stop_soft_ap_func(things_stop_soft_ap_func_type func);
+
+int things_notify_observers(const char *uri);
+
+int things_send_push_message(const char *push_uri, void *payload);
+
+int things_wifi_changed_call_func(int state, char *ap_name, char *ip_addr);
+
+typedef void (*things_pin_generated_func_type)(char *pin_data, size_t pin_size);
+
+int things_register_pin_generated_func(things_pin_generated_func_type func);
+
+typedef void (*things_pin_display_close_func_type)(void);
+
+int things_register_pin_display_close_func(things_pin_display_close_func_type func);
+
+typedef int (*things_get_user_confirm_func_type)(void);
+
+int things_register_user_confirm_func(things_get_user_confirm_func_type func);
+
+int things_get_easysetup_state(void);
+
+typedef void (*things_get_easysetup_state_func_type)(things_es_enrollee_state_e state);
+
+int things_register_easysetup_state_func(things_get_easysetup_state_func_type func);
+
+typedef void (*things_cloud_con_result_func_type)(int result, char *domain, char *access_token);
+
+typedef void (*things_abort_easysetup_func_type)(things_es_enrollee_abort_e level);
+
+typedef void (*things_sec_otm_state_func_type)(const char *addr, uint16_t port, const char *uuid, int event);
+
+int things_register_otm_event_handler(things_sec_otm_state_func_type otm_event_callback);
+
+int things_save_acl(const char *uuid, const char *resource_uri, const char *resource_type, const char *interface_name, uint16_t permission);
+
+int things_set_mot_status(bool enable);
+
+int things_get_resource_type(const char *resource_uri, int *count, char ***resource_types);
+
+int things_get_attributes_by_resource_type(const char *res_type, int *count, things_attribute_info_s ***attributes);
+
+bool things_is_collection_resource(const char *res_uri);
+
+int things_get_child_resources(const char *col_res_uri, int *count, things_resource_info_s ***child_resources);
+
+#ifdef __cplusplus
+}
+#endif                                                 // __cplusplus
+#endif                                                 // _THINGS_API_H_
diff --git a/framework/src/st_things/things_stack/inc/things_resource.h b/framework/src/st_things/things_stack/inc/things_resource.h
new file mode 100644 (file)
index 0000000..f83c918
--- /dev/null
@@ -0,0 +1,296 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _THINGS_RESOURCE_H_
+#define _THINGS_RESOURCE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif                                                 // __cplusplus
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <octypes.h>
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define QUERY_DELIMITER ";"            // or "#"
+
+//-----------------------------------------------------------------------------
+// Typedefs
+//-----------------------------------------------------------------------------
+/* Structure for Array Attribute */
+typedef struct things_representation_s {
+       void *payload;                  // 8 bytes
+       void **children_payload;        // 8 bytes
+       int64_t num_children;   // 8 bytes
+       struct things_representation_s **children;      // 8 * num_children bytes
+
+       /**
+        * @brief API for setting value with a key
+        * @param key : Attribute Key which will represent the value
+        * @param value : Attribute value
+        */
+       void (*things_set_value)(struct things_representation_s *rep, char *key, char *);
+       void (*things_set_bool_value)(struct things_representation_s *rep, char *key, bool);
+       void (*things_set_int_value)(struct things_representation_s *rep, char *key, int64_t);
+       void (*things_set_double_value)(struct things_representation_s *rep, char *key, double);
+       void (*things_set_byte_value)(struct things_representation_s *rep, char *key, uint8_t *value, size_t size);
+       bool(*things_set_object_value)(struct things_representation_s *mother, char *key, struct things_representation_s *child);
+       /**
+        * @brief API for setting/getting object array type of attribute.
+        * @param key : Attribute Key which will represent the array type of value
+        * @param length : Length of value(representation) array
+        * @param reps : Array type (representation) values
+        */
+       bool(*things_set_arrayvalue)(struct things_representation_s *, char *key, int length, struct things_representation_s **reps);
+
+       bool(*things_get_arrayvalue)(struct things_representation_s *, char *key, int *length, struct things_representation_s ***reps);
+
+       /**
+        * @brief API for setting/getting string array type of attribute.
+        * @param key : Attribute Key which will represent the array type of value
+        * @param length : Length of value(string) array
+        * @param array : Array type string values
+        */
+       void (*things_set_string_arrayvalue)(struct things_representation_s *mother, char *key, int length, char **array);
+
+       bool(*things_get_string_arrayvalue)(struct things_representation_s *mother, char *key, int *length, char ***array);
+
+       /**
+        * @brief API for setting/getting double array type of attribute.
+        * @param key : Attribute Key which will represent the array type of value
+        * @param length : Length of value(double) array
+        * @param array : Array type double values
+        */
+       void (*things_set_double_arrayvalue)(struct things_representation_s *mother, char *key, int length, double *array);
+
+       bool(*things_get_double_arrayvalue)(struct things_representation_s *mother, char *key, int *length, double **array);
+
+       /**
+       * @brief API for inserting int array type of attribute.
+       * @param key : Attribute Key which will represent the array type of value
+       * @param length : Length of value(int) array
+       * @param array : Array type int values
+       */
+       void (*things_set_int_arrayvalue)(struct things_representation_s *mother, char *key, int length, int64_t *array);
+
+       bool(*things_get_int_arrayvalue)(struct things_representation_s *mother, char *key, int *length, int64_t **array);
+       /**
+        * @brief API for getting value with a key
+        * @param key   : Attribute Key which represents the value
+        * @param value : Reference of the variable to where value will be copied
+        * @return      : true(value exist), false(value not exist)
+        */
+       bool(*things_get_value)(struct things_representation_s *rep, char *key, char **);
+       bool(*things_get_bool_value)(struct things_representation_s *rep, char *key, bool *);
+       bool(*things_get_int_value)(struct things_representation_s *rep, char *key, int64_t *);
+       bool(*things_get_double_value)(struct things_representation_s *rep, char *key, double *);
+       bool(*things_get_byte_value)(struct things_representation_s *rep, char *key, uint8_t **value, size_t *size);
+       bool(*things_get_object_value)(struct things_representation_s *mother, char *key, struct things_representation_s *child);
+
+} things_representation_s;
+
+/* Structure for Things resource */
+typedef struct things_resource_s {
+       char *query;                    // 4 bytes
+       char *uri;                              // 4 Bytes
+       char *res_type;                 // 4 Bytes
+       char *interface_type;   // 4 Bytes
+
+       OCRequestHandle request_handle;
+       OCResourceHandle resource_handle;       // 4 Bytes, OCResourceHandle handle;
+       int req_type;                   // 4 Bytes
+       double error;                   // 8 Bytes
+
+       struct things_resource_s *next; // 4 Bytes
+       struct things_representation_s *rep;    // 4 Bytes
+
+       size_t size;                    // 4 bytes
+       char *cmd_id;                   // 4 Bytes
+
+       void *dev_addr;                 //  sizeof(OCDevAddr) ????
+
+       void (*things_set_dev_addr)(struct things_resource_s *, void *OCDevAddr);
+       void *(*things_get_dev_addr)(struct things_resource_s *);
+
+       /**
+       * @brief API for setting URI.
+       * @param things_resource_s * : Instance of target resource
+       * @param const char *  : URI string value
+       */
+       void (*things_set_uri)(struct things_resource_s *, const char *uri);
+       /**
+       * @brief API for setting error when returning request handling result
+       * @param things_resource_s * : Instance of target resource
+       * @param double        : error code
+       */
+       void (*things_set_error)(struct things_resource_s *, double errorCode);
+
+       /**
+       * @brief API for getting query value
+       * @param things_resource_s * : Instance of target resource
+       * @param char* key     : key value to look up in the query(ex: query -> key=value?key=value?...)
+       * @param char* value   : value of the key in the query
+       * @return              : true(query exist), false(query not exist)
+       */
+       bool(*things_get_query)(struct things_resource_s *, char *key, char **value);
+
+       /**
+       * @brief API for getting URI
+       * @param things_resource_s * : Instance of target resource
+       * @param char** uri    : reference of the char* variable to where uri will be copied
+       */
+       void (*things_get_uri)(struct things_resource_s *, char **uri);
+
+       /**
+       * @brief API for getting # of supporting resource types
+       * @param things_resource_s * : Instance of target resource
+       * @return              : Number of supporting resource types
+       */
+       int (*things_get_num_of_res_types)(struct things_resource_s *);
+       int (*things_get_num_of_inf_types)(struct things_resource_s *);
+       /**
+       * @brief API for getting # of supporting resource type with index
+       * @param things_resource_s * : Instance of target resource
+       * @param things_resource_s * : Index of supported resource type list
+       * @return              : Supporting resource type
+       */
+       const char *(*things_get_res_type)(struct things_resource_s *, int index);
+       const char *(*things_get_inf_type)(struct things_resource_s *, int index);
+       /**
+       * @brief API for getting childrens of target resource
+       * @param things_resource_s * : Instance of target resource
+       * @return              : Instance of children resource
+       *                        (Children resource are managed with Linked List)
+       */
+       struct things_resource_s *(*things_get_children)(struct things_resource_s *);
+
+       /**
+       * @brief API for setting representation of the target resource
+       * @param things_resource_s *       : Instance of target resource
+       * @param things_representation_s * : Instance of the representation to set
+       */
+       void (*things_set_representation)(struct things_resource_s *, struct things_representation_s *rep);
+
+       /**
+       * @brief API for getting representation of the target resource
+       * @param things_resource_s *       : Instance of target resource
+       * @param things_representation_s * : Instance of the representation to set
+       * @return                    : true(Representation exist), false(Representation not exist)
+       */
+       bool(*things_get_representation)(struct things_resource_s *, struct things_representation_s **rep);
+
+       /**
+       * @brief API for getting payload (Internal use only, NOT API)
+       * @param things_resource_s *       : Instance of target resource
+       * @return                    : Instance OCRepPayload data structure defined by IoTivity stack
+       */
+       void *(*things_get_rep_payload)(struct things_resource_s *);
+
+       /**
+       * @brief API for creating instance of payload (Internal use only, NOT API)
+       * @param things_resource_s *       : Instance of target resource
+       * @return                    : New instance OCRepPayload data structure defined by IoTivity stack
+       */
+       void *(*things_create_payload)(struct things_resource_s *, char *);
+
+       /**
+       * @brief API for checking whether given interface type is supporting one or not
+       * @param things_resource_s *   : Instance of target resource
+       * @param iftype          : Interface type to check
+       * @return                : true (supporting interface type),false(not supporting)
+       */
+       bool(*things_is_supporting_interface_type)(struct things_resource_s *, char *ifType);
+
+       /**
+       * @brief API for checking whether given resource type is supporting one or not
+       * @param things_resource_s *   : Instance of target resource
+       * @param iftype          : Resource type to check
+       * @return                : true (supporting resource type),false(not supporting)
+       */
+       bool(*things_is_supporting_resource_type)(struct things_resource_s *, char *res_type);
+
+       /**
+       * @brief API for setting frameid
+       * @brief Frameid will be used to match the response delivered from st_things SW with received request
+       * @param things_resource_s *   : Instance of target resource
+       * @param cmd_id           : Frame ID
+       */
+       void (*things_set_command_id)(struct things_resource_s *res, char *cmd_id);
+
+       /**
+       * @brief API for getting children resource instances
+       * @param things_resource_s *   : Instance of target resource
+       * @return                : Instance of children resource(s)
+       */
+       struct things_resource_s *(*things_get_next)(struct things_resource_s *);
+
+       /**
+       * @brief API for adding children resource instances
+       * @param things_resource_s *   : Instance of target resource
+       * @param things_resource_s *   : Instance of children resource
+       */
+       void (*things_add_child)(struct things_resource_s *, struct things_resource_s *);
+
+} things_resource_s;
+
+/**
+* @brief API for creating instance of payload
+* @param rep_payload            : Instance of target resource
+* @return things_representation_s *  : Instance of resource repsentation
+*/
+things_representation_s *things_create_representation_inst(void *rep_payload);
+
+/**
+* @brief API for creating instance of resource
+* @param void*      : Instance of request handle
+* @param void*      : Instance of resource handle
+* @param void*      : Query in the request message
+* @param void*      : Instance of payload in the request
+* @return things_resource_s *  : Instance of resource repsentation
+*/
+things_resource_s *things_create_resource_inst(OCRequestHandle, OCResourceHandle, void *, void *);
+
+/**
+* @brief API for cloning instance of given resource
+* @param things_resource_s *   : Instance of resource to clone
+* @return things_resource_s *  : Instance of cloned resource
+*/
+things_resource_s *things_clone_resource_inst(things_resource_s *);
+void things_clone_resource_inst2(things_resource_s *pori, things_resource_s **pclone);
+
+/**
+* @brief API for releasing memory allocated for the instance of given representation
+* @param things_representation_s *   : Instance of representation to release
+*/
+void things_release_representation_inst(things_representation_s *);
+
+/**
+* @brief API for releasing memory allocated for the instance of given resource
+* @param things_representation_s *   : Instance of resource to release
+*/
+void things_release_resource_inst(things_resource_s *);
+
+#ifdef __cplusplus
+}
+#endif                                                 // __cplusplus
+#endif                                                 // _THINGS_RESOURCE_H_
diff --git a/framework/src/st_things/things_stack/inc/things_types.h b/framework/src/st_things/things_stack/inc/things_types.h
new file mode 100644 (file)
index 0000000..a16d6ce
--- /dev/null
@@ -0,0 +1,244 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_TYPES_H_
+#define _THINGS_TYPES_H_
+
+#define THINGS_STRING_MAX_DNSNAME  256
+#define THINGS_STRING_MAX_LENGTH   100
+
+#define MAX_SSIDLEN     33
+#define MAX_CREDLEN     64
+#define IP_PORT                 22
+
+typedef enum {
+       WiFi_11A = 0,
+       WiFi_11B,
+       WiFi_11G,
+       WiFi_11N,
+       WiFi_11AC,
+       WiFi_EOF = 999,
+} wifi_mode_e;
+
+typedef enum {
+       WiFi_24G = 0,
+       WiFi_5G,
+       WiFi_BOTH,
+       WiFi_FREQ_EOF
+} wifi_freq_e;
+
+typedef enum {
+       NONE_AUTH = 0,
+       WEP,
+       WPA_PSK,
+       WPA2_PSK
+} wifi_auth_type_e;
+
+typedef enum {
+       NONE_ENC = 0,
+       WEP_64,
+       WEP_128,
+       TKIP,
+       AES,
+       TKIP_AES
+} wifi_enc_type_e;
+
+typedef struct {
+       char ssid[MAX_SSIDLEN]; /**< ssid of the Enroller**/
+       char pwd[MAX_CREDLEN]; /**< pwd of the Enroller**/
+       wifi_auth_type_e authtype;      /**< auth type of the Enroller**/
+       wifi_enc_type_e enctype; /**< encryption type of the Enroller**/
+       int discovery_channel;          // samsung specific property
+} es_wifi_prov_data_s;
+
+typedef struct {
+       char language[THINGS_STRING_MAX_LENGTH];
+       char country[THINGS_STRING_MAX_LENGTH];
+       char datetime[THINGS_STRING_MAX_LENGTH];
+} es_dev_conf_prov_data_s;
+
+typedef struct {
+       char auth_code[THINGS_STRING_MAX_LENGTH];
+       char auth_provider[THINGS_STRING_MAX_LENGTH];
+       char ip[IP_PORT];
+       char port[IP_PORT];
+       char host_name[THINGS_STRING_MAX_DNSNAME];
+       char ci_server[THINGS_STRING_MAX_LENGTH];
+       char server_id[THINGS_STRING_MAX_LENGTH];
+       char client_id[THINGS_STRING_MAX_LENGTH];
+       char accesstoken[THINGS_STRING_MAX_LENGTH];
+       int actoken_type;
+       char refreshtoken[THINGS_STRING_MAX_LENGTH];
+       char uid[THINGS_STRING_MAX_LENGTH];
+} es_cloud_prov_data_s;
+
+typedef struct things_cloud_info_s {
+       char *domain;                   // mandatory ( You can choose one in both "domain" and "ip". )
+       char *ip;
+       char *port;                             // optional
+       char *auth_provider;    // mandatory
+       char *access_token;             // mandatory
+       char *access_token_type;        // optional
+       char *refresh_token;    // mandatory
+       char *user_id;                  // mandatory
+       char *client_id;                // mandatory
+} things_cloud_info_s;
+
+#define MAX_DEVICEID_LEN 8
+#define MAX_RESOURCE_LEN 128
+#define MAX_URI_LEN 128
+#define MAX_QUERY_LEN 100
+#define MAX_ATTRIBUTE_LEN 64
+#define MAX_VALUETYPE_LEN 32
+#define MAX_ATTRVALUE_LEN 512
+#define MAX_KEY_LENGTH    50
+#define MAX_SPEC_LENGTH       7
+#define MAX_RID_LENGTH       10
+#define MAX_IT_CNT        5
+#define MAX_RT_CNT        10
+
+typedef struct things_info_s {
+       char device_id[MAX_DEVICEID_LEN];
+       char resource[MAX_RESOURCE_LEN];
+       char query[MAX_QUERY_LEN];
+       char attribute[MAX_ATTRIBUTE_LEN];
+       char type[MAX_VALUETYPE_LEN];
+       char value[MAX_ATTRVALUE_LEN];
+       char id[MAX_DEVICEID_LEN];
+
+       void *request_handle;
+       void *resource_handle;
+} things_info_s;
+
+typedef struct things_attribute_info_s {
+       char key[MAX_KEY_LENGTH];
+       char spec[MAX_SPEC_LENGTH];
+       int type;
+       bool mandatory;
+       int rw;
+} things_attribute_info_s;
+
+typedef struct things_resource_info_s {
+       char rid[MAX_RID_LENGTH];
+       char uri[MAX_URI_LEN];
+       char *interface_types[MAX_IT_CNT];
+       char *resource_types[MAX_RT_CNT];
+
+       int if_cnt;
+       int rt_cnt;
+       bool observable;
+       int policy;
+} things_resource_info_s;
+
+typedef enum {
+       RST_NEED_CONFIRM = 0,
+
+       RST_AUTO_RESET = 1,
+
+       RST_ENUM_EOF
+} things_es_enrollee_reset_e;
+
+typedef enum {
+       /**
+        * Default Abort State.
+        */
+       ABORT_INIT = 0,
+
+       /**
+        * Abort Status indicating cancel Reset Confirm.
+        */
+       ABORT_BEFORE_RESET_CONFIRM = 1,
+
+       /**
+        * Abort Status indicating cancel Security Confirm.
+        */
+       ABORT_BEFORE_SEC_CONFIRM = 2,
+
+       /**
+        * Abort Status indicating being security-process to delete Owned Security Data.
+        */
+       ABORT_BEFORE_DATA_PROVISIONING = 3
+} things_es_enrollee_abort_e;
+
+/**
+ * @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 connecting to target network
+        */
+       ES_STATE_CONNECTING_TO_ENROLLER,
+
+       /**
+        * Status indicating successful connection to target network
+        */
+       ES_STATE_CONNECTED_TO_ENROLLER,
+
+       /**
+        * Status indicating connection failure to target network
+        */
+       ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER,
+
+       /**
+        * Status indicating being registering to cloud
+        */
+       ES_STATE_REGISTERING_TO_CLOUD,
+
+       /**
+        * Status indicating successful registration to cloud
+        */
+       ES_STATE_REGISTERED_TO_CLOUD,
+
+       /**
+        * Status indicating registration failure to cloud
+        */
+       ES_STATE_FAILED_TO_REGISTER_TO_CLOUD,
+
+       /**
+        * Status indicating being publishing resources to cloud
+        */
+       ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD,
+
+       /**
+        * Status indicating successful resource publish to cloud
+        */
+       ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD,
+
+       /**
+        * Status indicating resource publish failure to cloud
+        */
+       ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD,
+
+       /**
+        * Status indicating Logout from cloud
+        */
+       ES_STATE_LOGOUT_FROM_CLOUD,
+
+       /**
+        * End of Easy setup status
+        */
+       ES_STATE_EOF = 255
+} things_es_enrollee_state_e, things_prov_status_e, things_cloud_status_e;
+
+#endif                                                 /* _THINGS_TYPES_H_ */
diff --git a/framework/src/st_things/things_stack/port_tinyara.c b/framework/src/st_things/things_stack/port_tinyara.c
new file mode 100644 (file)
index 0000000..c98b922
--- /dev/null
@@ -0,0 +1,96 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 <tinyara/config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <net/lwip/netif.h>
+#include <ocstack.h>
+#include "uuid/uuid.h"
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+extern struct netif *g_netdevices;
+#endif
+
+void uuid_generate_random(uuid_t out)
+{
+       int i = 0;
+
+       srand(time(NULL));                      /* TODO: Need to check time(NULL) */
+       for (i = 0; i < sizeof(uuid_t); i++) {  /* 16 means UUID size */
+               out[i] = rand() % 0xff;
+       }
+
+       out[6] = (out[6] & 0x0F) | 0x40;
+       out[8] = (out[8] & 0x3F) | 0x80;
+}
+
+void uuid_generate(uuid_t out)
+{
+       uuid_generate_random(out);
+}
+
+void uuid_unparse_lower(const uuid_t uu, char *out)
+{
+       snprintf(out, 37 /* UUID_STRING_SIZE */ ,
+                        "%02x%02x%02x%02x-" "%02x%02x-" "%02x%02x-" "%02x%02x-" "%02x%02x%02x%02x%02x%02x", uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+       static struct ifaddrs ifa;
+       static struct sockaddr_in addr, netmask;
+       uint8_t flags;
+
+       memset(&ifa, 0, sizeof(ifa));
+       memset(&addr, 0, sizeof(addr));
+       memset(&netmask, 0, sizeof(netmask));
+
+       struct netif *curr = g_netdevices;
+
+       netlib_get_ipv4addr(curr->d_ifname, &addr.sin_addr);
+       netlib_get_dripv4addr(curr->d_ifname, &netmask.sin_addr);
+       netlib_getifstatus(curr->d_ifname, &flags);
+
+       ifa.ifa_next = NULL;
+       ifa.ifa_name = curr->d_ifname;
+       ifa.ifa_flags = flags | IFF_RUNNING;
+       addr.sin_family = netmask.sin_family = AF_INET;
+       ifa.ifa_addr = (struct sockaddr *)&addr;
+       ifa.ifa_netmask = (struct sockaddr *)&netmask;
+
+       *ifap = &ifa;
+
+       return 0;
+}
+
+unsigned int if_nametoindex(const char *ifname)
+{
+       return 0;                                       // TODO: Now supports only 1 device
+}
+
+const char *gai_strerror(int errcode)
+{
+       static const char *n_str = "null";
+       return n_str;
+}
diff --git a/framework/src/st_things/things_stack/src/common/cloud/Make.defs b/framework/src/st_things/things_stack/src/common/cloud/Make.defs
new file mode 100644 (file)
index 0000000..c2820d6
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += cloud_connector.c cloud_evtpend.c cloud_manager.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/cloud
+VPATH += :src/st_things/things_stack/src/common/cloud
\ No newline at end of file
diff --git a/framework/src/st_things/things_stack/src/common/cloud/cloud_connector.c b/framework/src/st_things/things_stack/src/common/cloud/cloud_connector.c
new file mode 100644 (file)
index 0000000..d03c412
--- /dev/null
@@ -0,0 +1,692 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _BSD_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#include <string.h>
+#include <stdlib.h>
+
+#include <netdb.h>
+#ifdef __USE_MISC
+#include <arpa/inet.h>
+#include <errno.h>
+#endif
+
+#include "octypes.h"
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "rd_client.h"
+
+#include "things_malloc.h"
+#include "things_logger.h"
+#include "es_common.h"
+#include "cloud_connector.h"
+#include "things_wait_handler.h"
+#include "things_data_manager.h"
+#include <wifi_manager/wifi_manager.h>
+
+#define TAG "[cloud_cntor]"
+
+#define HOSTENT_INTERNAL_HEADER_SIZE        100
+
+/** Account Device-Profile publish URI.*/
+#define OC_RSRVD_ACCOUNT_DEVPROFILE_URI    "/oic/account/profile/device"
+
+static OCRepPayload *make_dev_profile_payload(const st_device_s *dev_info);
+
+int CICheckDomain(const char *DomainName, char **pIP)
+{
+
+       char ipbuffer[20];
+       memset(ipbuffer, 0, 20);
+       char bytes[4];
+
+       int ip4_address = 0;
+
+       wifi_manager_result_e res = wifi_net_hostname_to_ip4(DomainName, &ip4_address);
+       if (res == 0) {
+               bytes[0] = ip4_address & 0XFF;
+               bytes[1] = (ip4_address >> 8) & 0XFF;
+               bytes[2] = (ip4_address >> 16) & 0XFF;
+               bytes[3] = (ip4_address >> 24) & 0XFF;
+               //54.85.39.78
+               //78.85.39.54
+
+               snprintf(ipbuffer, sizeof(ipbuffer), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "DNS resolved IP for[%s] is =%s", DomainName, ipbuffer);
+
+               if (pIP != NULL) {
+                       *pIP = strdup(ipbuffer);
+               }
+       } else {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, " Failed to get the IP, hard coding the ip");
+               snprintf(ipbuffer, sizeof(ipbuffer), "%s", "13.124.51.231");
+
+               usleep(500);
+               if (pIP != NULL) {
+                       *pIP = strdup(ipbuffer);
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * @brief              Entry Point for checking about internet & Cloud connection.
+ * @param DomainName   wanted Domain-Name string to look-up IP address. (unit: const char*)
+ * @param pIP          Variable pointer to store Founded IP address. (unit: char**)
+ * @return             success : return 0 \n
+ *                     failure : return > 0
+ */
+int ci_connection_pre_check(const char *DomainName, char **pIP)
+{
+       int n_err = 0;                          // Success return value
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "DomainName=%s, pIP=0x%X", DomainName, pIP);
+
+       if (CICheckDomain("samsung.com", NULL) != 0) {
+               if (DomainName == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "AP is Not Connected to Internet.");
+                       return -1;
+               }
+       }
+
+       if (DomainName != NULL) {
+               n_err = CICheckDomain(DomainName, pIP);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Found IP = %s, n_err = %d", *pIP, n_err);
+       }
+
+       return n_err;
+}
+
+/**
+ * @brief                  Send Sign-UP request to Cloud.
+ * @param host             wanted Cloud address. (unit: const char*) \n
+ *                         Ex) coaps+tcp://123.123.123.123:1234
+ * @param device_id         Identifier of device. (unit: const char*)
+ * @param event_data        Data structure pointer for Cloud-Provisioning Data.
+ * @param response         Call-Back function when cloud response against this request.
+ * @param timeoutHandler   Call function when Time-out is occurred.
+ * @param timeout          Data structure pointer for Time-out processing Data.
+ * @return                 success : OC_STACK_OK \n
+ *                         failure : other value
+ */
+OCStackResult things_cloud_signup(const char *host, const char *device_id, const es_cloud_prov_data_s *event_data, OCClientResponseHandler response, check_time_out_call_func timeoutHandler, timeout_s *timeout)
+{
+       OCDoHandle g_req_handle = NULL;
+       OCStackResult result = OC_STACK_ERROR;
+       char targetUri[MAX_URI_LENGTH * 2] = { 0, };
+       OCCallbackData cb_data;
+       OCRepPayload *registerPayload = NULL;
+
+       if (host == NULL || device_id == NULL || event_data == NULL || (event_data->accesstoken[0] == 0 && event_data->auth_code[0] == 0)) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid event_data.");
+               goto no_memory;
+       }
+
+       snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, OC_RSRVD_ACCOUNT_URI);
+       THINGS_LOG_D(THINGS_INFO, TAG, "Signing up to : %s", targetUri);
+
+       memset(&cb_data, 0, sizeof(OCCallbackData));
+       cb_data.cb = response;
+       cb_data.cd = NULL;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+       registerPayload = OCRepPayloadCreate();
+       if (!registerPayload) {
+               goto no_memory;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "di              : %s", device_id);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "authprovider    : %s", event_data->auth_provider);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "devicetype      : resource_server");
+
+       OCRepPayloadSetPropString(registerPayload, "di", device_id);
+       OCRepPayloadSetPropString(registerPayload, "authprovider", event_data->auth_provider);
+       OCRepPayloadSetPropString(registerPayload, "devicetype", "resource_server");
+
+       if (event_data->accesstoken[0] != 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "accesstoken     : %s", event_data->accesstoken);
+               OCRepPayloadSetPropString(registerPayload, "accesstoken", event_data->accesstoken);
+
+               if (event_data->uid[0] != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "uid             : %s", event_data->uid);
+                       OCRepPayloadSetPropString(registerPayload, "uid", event_data->uid);
+               }
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "authcode        : %s", event_data->auth_code);
+               OCRepPayloadSetPropString(registerPayload, "authcode", event_data->auth_code);
+       }
+
+       if (event_data->client_id[0] != 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "clientid        : %s", event_data->client_id);
+               OCRepPayloadSetPropString(registerPayload, OC_RSRVD_ES_CLIENTID, event_data->client_id);
+       }
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "OCToCATransportFlags(CT_ADAPTER_TCP)");
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+       //CASelectCipherSuite(0x35, (1 << 4));
+#endif
+
+       if (is_empty_request_handle() == true) {
+               result = OCDoResource(&g_req_handle, OC_REST_POST, targetUri, NULL, (OCPayload *) registerPayload, CT_ADAPTER_TCP, OC_LOW_QOS, &cb_data, NULL, 0);
+
+               if (result == OC_STACK_OK && timeoutHandler != NULL) {
+                       if (add_request_handle(g_req_handle) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] ReqHandles array space is small.");
+                               goto no_memory;
+                       }
+
+                       create_time_out_process(g_req_handle, timeoutHandler, timeout);
+               }
+       }
+
+       return result;
+
+no_memory:
+       OCRepPayloadDestroy(registerPayload);
+       return OC_STACK_NO_MEMORY;
+}
+
+/**
+ * @brief                  Send Sign-IN request to Cloud.
+ * @param host             wanted Cloud address. (unit: const char*) \n
+ *                         Ex) coaps+tcp://123.123.123.123:1234
+ * @param uId              Identifier of User. (unit: const char*)
+ * @param device_id         Identifier of device. (unit: const char*)
+ * @param accesstoken      received access-token from Cloud.
+ * @param response         Call-Back function when cloud response against this request.
+ * @param timeoutHandler   Call function when Time-out is occurred.
+ * @param timeout          Data structure pointer for Time-out processing Data.
+ * @return                 success : OC_STACK_OK \n
+ *                         failure : other value
+ */
+OCStackResult things_cloud_session(const char *host, const char *uId, const char *device_id, const char *accesstoken, bool isLogin, OCClientResponseHandler response, check_time_out_call_func timeoutHandler, timeout_s *timeout)
+{
+       OCDoHandle g_req_handle = NULL;
+       OCStackResult result = OC_STACK_ERROR;
+       char targetUri[MAX_URI_LENGTH * 2] = { 0, };
+       char *coreVer = NULL;
+       char *IoTivityVer = NULL;
+
+       if (accesstoken == NULL || accesstoken[0] == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "accesstoken is invalid.(0x%X)", accesstoken);
+               return OC_STACK_ERROR;
+       }
+
+       snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, OC_RSRVD_ACCOUNT_SESSION_URI);
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "Initiate Session with : %s", targetUri);
+
+       OCCallbackData cb_data;
+       memset(&cb_data, 0, sizeof(OCCallbackData));
+       cb_data.cb = response;
+       cb_data.cd = NULL;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+       OCRepPayload *loginoutPayload = OCRepPayloadCreate();
+       if (!loginoutPayload) {
+               goto no_memory;
+       }
+
+       if (OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, (void **)&coreVer) != OC_STACK_OK || (IoTivityVer = strdup(IOTIVITY_VERSION)) == NULL)
+//            OCGetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_VERSION, (void**)&IoTivityVer) != OC_STACK_OK )
+       {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Getting Core_Spec_Ver or IoTivity_Ver is failed.");
+               goto no_memory;
+       }
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "coreversion      : %s", coreVer);
+       THINGS_LOG_D(THINGS_INFO, TAG, "verticalversion  : %s", IoTivityVer);
+
+       if (uId != NULL) {
+               OCRepPayloadSetPropString(loginoutPayload, KEY_ID_USER, uId);
+       }
+       OCRepPayloadSetPropString(loginoutPayload, KEY_ID_DEVICE, device_id);
+       OCRepPayloadSetPropString(loginoutPayload, KEY_TOKEN_ACCESS, accesstoken);
+       OCRepPayloadSetPropBool(loginoutPayload, KEY_LOGINOUT, isLogin);
+       OCRepPayloadSetPropString(loginoutPayload, KEY_ICORE_VER, coreVer);
+       OCRepPayloadSetPropString(loginoutPayload, KEY_IOTIVITY_VER, IoTivityVer);
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+       //CASelectCipherSuite(0x35, (1 << 4));
+#endif
+
+       if (is_empty_request_handle() == true) {
+               result = OCDoResource(&g_req_handle, OC_REST_POST, targetUri, NULL, (OCPayload *) loginoutPayload, CT_ADAPTER_TCP, OC_LOW_QOS, &cb_data, NULL, 0);
+
+               if (result == OC_STACK_OK && timeoutHandler != NULL) {
+                       if (add_request_handle(g_req_handle) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] ReqHandles array space is small.");
+                               goto no_memory;
+                       }
+
+                       create_time_out_process(g_req_handle, timeoutHandler, timeout);
+               }
+       }
+
+       if (IoTivityVer) {
+               things_free(IoTivityVer);
+               IoTivityVer = NULL;
+       }
+       if (coreVer) {
+               things_free(coreVer);
+               coreVer = NULL;
+       }
+       return result;
+
+no_memory:
+       if (IoTivityVer) {
+               things_free(IoTivityVer);
+               IoTivityVer = NULL;
+       }
+       if (coreVer) {
+               things_free(coreVer);
+               coreVer = NULL;
+       }
+       OCRepPayloadDestroy(loginoutPayload);
+       return OC_STACK_NO_MEMORY;
+}
+
+/**
+ * @brief                  Send Resources Publish request to Cloud.
+ * @param host             wanted Cloud address. (unit: const char*)\n
+ *                         Ex) coaps+tcp://123.123.123.123:1234
+ * @param list             Resource List pointer for Publishing to Cloud.
+ * @param length           Count of Resource in Resource List(list).
+ * @param response         Call-Back function when cloud response against this request.
+ * @param timeoutHandler   Call function when Time-out is occurred.
+ * @param timeout          Data structure pointer for Time-out processing Data.
+ * @return                 success : OC_STACK_OK \n
+ *                         failure : other value
+ */
+OCStackResult things_cloud_rsc_publish(char *host, things_resource_s **list, int length, OCClientResponseHandler response, check_time_out_call_func timeoutHandler, timeout_s *timeout)
+{
+       OCStackResult result = OC_STACK_ERROR;
+       THINGS_LOG_D(THINGS_INFO, TAG, "Resource Publish Start.");
+
+       OCDoHandle g_req_handle = NULL;
+       OCCallbackData cb_data;
+       cb_data.cb = response;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+       cb_data.cd = NULL;
+
+       OCResourceHandle resourceHandles[length + 2];
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "Publishing [%d] number of resources ", length);
+       int iter = 0;
+       for (iter = 0; iter < length; iter++) {
+               resourceHandles[iter] = list[iter]->resource_handle;
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "URI : %s ", list[iter]->uri);
+       }
+
+       uint8_t numResource = 0;
+       OCGetNumberOfResources(&numResource);
+       if (numResource > 0) {
+               for (uint8_t index = 0; index < numResource; index++) {
+                       OCResourceHandle handle = OCGetResourceHandle(index);
+
+                       const char *uri = OCGetResourceUri(handle);
+
+                       if (0 == strncmp(uri, OC_RSRVD_DEVICE_URI, strlen(OC_RSRVD_DEVICE_URI))
+                               || 0 == strncmp(uri, OC_RSRVD_PLATFORM_URI, strlen(OC_RSRVD_PLATFORM_URI))) {
+                               resourceHandles[iter++] = handle;
+                       }
+               }
+       }
+
+       if (is_empty_request_handle() == true) {
+               result = OCRDPublish(&g_req_handle, host, CT_ADAPTER_TCP, resourceHandles, iter, &cb_data, OC_LOW_QOS);
+
+               if (result == OC_STACK_OK && timeoutHandler != NULL) {
+                       if (add_request_handle(g_req_handle) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] ReqHandles array space is small.");
+                               return OC_STACK_ERROR;
+                       }
+
+                       create_time_out_process(g_req_handle, timeoutHandler, timeout);
+               }
+       }
+
+       return result;
+}
+
+OCStackResult things_cloud_rsc_publish_with_device_id(char *host, const char *id, things_resource_s **list, int length, OCClientResponseHandler response, check_time_out_call_func timeoutHandler, timeout_s *timeout)
+{
+       OCStackResult result = OC_STACK_ERROR;
+       THINGS_LOG_D(THINGS_INFO, TAG, "Resource Publish Start.");
+
+       OCDoHandle g_req_handle = NULL;
+       OCCallbackData cb_data;
+       cb_data.cb = response;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+       cb_data.cd = NULL;
+
+       OCResourceHandle resourceHandles[length + 2];
+
+       THINGS_LOG_V(THINGS_INFO, TAG, "Device ID ==> %s ", id);
+       THINGS_LOG_V(THINGS_INFO, TAG, "Publishing [%d] number of resources ", length);
+
+       int iter = 0;
+       for (iter = 0; iter < length; iter++) {
+               resourceHandles[iter] = list[iter]->resource_handle;
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "URI : %s ", list[iter]->uri);
+       }
+
+       if (iter > 0) {
+               result = OCRDPublishWithDeviceId(&g_req_handle, host, id, CT_ADAPTER_TCP, resourceHandles, iter, &cb_data, OC_LOW_QOS);
+       }
+//    if(result == OC_STACK_OK && timeoutHandler != NULL )
+//    {
+//        if( add_request_handle(g_req_handle) == NULL )
+//        {
+//            THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] ReqHandles array space is small.");
+//            return OC_STACK_ERROR;
+//        }
+//
+//        create_time_out_process(g_req_handle, timeoutHandler, timeout);
+//    }
+
+       return result;
+}
+
+/**
+ * @brief                  Send Dev-Profile Publish request to Cloud.
+ * @param host             wanted Cloud address. (unit: const char*)\n
+ *                         Ex) coaps+tcp://123.123.123.123:1234
+ * @param response         Call-Back function when cloud response against this request.
+ * @param timeoutHandler   Call function when Time-out is occurred.
+ * @param timeout          Data structure pointer for Time-out processing Data.
+ * @return                 success : OC_STACK_OK \n
+ *                         failure : other value
+ */
+OCStackResult things_cloud_dev_profile_publish(char *host, OCClientResponseHandler response, check_time_out_call_func timeoutHandler, timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Device-profile Publish Start.");
+
+       long devCnt = 0;
+       st_device_s *dev_info = NULL;
+       int cntArrayPayload = 0;
+       OCRepPayload **arrayPayload = NULL;
+       OCRepPayload *payload = NULL;
+       OCCallbackData cb_data;
+       OCDoHandle g_req_handle = NULL;
+       OCStackResult result = OC_STACK_ERROR;
+       char targetUri[MAX_URI_LENGTH * 2] = { 0, };
+       char *coreVer = NULL;
+       char *IoTivityVer = NULL;
+
+       if ((devCnt = dm_get_num_of_dev_cnt()) < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not exist device to publish profile-Info of Device.");
+               return OC_STACK_ERROR;
+       }
+
+       snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, OC_RSRVD_ACCOUNT_DEVPROFILE_URI);
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "Initiate DevProfile with : %s", targetUri);
+
+       cb_data.cb = response;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+       cb_data.cd = NULL;
+
+       payload = OCRepPayloadCreate();
+       if (!payload) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] memory allocation is failed.(payload)");
+               goto no_memory;
+       }
+
+       if ((arrayPayload = (OCRepPayload **) things_malloc(sizeof(OCRepPayload *) * devCnt)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] memory allocation is failed.(arrayPayload)");
+               goto no_memory;
+       }
+       // Add All-device-info
+       for (unsigned long i = 0; i < devCnt; i++) {
+               if ((dev_info = dm_get_info_of_dev(i)) == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] device info structure is NULL.(seq=%d)", i);
+                       goto no_memory;
+               }
+
+               if (dev_info->is_physical == 1) {
+                       if ((arrayPayload[cntArrayPayload] = make_dev_profile_payload(dev_info)) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "It's failed making payload of Device-Info.(seq=%d)", cntArrayPayload);
+                               goto no_memory;
+                       }
+                       cntArrayPayload++;
+               }
+       }
+
+       if (cntArrayPayload < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] pysical device is not exist. So, Can not Sending request for Device-Profile.");
+               goto no_memory;
+       }
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { cntArrayPayload, 0, 0 };
+       OCRepPayloadSetPropObjectArray(payload, "devices", arrayPayload, dimensions);
+
+       if (is_empty_request_handle() == true) {
+               result = OCDoResource(&g_req_handle, OC_REST_POST, targetUri, NULL, (OCPayload *) payload, CT_ADAPTER_TCP, OC_LOW_QOS, &cb_data, NULL, 0);
+
+               if (result == OC_STACK_OK && timeoutHandler != NULL) {
+                       if (add_request_handle((OCDoHandle) 1) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] ReqHandles array space is small.");
+                               /*for SVACE Warning */
+                               if (arrayPayload) {
+                                       for (int i = 0; i < cntArrayPayload; i++) {
+                                               OCPayloadDestroy((OCPayload *) arrayPayload[i]);
+                                       }
+                                       things_free(arrayPayload);
+                                       arrayPayload = NULL;
+                               }
+                               return OC_STACK_ERROR;
+                       }
+
+                       create_time_out_process((OCDoHandle) 1, timeoutHandler, timeout);
+               }
+       }
+
+       if (arrayPayload) {
+               for (int i = 0; i < cntArrayPayload; i++) {
+                       OCPayloadDestroy((OCPayload *) arrayPayload[i]);
+               }
+               things_free(arrayPayload);
+               arrayPayload = NULL;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit. -Success-");
+       return result;
+
+no_memory:
+
+       if (arrayPayload) {
+               for (int i = 0; i < cntArrayPayload; i++) {
+                       OCPayloadDestroy((OCPayload *) arrayPayload[i]);
+               }
+               things_free(arrayPayload);
+               arrayPayload = NULL;
+       }
+       OCRepPayloadDestroy(payload);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit. -Fail-");
+       return OC_STACK_NO_MEMORY;
+}
+
+/**
+ * @brief                  Send Refresh access-token request to Cloud.\n
+ *                         Set should call refresh before expiresin of refresh-token or when receive 4.01 during sign-in
+ * @param host             wanted Cloud address. (unit: const char*) \n
+ *                         Ex) coaps+tcp://123.123.123.123:1234
+ * @param uId              Identifier of User.
+ * @param device_id         Identifier of Device.
+ * @param refreshtoken     Token for refreshing access-token from Cloud.
+ * @param response         Call-Back function when cloud response against this request.
+ * @return                 success : OC_STACK_OK \n
+ *                         failure : other value
+ */
+OCStackResult things_cloud_refresh(const char *host, const char *uId, const char *device_id, const char *refreshtoken, OCClientResponseHandler response)
+{
+       char targetUri[MAX_URI_LENGTH * 2] = { 0, };
+       snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI);
+
+       OCCallbackData cb_data;
+       memset(&cb_data, 0, sizeof(OCCallbackData));
+       cb_data.cb = response;
+       cb_data.cd = NULL;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+       OCRepPayload *refreshPayload = OCRepPayloadCreate();
+       if (!refreshPayload) {
+               goto no_memory;
+       }
+
+       if (uId != NULL) {
+               OCRepPayloadSetPropString(refreshPayload, KEY_ID_USER, uId);
+       }
+       OCRepPayloadSetPropString(refreshPayload, KEY_ID_DEVICE, device_id);
+       OCRepPayloadSetPropString(refreshPayload, KEY_TYPE_GRANT, VALUE_TYPE_GRANT_TOKEN);
+       OCRepPayloadSetPropString(refreshPayload, KEY_TOKEN_ACCESS_REFRESH, refreshtoken);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "targetURI    =%s", targetUri);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "uid          =%s", uId);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "di           =%s", device_id);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "granttype    =%s", VALUE_TYPE_GRANT_TOKEN);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "refreshtoken =%s", refreshtoken);
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+       //CASelectCipherSuite(0x35, (1 << 4));
+#endif
+
+       return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) refreshPayload, CT_ADAPTER_TCP, OC_LOW_QOS, &cb_data, NULL, 0);
+
+no_memory:
+       OCRepPayloadDestroy(refreshPayload);
+       return OC_STACK_NO_MEMORY;
+}
+
+OCStackResult things_cloud_topic_publish_topic(const char *host, const char *topic, OCRepPayload *message, OCClientResponseHandler response)
+{
+       char targetUri[MAX_URI_LENGTH * 2] = { 0, };
+
+       snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, topic);
+
+       OCCallbackData cb_data;
+       memset(&cb_data, 0, sizeof(OCCallbackData));
+       cb_data.cb = response;
+       cb_data.cd = NULL;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+       if (!message) {
+               goto no_memory;
+       }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+       //CASelectCipherSuite(0x35, (1 << 4));
+#endif
+       return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) message, CT_ADAPTER_TCP, OC_LOW_QOS, &cb_data, NULL, 0);
+
+no_memory:
+       OCRepPayloadDestroy(message);
+       return OC_STACK_NO_MEMORY;
+}
+
+static OCRepPayload *make_dev_profile_payload(const st_device_s *dev_info)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       bool res = false;
+       char *manuFactory = NULL;
+       char *coreVer = NULL;
+       char *IoTivityVer = NULL;
+       OCRepPayload *payload = NULL;
+
+       if (dev_info == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "input argument is invalid.(dev_info is null)");
+               return NULL;
+       }
+
+       if ((payload = OCRepPayloadCreate()) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.(payload)");
+               return NULL;
+       }
+
+       if (OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, (void **)&coreVer) != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Getting CoreVersion of IoTivity is failed.");
+               goto GOTO_OUT;
+       }
+
+       IoTivityVer = strdup(IOTIVITY_VERSION);
+
+       if (OCGetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_NAME, (void **)&manuFactory) != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Getting manufacturer-name is failed.");
+               goto GOTO_OUT;
+       }
+
+       OCRepPayloadSetPropString(payload, "di", dev_info->device_id);
+       OCRepPayloadSetPropString(payload, "n", dev_info->name);
+       OCRepPayloadSetPropString(payload, "icv", coreVer);
+       OCRepPayloadSetPropString(payload, "dmv", IoTivityVer);
+//    OCRepPayloadSetPropString(payload, "vrv", );
+       OCRepPayloadSetPropString(payload, "rt", dev_info->type);
+       OCRepPayloadSetPropString(payload, "mnmn", manuFactory);
+       OCRepPayloadSetPropString(payload, "mnmo", dev_info->model_num);
+       OCRepPayloadSetPropString(payload, "mnpv", dev_info->ver_p);
+       OCRepPayloadSetPropString(payload, "mnos", dev_info->ver_os);
+       OCRepPayloadSetPropString(payload, "mnhw", dev_info->ver_hw);
+       OCRepPayloadSetPropString(payload, "mnfv", dev_info->ver_fw);
+       OCRepPayloadSetPropString(payload, "vid", dev_info->vender_id);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "di   = %s", dev_info->device_id);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "n    = %s", dev_info->name);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "icv  = %s", coreVer);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "dmv  = %s", IoTivityVer);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "rt   = %s", dev_info->type);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "mnmn = %s", manuFactory);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "mnmo = %s", dev_info->model_num);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "mnpv = %s", dev_info->ver_p);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "mnos = %s", dev_info->ver_os);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "mnhw = %s", dev_info->ver_hw);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "mnfv = %s", dev_info->ver_fw);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "vid  = %s", dev_info->vender_id);
+
+       res = true;
+
+GOTO_OUT:
+       if (coreVer) {
+               things_free(coreVer);
+               coreVer = NULL;
+       }
+
+       if (IoTivityVer) {
+               things_free(IoTivityVer);
+               IoTivityVer = NULL;
+       }
+
+       if (manuFactory) {
+               things_free(manuFactory);
+               manuFactory = NULL;
+       }
+
+       if (res == false) {
+               OCPayloadDestroy((OCPayload *) payload);
+               payload = NULL;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit. payload=0x%X", payload);
+       return payload;
+}
diff --git a/framework/src/st_things/things_stack/src/common/cloud/cloud_evtpend.c b/framework/src/st_things/things_stack/src/common/cloud/cloud_evtpend.c
new file mode 100644 (file)
index 0000000..6643c29
--- /dev/null
@@ -0,0 +1,156 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 <unistd.h>
+#include <pthread.h>
+
+#include "things_logger.h"
+#include "cloud_evtpend.h"
+#include "resource_handler.h"
+
+#define TAG "[cloudevtpend]"
+
+static es_cloud_pending_event_s pending_event = { false, false, false, };
+
+static pthread_mutex_t g_pending_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void ci_cp_init_event_pend(void)
+{
+       pthread_mutex_lock(&g_pending_mutex);
+       pending_event.exist = false;
+       pending_event.is_there_ci_prov = false;
+       pending_event.using_count = 0;
+       init_es_cloud_prov_data(&pending_event.event);
+       pthread_mutex_unlock(&g_pending_mutex);
+}
+
+es_cloud_prov_data_s *ci_cp_get_pended_data(void)      // [GET] If there pending-Data, then return point of Data.
+{
+       es_cloud_prov_data_s *p_event = NULL;
+
+       pthread_mutex_lock(&g_pending_mutex);
+       if (pending_event.exist == true) {
+               p_event = &pending_event.event;
+       }
+       pthread_mutex_unlock(&g_pending_mutex);
+
+       return p_event;
+}
+
+bool ci_cp_get_is_there_cp(void)       // [GET] return is_there_ci_prov value.
+{
+       bool is_there = false;
+
+       pthread_mutex_lock(&g_pending_mutex);
+       is_there = pending_event.is_there_ci_prov;
+       pthread_mutex_unlock(&g_pending_mutex);
+
+       return is_there;
+}
+
+bool ci_cp_cas_is_there_cp_if_false(void)      // [CAS] If is_there_ci_prov value is false, then set true and return is_there_ci_prov value.
+{
+       bool is_there = false;
+
+       pthread_mutex_lock(&g_pending_mutex);
+       is_there = pending_event.is_there_ci_prov;
+       if (is_there == false) {
+               pending_event.is_there_ci_prov = true;
+       }
+       pthread_mutex_unlock(&g_pending_mutex);
+
+       return is_there;
+}
+
+void ci_cp_del_pended_data(void)       // [SET] Setting false to Flag about existing of pending-Data.
+{
+       bool b_continue = true;
+
+       while (b_continue) {
+               pthread_mutex_lock(&g_pending_mutex);
+               if (pending_event.exist == false || pending_event.using_count == 0) {
+                       pending_event.exist = false;
+                       b_continue = false;
+               }
+               pthread_mutex_unlock(&g_pending_mutex);
+
+               if (b_continue == true) {
+                       usleep(100000);         // 0.1 seconds delay.
+               }
+       }
+}
+
+void ci_cp_del_is_there_cp(void)       // [SET] Setting false to Flag about existing of new CP-data.
+{
+       pthread_mutex_lock(&g_pending_mutex);
+       pending_event.is_there_ci_prov = false;
+       pthread_mutex_unlock(&g_pending_mutex);
+}
+
+int ci_cp_pend_event_data(es_cloud_prov_data_s *event_data)    // [SET] Setting true all Flag and Store Event-Data to pending repo.
+{
+       if (event_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Event Data is NULL.");
+               return 0;
+       }
+
+       bool b_continue = true;
+
+       while (b_continue) {
+               pthread_mutex_lock(&g_pending_mutex);
+               if (pending_event.using_count == 0) {
+                       pending_event.exist = true;
+                       pending_event.is_there_ci_prov = true;
+
+                       if (event_data != &pending_event.event) {
+                               clone_es_cloud_prov_data(&pending_event.event, event_data);
+                       }
+                       b_continue = false;
+               }
+               pthread_mutex_unlock(&g_pending_mutex);
+
+               if (b_continue == true) {
+                       usleep(100000);         // 0.1 seconds delay.
+               }
+       }
+
+       return 1;
+}
+
+int ci_cp_enter_pend_data_block(void)
+{
+       int using_cnt = 0;
+
+       pthread_mutex_lock(&g_pending_mutex);
+       pending_event.using_count++;
+       using_cnt = pending_event.using_count;
+       pthread_mutex_unlock(&g_pending_mutex);
+
+       return using_cnt;
+}
+
+int ci_cp_release_penddata_block(void)
+{
+       int using_cnt = 0;
+
+       pthread_mutex_lock(&g_pending_mutex);
+       pending_event.using_count--;
+       using_cnt = pending_event.using_count;
+       pthread_mutex_unlock(&g_pending_mutex);
+
+       return using_cnt;
+}
diff --git a/framework/src/st_things/things_stack/src/common/cloud/cloud_manager.c b/framework/src/st_things/things_stack/src/common/cloud/cloud_manager.c
new file mode 100644 (file)
index 0000000..b5bc0a5
--- /dev/null
@@ -0,0 +1,2490 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#define _BSD_SOURCE
+
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <time.h>
+
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "cautilinterface.h"
+
+#include "es_common.h"
+#include "cacommon.h"
+#include "things_string_util.h"
+#include "things_def.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_data_manager.h"
+#include "cloud_connector.h"
+#include "cloud_manager.h"
+#include "cloud_evtpend.h"
+#include "things_types.h"
+#include "easysetup.h"
+#include "easysetup_manager.h"
+#include "resource_handler.h"
+#include "../utils/inc/things_network.h"
+#include "NSProviderInterface.h"
+#include "things_ping.h"
+#include "things_thread.h"
+#include "things_security_manager.h"
+#include "things_rtos_util.h"
+
+#define DEFAULT_CI_HOST         "52.40.216.160:5683"   //!< Non Security Cloud IPv4:Port. Not used in common.
+#define MAX_CI_ADDRESS          256
+#define RESOURCE_DISCOVERY_QUERY "/oic/res"
+#define RESOURCE_DISCOVERY_QUERY_DI "/oic/res?di="
+
+#define ERR_UPPER_UNIT  10000  //!< Unit of Network-State for Cloud Error-Code
+#define MAX_SIGNUP_SENDNUM  1  //!< Max re-transmission count of send_cnt_sign_up variable.
+#define MAX_RETRY_RSCPUBLISH    10     //!< Max re-transmission count of retranslate_rsc_publish_cnt variable.
+
+#define TAG "[cloudmnger]"
+
+typedef void *(*pthread_func_type)(void *);
+
+/*! Cloud Session Management enum. */
+typedef enum {
+       CISESS_NULL = -2,
+       CISESS_APDISCON = -1,           //!< -1 : AP Disconnected.
+       CISESS_STOP = 0,                        //!<  0 : Cloud Connection Disconnected & AP Connected.
+       CISESS_BUSY = 1,                        //!<  1 : Cloud Connection Connecting & Connected. (Busy)
+       CISESS_STOP_TRIGGER = 2,        //!<  2 : Triggered for Cloud Connection disconnect.
+       CISESS_SIGNOUT = 3                      //!<  3 : Sign-Out from Cloud.
+} ci_session_level_e;
+
+/*! Provisioned Data + Time-Out Data. */
+typedef struct es_cloud_event_timeout_s {
+       timeout_s timeOut;                      //!< Time-Out value(unit: seconds)
+       es_cloud_prov_data_s event;     //!< Cloud Provisioned Data
+} es_cloud_event_timeout_s;
+
+volatile static ci_session_level_e g_qis_cloud_thread_running = CISESS_APDISCON;       //!< Variable for managing Cloud session.(No cached)
+
+static int send_cnt_sign_up = 0;       //!< Counter for Sign-UP re-transmission process.
+static int retranslate_rsc_publish_cnt = 0;    //!< Counter for Resource-Publish re-transmission process.
+
+static pthread_mutex_t g_es_mutex = PTHREAD_MUTEX_INITIALIZER; //!< Mutex variable for thread-safety of start_ci_connection().
+static pthread_mutex_t g_es_tcp_session_mutex = PTHREAD_MUTEX_INITIALIZER;     //!< Mutex variable for thread-safety of ci_retry_stop_by_tcp_cb().
+
+static char g_cloud_ip[IP_PORT] = { 0, };      //!< Current Connected Cloud Ipv4 address.
+static char g_cloud_port[IP_PORT] = { 0, };    //!< Current Connected Cloud Port number.
+static char g_cloud_address[MAX_CI_ADDRESS] = { 0, };  //!< Current Connected Cloud Address.
+
+static es_cloud_signup_s *signed_up_data = NULL;       
+
+static things_server_builder_s *g_server_builder = NULL;       //!< Server-Builder pointer to get Resource List.
+static things_resource_s **g_resource_lists = NULL;    //!< Resource List pointer to be publishing resources to Cloud.
+static int g_len = 0;                  //!< EA of Resources in "g_resource_lists" variable.
+
+static things_cloud_con_result_func_type things_res_cb_function = NULL;        //!< call-back Function pointer : it's called when finish Cloud-Connection.
+
+static OCStackResult publish_resource_main_dev_into_cloud(things_resource_s **list, int length, timeout_s *timeout);
+static int cloud_retry_sign_up(es_cloud_prov_data_s *event_data, timeout_s *timeout);
+static char *make_cloud_address(char *ip, char *port, const char *ci_addr);
+static void cloud_request_retry_trigger(timeout_s *timeout);
+static es_cloud_prov_data_s *if_failed_then_retry(OCDoHandle handle, OCStackResult result, int *n_err);
+static void force_session_stop(ci_session_level_e state);
+static int es_cloud_state_set_and_notify(things_cloud_status_e state, es_error_code_e es_err, OCClientResponse *response, ci_error_code_e *ci_err);
+static int get_cloud_code(OCClientResponse *response, OCMethod method, ci_error_code_e *err);
+static CAResponseResult_t things_result_to_network_result(OCStackResult oc_code, OCMethod method);
+static char *make_ip_port(char *p_ip, char *p_port);
+static es_cloud_event_timeout_s *clone_data_add_timeout(es_cloud_prov_data_s *cloud_data, timeout_s *timeout);
+static void ci_finish_cloud_con(int result);
+static void publish_dev_profile_into_cloud(timeout_s *timeout);
+
+static void *handle_signup_timeout(timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Sign-UP is Time-Out.");
+
+       es_cloud_prov_data_s *pend_cloud_data = NULL;
+
+       if (timeout == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] timeout is NULL.");
+               return 0;
+       }
+
+       send_cnt_sign_up++;
+
+       if (send_cnt_sign_up <= MAX_SIGNUP_SENDNUM) {
+               if ((pend_cloud_data = ci_cp_get_pended_data()) != NULL) {
+                       timeout->cur_counter = timeout->cur_num;
+                       THINGS_LOG_V(THINGS_INFO, TAG, "Sign-UP Request Send is re-tryed(%d).", send_cnt_sign_up);
+                       if (cloud_retry_sign_up(pend_cloud_data, timeout) == 0) {
+                               send_cnt_sign_up = MAX_SIGNUP_SENDNUM + 1;
+                       }
+               } else {
+                       send_cnt_sign_up = MAX_SIGNUP_SENDNUM + 1;
+               }
+       }
+
+       if (send_cnt_sign_up > MAX_SIGNUP_SENDNUM) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Sign-UP Re-Try Request Send is failed.");
+
+               oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD | PING_ST_SIGNIN);
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ES_ERRCODE_NO_RESPONSE_FROM_CLOUD_SERVER, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+               }
+
+               force_session_stop(CISESS_NULL);
+               send_cnt_sign_up = 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return 0;
+}
+
+static void *handle_signin_timeout(timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Sign-IN is Time-Out.");
+
+       if (timeout == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] timeout is NULL.");
+               return 0;
+       }
+
+       int thres_hold = timeout->ori_num * 10; // PDF thres_hold 0.2 --> 5
+
+       if (timeout->cur_num < thres_hold && (timeout->cur_num = (int)next_time_out((long long)timeout->ori_num, (long long)timeout->cur_num)) != -1) {
+               if (timeout->cur_num > thres_hold) {
+                       timeout->cur_num = thres_hold;
+               }
+               timeout->cur_counter = timeout->cur_num;
+
+               THINGS_LOG_V(THINGS_INFO, TAG, "Sign-IN Request Send is re-tryed. (PDF interval:%d)", timeout->cur_num);
+
+               force_session_stop(CISESS_SIGNOUT);
+               cloud_request_retry_trigger(timeout);
+       } else {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Sign-IN Re-Try Request Send is failed.");
+
+               oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD | PING_ST_SIGNIN);
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ES_ERRCODE_NO_RESPONSE_FROM_CLOUD_SERVER, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+               }
+
+               force_session_stop(CISESS_NULL);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return 0;
+}
+
+static void *handle_publish_timeout(timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Resource-Publish is Time-Out.");
+
+       if (timeout == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] timeout is NULL.");
+               return 0;
+       }
+
+       int thres_hold = timeout->ori_num * 5;  // PDF thres_hold 0.2 --> 5
+
+       if (timeout->cur_num < thres_hold && (timeout->cur_num = (int)next_time_out((long long)timeout->ori_num, (long long)timeout->cur_num)) != -1) {
+               if (timeout->cur_num > thres_hold) {
+                       timeout->cur_num = thres_hold;
+               }
+               timeout->cur_counter = timeout->cur_num;
+
+               THINGS_LOG_V(THINGS_INFO, TAG, "RSC_Publish Request Send is re-tryed. (PDF interval:%d)", timeout->cur_num);
+               publish_resource_into_cloud(RSC_PUB_MAIN_ONLY, timeout);
+       } else {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Resource-Publish Re-Try Request Sending is failed.");
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD, ES_ERRCODE_NO_RESPONSE_FROM_CLOUD_SERVER, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+               }
+
+               force_session_stop(CISESS_NULL);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return 0;
+}
+
+static void *handle_dev_profile_timeout(timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Device Profile Publish is Time-Out.");
+
+       if (timeout == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] timeout is NULL.");
+               return 0;
+       }
+
+       int thres_hold = timeout->ori_num * 5;  // PDF thres_hold 0.2 --> 5
+
+       if (timeout->cur_num < thres_hold && (timeout->cur_num = (int)next_time_out((long long)timeout->ori_num, (long long)timeout->cur_num)) != -1) {
+               if (timeout->cur_num > thres_hold) {
+                       timeout->cur_num = thres_hold;
+               }
+               timeout->cur_counter = timeout->cur_num;
+
+               THINGS_LOG_V(THINGS_INFO, TAG, "Device Profile Request Send is re-tryed. (PDF interval:%d)", timeout->cur_num);
+               publish_dev_profile_into_cloud(timeout);
+       } else {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Device Profile publish Re-Try Request Sending is failed.");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return 0;
+}
+
+static int set_def_cloud_info(es_cloud_signup_s *cloud_info, const char *cloud_addr, const es_cloud_prov_data_s *prov_data)
+{
+       int result = 1;
+       char *ip_port = NULL;
+       char *m_domain = NULL;
+       char *t_domain = NULL;
+
+       if (cloud_info == NULL || cloud_addr == NULL || cloud_addr[0] == 0) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Parameter value is invalid.(cloud_info=0x%X, coud_addr=%s)", cloud_info, cloud_addr);
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cloud_addr = %s", cloud_addr);
+
+       if (cloud_info->address != NULL) {
+               things_free(cloud_info->address);
+               cloud_info->address = NULL;
+       }
+
+       if (cloud_info->port != NULL) {
+               things_free(cloud_info->port);
+               cloud_info->port = NULL;
+       }
+
+       if (cloud_info->domain != NULL) {
+               things_free(cloud_info->domain);
+               cloud_info->domain = NULL;
+       }
+
+       ip_port = strstr(cloud_addr, "://");
+       if (ip_port == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "cloud_addr is invalid.");
+               return 0;
+       }
+       ip_port = ip_port + 3;
+
+       if ((cloud_info->address = (char *)things_malloc(sizeof(char) * MAX_CI_ADDRESS)) == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Cloud_info address memory allocation is Failed.");
+               return 0;
+       }
+
+       things_strncpy(cloud_info->address, ip_port, MAX_CI_ADDRESS);   // Ip:Port  save.
+
+       // if exist Cloud m_domain Name, then Save Name and Port.
+       if (cloud_info->redirect_uri != NULL && strlen(cloud_info->redirect_uri) > 0) {
+               m_domain = strdup(cloud_info->redirect_uri);
+       } else if (prov_data != NULL) {
+               m_domain = strdup(prov_data->host_name);
+       }
+
+       if (m_domain != NULL && strlen(m_domain) != 0) {
+               t_domain = m_domain;
+               if (strstr(m_domain, "://") != NULL) {
+                       t_domain = strstr(m_domain, "://") + 3;
+               }
+
+               if (strchr(t_domain, ':') != NULL) {
+                       ip_port = strchr(t_domain, ':');
+                       *ip_port = NULL;
+                       ip_port++;
+               } else {
+                       if ((ip_port = strchr(ip_port, ':')) == NULL) {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Not exit Port number.");
+                               result = 0;
+                               goto GOTO_OUT;
+                       }
+                       ip_port++;
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "m_domain = %s", t_domain);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Port   = %s", ip_port);
+
+               int length_port = strlen(ip_port) + 1;
+               int length_domain = strlen(t_domain) + 1;
+
+               if ((cloud_info->port = (char *)things_malloc(sizeof(char) * length_port)) == NULL) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Cloud_info port memory allocation is Failed.");
+                       result = 0;
+                       goto GOTO_OUT;
+               }
+
+               if ((cloud_info->domain = (char *)things_malloc(sizeof(char) * length_domain)) == NULL) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Cloud_info domain-name memory allocation is Failed.");
+                       result = 0;
+                       goto GOTO_OUT;
+               }
+
+               things_strncpy(cloud_info->port, ip_port, length_port); // Cloud Port save.
+
+               things_strncpy(cloud_info->domain, t_domain, length_domain);    // Cloud domain name save.
+       }
+
+       if (cloud_info->refresh_token == NULL) {
+               if (prov_data == NULL || prov_data->refreshtoken[0] == 0) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Not exist Refresh Token. please check your system.");
+                       result = 0;
+                       goto GOTO_OUT;
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "refreshtoken = %s", prov_data->refreshtoken);
+
+               int length_refresh = strlen(prov_data->refreshtoken) + 1;
+
+               if ((cloud_info->refresh_token = (char *)things_malloc(sizeof(char) * length_refresh)) == NULL) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Cloud_info port memory allocation is Failed.");
+                       result = 0;
+                       goto GOTO_OUT;
+               }
+
+               things_strncpy(cloud_info->refresh_token, prov_data->refreshtoken, length_refresh);     // Cloud Refresh Token save.
+       }
+
+GOTO_OUT:
+       if (m_domain) {
+               things_free(m_domain);
+               m_domain = NULL;
+               t_domain = NULL;
+       }
+       ip_port = NULL;
+
+       if (result == 0) {
+               if (cloud_info->address) {
+                       things_free(cloud_info->address);
+                       cloud_info->address = NULL;
+               }
+
+               if (cloud_info->port) {
+                       things_free(cloud_info->port);
+                       cloud_info->port = NULL;
+               }
+
+               if (cloud_info->domain) {
+                       things_free(cloud_info->domain);
+                       cloud_info->domain = NULL;
+               }
+       }
+
+       return result;
+}
+
+OCStackApplicationResult handle_register_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       int res = OC_STACK_DELETE_TRANSACTION;
+       int n_err = 0;
+       es_cloud_prov_data_s *proved_data = NULL;
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Register callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Register response received code: %s(%d)", get_result(client_response->result), client_response->result);
+       if ((proved_data = if_failed_then_retry(handle, client_response->result, &n_err)) == NULL) {
+               if (n_err == 1 || n_err == 4) { // OC_STACK_COMM_ERROR or Handle is invalid.
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "OC_STACK_COMM_ERROR(1) or Handle InValid(4) : %d", n_err);
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "System Error occurred.(proved_data=0x%X, n_err=%d)", proved_data, n_err);
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+               }
+
+               return OC_STACK_DELETE_TRANSACTION;
+       }
+
+       send_cnt_sign_up = 0;
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "PAYLOAD_TYPE_REPRESENTATION received");
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "You can login using received session variable after disconnected or reboot");
+
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val != NULL) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int ", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+
+                       oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD | PING_ST_SIGNIN);
+
+                       if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, (ci_error_code_e) NULL, client_response, &ci_err) != 0) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                               res = OC_STACK_DELETE_TRANSACTION;
+                               goto GOTO_OUT;
+                       }
+
+                       switch (ci_err) {
+                       case ERRCI_NOT_ACCEPTABLE:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Cloud received duplicated-request in 500msec. retry-again");
+                               if (g_qis_cloud_thread_running != CISESS_APDISCON) {
+                                       cloud_request_retry_trigger(NULL);
+                               }
+                               break;
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_SAMSUNG_ACCOUNT_UNAUTHORIZED_TOKEN:
+                       case ERRCI_SAMSUNG_ACCOUNT_AUTHORIZATION_FAILED:
+                       case ERRCI_FORBIDDEN:
+                       case ERRCI_USER_NOT_FOUND:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE] %d : fix the information and try again.", ci_err);
+                               if (cloud_retry_sign_in(NULL) != 0) {
+                                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Cloud connection Re-try is failed.");
+                               }
+                               res = OC_STACK_DELETE_TRANSACTION;
+                               break;
+                       case ERRCI_DEVICE_DUPLICATE_PARAM:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE] %d : check your device_id and try again.", ci_err);
+                               ;                               // TODO : need cloud definition.
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               esm_get_network_status();       // State return
+                               res = OC_STACK_DELETE_TRANSACTION;
+                               break;
+                       }
+
+                       goto GOTO_OUT;
+               }
+
+               if (es_cloud_signup_init(&signed_up_data) == false) {
+                       es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "signed_up_data-memory allocation is Failed, try again.");
+                       res = OC_STACK_DELETE_TRANSACTION;
+                       goto GOTO_OUT;
+               }
+               // [Kes] get Signed-data but mandatory key-value are follows. (accesstoken / refreshtoken / token_type / expiresin / uid)
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_TOKEN_ACCESS, &signed_up_data->access_token);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_TOKEN_ACCESS_REFRESH, &signed_up_data->refresh_token);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_TOKEN_TYPE, &signed_up_data->token_type);
+               OCRepPayloadGetPropInt(((OCRepPayload *) client_response->payload), KEY_EXPIRE_TIME, &signed_up_data->expire_time);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_ID_USER, &signed_up_data->uid);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_SERVER_REDIRECT_URI, &signed_up_data->redirect_uri);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_CERTIFICATE_FILE, &signed_up_data->certificate);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_SERVER_ID, &signed_up_data->sid);
+
+#ifdef __SECURED__
+               if (sm_save_cloud_acl(signed_up_data->sid) != 0) {      // OIC_SEC_OK(0)
+                       es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "It's failed to save Cloud UUID to ACL list.");
+                       res = OC_STACK_DELETE_TRANSACTION;
+                       goto GOTO_OUT;
+               }
+#endif                                                 //__SECURED__
+
+               if (set_def_cloud_info(signed_up_data, g_cloud_address, proved_data) == 0) {
+                       es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "signed_up_data default setting is Failed.");
+                       res = OC_STACK_DELETE_TRANSACTION;
+                       goto GOTO_OUT;
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "expiresin : %lld", signed_up_data->expire_time);
+
+               if (signed_up_data->access_token == NULL || strlen(signed_up_data->access_token) < 1) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Session Key is NULL");
+
+                       if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ES_ERRCODE_INVALID_ACCESSTOKEN, NULL, NULL) != 0) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                               res = OC_STACK_DELETE_TRANSACTION;
+                               goto GOTO_OUT;
+                       }
+               } else {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Write Sign-Up data to file.");
+                       if (dm_update_things_cloud(signed_up_data) == 0) {
+                               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Sign-UP data can not write to info file.");
+                               res = OC_STACK_DELETE_TRANSACTION;
+                               goto GOTO_OUT;
+                       }
+
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Start Login Into Cloud");
+                       log_in_out_to_cloud(true, NULL);
+                       res = OC_STACK_DELETE_TRANSACTION;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Received Failed-Response of Sign-UP without payload from Cloud Server.");
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ES_ERRCODE_UNKNOWN, NULL, NULL) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+                       res = OC_STACK_DELETE_TRANSACTION;
+                       goto GOTO_OUT;
+               }
+       }
+
+GOTO_OUT:
+       if (proved_data) {
+               things_free(proved_data);
+               proved_data = NULL;
+       }
+
+       return res;
+}
+
+/**
+ * @brief                 Call-Back function of "OCDoResource" for Cloud Sign-IN response.
+ * @param ctx             User Data. (Not used)
+ * @param handle          OCDoHandle of Request correspond to this Cloud-Response.
+ * @param client_response  Cloud Response Data.
+ * @return                Success return OC_STACK_DELETE_TRANSACTION (1)  \n
+ *                        Failed  return OC_STACK_DELETE_TRANSACTION (0)
+ */
+OCStackApplicationResult handle_login_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Login callback received");
+
+       int n_err = 0;
+       es_cloud_prov_data_s *proved_data = NULL;
+       OCStackApplicationResult res = OC_STACK_DELETE_TRANSACTION;
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Login callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Login response received code: %s(%d)", get_result(client_response->result), client_response->result);
+       proved_data = if_failed_then_retry(handle, client_response->result, &n_err);
+
+       if (proved_data) {
+               things_free(proved_data);
+               proved_data = NULL;
+       }
+
+       if (n_err >= 3 || n_err == 1) { // mem alloc error, handle is invalid.
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Memory alloc error or InValid Resp CB.(%d)", n_err);
+               return OC_STACK_DELETE_TRANSACTION;
+       }
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "PAYLOAD_TYPE_REPRESENTATION received");
+
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+
+                       oic_ping_unset_mask(g_cloud_ip, PING_ST_SIGNIN);
+
+                       if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, (ci_error_code_e) NULL, client_response, &ci_err) != 0) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                               return OC_STACK_DELETE_TRANSACTION;
+                       }
+
+                       switch (ci_err) {
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD);
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_VALIDATION_FAILED:
+                       case ERRCI_TOKEN_EXPIRED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE] AccessToken \"%d\", refresh AccessToken and try again.", ci_err);
+                               refresh_token_into_cloud();     // refresh accesstoken.
+                               break;
+                       case ERRCI_FORBIDDEN:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> URI is invalid, fix the URI and try again.");
+                               cloud_retry_sign_in(NULL);      // TODO : need re-code
+                               break;
+                       case ERRCI_DEVICE_NOT_FOUND:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Device Not Found, Check your device ID and User ID coupling.");
+                               oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD);
+                               esm_get_network_status();       // State return
+                               if (things_reset(NULL, RST_AUTO_RESET) == -1) {
+                                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] things_reset is failed.");
+                               }
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD);
+                               esm_get_network_status();       // State return
+                               break;
+                       }
+
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+
+               if (es_cloud_state_set_and_notify(ES_STATE_REGISTERED_TO_CLOUD, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+
+               oic_ping_set_mask(g_cloud_ip, atoi(g_cloud_port), PING_ST_SIGNIN);
+
+               // [ysy] Plublish resources to cloud
+               THINGS_LOG(THINGS_DEBUG, TAG, "Start OCCloudPUblish");
+               retranslate_rsc_publish_cnt = 0;
+               publish_resource_into_cloud(RSC_PUB_MAIN_ONLY, NULL);
+#ifdef ENABLE_PUSH_NOTY
+               NSProviderEnableRemoteService(g_cloud_address);
+#endif
+
+               res = OC_STACK_DELETE_TRANSACTION;
+       } else if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Received Failed-Response of Sign-IN without payload from Cloud Server.");
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ES_ERRCODE_UNKNOWN, NULL, NULL) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+       }
+
+       return res;
+}
+
+/**
+ * @brief                 Call-Back function of "OCDoResource" for Cloud Sign-OUT response.
+ * @param ctx             User Data. (Not used)
+ * @param handle          OCDoHandle of Request correspond to this Cloud-Response.
+ * @param client_response  Cloud Response Data.
+ * @return                Success return OC_STACK_DELETE_TRANSACTION (1) \n
+ *                        Failed  return OC_STACK_DELETE_TRANSACTION (0)
+ */
+OCStackApplicationResult handle_logout_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Logout callback received");
+
+       OCStackApplicationResult res = OC_STACK_DELETE_TRANSACTION;
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Logout callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Logout response received code: %s(%d)", get_result(client_response->result), client_response->result);
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "PAYLOAD_TYPE_REPRESENTATION received");
+
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+       }
+
+       if (g_qis_cloud_thread_running != CISESS_BUSY && g_qis_cloud_thread_running != CISESS_APDISCON) {
+               things_es_enrollee_state_e es_err = ES_STATE_INIT;
+
+               if (esm_get_network_status() == true) {
+                       es_err = ES_STATE_CONNECTED_TO_ENROLLER;
+               }
+
+               if (es_cloud_state_set_and_notify(es_err, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+               }
+       }
+
+       res = OC_STACK_DELETE_TRANSACTION;
+
+       return res;
+}
+
+static bool check_comm_error_retrans(OCStackResult result)
+{
+#define MAX_COMM_ERROR_RETRANSMISSION       10
+       bool ret = false;
+       static int retransmission_count = 0;
+
+       if (result == OC_STACK_COMM_ERROR) {    // Don't Send Request Message.
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Request-Send is Failed.");
+               if (g_qis_cloud_thread_running != CISESS_APDISCON && retransmission_count < MAX_COMM_ERROR_RETRANSMISSION) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Re-transmission try.");
+                       retransmission_count++;
+                       ret = true;
+               } else {
+                       retransmission_count = 0;
+               }
+       } else {
+               retransmission_count = 0;
+       }
+
+       return ret;
+#undef MAX_COMM_ERROR_RETRANSMISSION
+}
+
+OCStackApplicationResult handle_refresh_token_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Refresh Token callback received");
+
+       OCStackApplicationResult res = OC_STACK_DELETE_TRANSACTION;
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Login/out callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Refresh Token response received code: %s(%d)", get_result(client_response->result), client_response->result);
+
+       if (check_comm_error_retrans(client_response->result) == true) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Re-Start Refresh-Token Process.");
+               refresh_token_into_cloud();
+       }
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "PAYLOAD_TYPE_REPRESENTATION received");
+
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val != NULL) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+                       // Method don't care because issue is not occurred by it.
+                       if (get_cloud_code(client_response, OC_REST_POST, &ci_err) == 0) {
+                               ci_err = ERRCI_UNKNOWN;
+                       }
+
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Cloud ErrCode = %d", ci_err);
+//            es_set_cloud_error_code(ci_err);
+
+                       switch (ci_err) {
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_VALIDATION_FAILED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> RefreshToken is invalid, fix RefreshToken and try again.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_SAMSUNG_ACCOUNT_UNAUTHORIZED_TOKEN:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> RefreshToken is mismatched with client ID, fix RefreshToken or Client ID.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_EXPIRED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> RefreshToken is expired, refresh RefreshToken and try again.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_FORBIDDEN:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> URI is invalid, fix the URI and try again.");
+                               esm_get_network_status();       // State return
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               esm_get_network_status();       // State return
+                               break;
+                       }
+
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+
+               OICFree(signed_up_data->access_token);
+               OICFree(signed_up_data->refresh_token);
+               OICFree(signed_up_data->token_type);
+               signed_up_data->expire_time = 0;
+
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_TOKEN_ACCESS, &signed_up_data->access_token);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_TOKEN_ACCESS_REFRESH, &signed_up_data->refresh_token);
+               OCRepPayloadGetPropString(((OCRepPayload *) client_response->payload), KEY_TOKEN_TYPE, &signed_up_data->token_type);
+               OCRepPayloadGetPropInt(((OCRepPayload *) client_response->payload), KEY_EXPIRE_TIME, &signed_up_data->expire_time);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "expiresin : %lld", signed_up_data->expire_time);
+
+               if (signed_up_data->access_token == NULL || strlen(signed_up_data->access_token) < 1) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Session Key is NULL. Refresh Token Failed.");
+               } else {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Write Sign-Up data to file.");
+                       if (dm_update_things_cloud(signed_up_data) == 1) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Re-Try Sign-IN step.");
+                               force_session_stop(CISESS_SIGNOUT);
+                               log_in_out_to_cloud(true, NULL);
+                       } else {
+                               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Refreshed Sign-UP data can not write to info file.");
+                       }
+               }
+
+               res = OC_STACK_DELETE_TRANSACTION;
+       }
+
+       return res;
+}
+
+OCStackApplicationResult handle_main_dev_publish_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Publish callback received");
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Publish callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Publish resource response received, code: %s(%d)", get_result(client_response->result), client_response->result);
+       if (cas_request_handle(handle, NULL) == 1) {
+               del_all_request_handle();
+
+               if (check_comm_error_retrans(client_response->result) == true) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Re-Start publish_resource_into_cloud");
+                       publish_resource_into_cloud(RSC_PUB_MAIN_ONLY, NULL);
+               }
+
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Response Handle(0x%X) is not exist in the Request Handle list.", handle);
+               return OC_STACK_DELETE_TRANSACTION;
+       }
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val != NULL) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+
+                       if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD, (ci_error_code_e) NULL, client_response, &ci_err) != 0) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                               PROFILING_TIME("Cloud Provisioning End.");
+                               return OC_STACK_DELETE_TRANSACTION;
+                       }
+
+                       switch (ci_err) {
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_VALIDATION_FAILED:
+                       case ERRCI_TOKEN_EXPIRED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> AccessToken \"%d\", refresh AccessToken and try again.", ci_err);
+                               refresh_token_into_cloud();     // refresh accesstoken.
+                               break;
+                       case ERRCI_FORBIDDEN:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> URI is invalid, fix the URI and try again.");
+                               break;
+                       case ERRCI_RDLINK_INVALID_PARAM:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> Resource List Cbor syntax is invalid. Re-Translation.");
+                               if (retranslate_rsc_publish_cnt < MAX_RETRY_RSCPUBLISH) {
+                                       publish_resource_into_cloud(RSC_PUB_MAIN_ONLY, NULL);
+                                       retranslate_rsc_publish_cnt++;
+                               } else {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[INFO] Resource Publish is Re-translated about %d\n Please check Network Line.", retranslate_rsc_publish_cnt);
+                                       retranslate_rsc_publish_cnt = 0;
+                                       esm_get_network_status();       // State return
+                               }
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               break;
+                       }
+               }
+
+       } else if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Received Failed-Response of Resource-Publish without payload from Cloud Server.");
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD, ES_ERRCODE_UNKNOWN, NULL, NULL) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+                       PROFILING_TIME("Cloud Provisioning End.");
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+       }
+
+       if (client_response->result == OC_STACK_RESOURCE_CHANGED) {
+               if (es_cloud_state_set_and_notify(ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                       PROFILING_TIME("Cloud Provisioning End.");
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+
+               publish_resource_into_cloud(RSC_PUB_SUB_ALL, NULL);
+               publish_dev_profile_into_cloud(NULL);
+       }
+
+       PROFILING_TIME("Cloud Provisioning End.");
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult handle_sub_dev_publish_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Sub-Device resource Publish callback received");
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Publish callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Publish resource response received, code: %s(%d)", get_result(client_response->result), client_response->result);
+       if (check_comm_error_retrans(client_response->result) == true) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Resource Publish Request-Send is Failed.");
+               publish_resource_into_cloud(RSC_PUB_SUB_ALL, NULL);
+       }
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val != NULL) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+
+                       if (get_cloud_code(client_response, OC_REST_POST, &ci_err) == 0) {
+                               ci_err = ERRCI_UNKNOWN;
+                       }
+//            es_set_cloud_error_code(ci_err);
+
+                       switch (ci_err) {
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_VALIDATION_FAILED:
+                       case ERRCI_TOKEN_EXPIRED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> AccessToken \"%d\", refresh AccessToken and try again.", ci_err);
+                               refresh_token_into_cloud();     // refresh accesstoken.
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               break;
+                       }
+               }
+
+       }
+
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult handle_dev_profile_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Device Profile Publish callback received");
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Publish callback received");
+       }
+
+       del_all_request_handle();
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Device Profile Publish response received, code: %s(%d)", get_result(client_response->result), client_response->result);
+       if (check_comm_error_retrans(client_response->result) == true) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Device Profile Publish Request-Send is Failed.");
+               publish_dev_profile_into_cloud(NULL);
+       }
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val != NULL) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+
+                       if (get_cloud_code(client_response, OC_REST_POST, &ci_err) == 0) {
+                               ci_err = ERRCI_UNKNOWN;
+                       }
+//            es_set_cloud_error_code(ci_err);
+
+                       switch (ci_err) {
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_VALIDATION_FAILED:
+                       case ERRCI_TOKEN_EXPIRED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]-> AccessToken \"%d\", refresh AccessToken and try again.", ci_err);
+                               refresh_token_into_cloud();     // refresh accesstoken.
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               break;
+                       }
+               }
+
+       }
+
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult handle_find_resource_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       if (ctx == (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Callback Context for DISCOVER query recvd successfully");
+       }
+
+       if (client_response) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+
+               //char* connectionType = getConnectivityType (client_response->connType);
+               //THINGS_LOG_D(THINGS_DEBUG, TAG, "Discovered on %s", connectionType.c_str());
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Device =============> Discovered @ %s:%d", client_response->devAddr.addr, client_response->devAddr.port);
+
+               if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+                       OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+                       while (val != NULL) {
+                               if (val->type == OCREP_PROP_INT) {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                               } else if (val->type == OCREP_PROP_STRING) {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                               } else {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                               }
+
+                               val = val->next;
+                       }
+               }
+
+               if (client_response->result != OC_STACK_OK) {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Refresh Token process Start.");
+                       refresh_token_into_cloud();
+               }
+
+       } else {
+               THINGS_LOG_D(THINGS_INFO, TAG, "handle_find_resource_cb received Null client_response");
+       }
+
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult handle_publish_topic_cb(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Publish Topic callback received");
+
+       OCStackApplicationResult res = OC_STACK_DELETE_TRANSACTION;
+
+       if (ctx != (void *)DEFAULT_CONTEXT_VALUE) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid Publish Topic callback received");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Publish Topic response received code: %s(%d)", get_result(client_response->result), client_response->result);
+
+       if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "PAYLOAD_TYPE_REPRESENTATION received");
+
+               OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+               while (val) {
+                       if (val->type == OCREP_PROP_INT) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", val->name, val->i);
+                       } else if (val->type == OCREP_PROP_STRING) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", val->name, val->str);
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", val->type);
+                       }
+
+                       val = val->next;
+               }
+
+               if (client_response->result != OC_STACK_RESOURCE_CHANGED) {
+                       ci_error_code_e ci_err = ERRCI_NO_ERROR;
+
+                       if (0 == get_cloud_code(client_response, OC_REST_POST, &ci_err)) {
+                               ci_err = ERRCI_UNKNOWN;
+                       }
+
+                       switch (ci_err) {
+                       case ERRCI_INTERNAL_SERVER_ERROR:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE]Cloud Server has a issue, Check your Cloud Server.");
+                               esm_get_network_status();       // State return
+                               break;
+                       case ERRCI_TOKEN_VALIDATION_FAILED:
+                       case ERRCI_TOKEN_EXPIRED:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ERRCODE] AccessToken \"%d\", refresh AccessToken and try again.", ci_err);
+                               refresh_token_into_cloud();     // refresh accesstoken.
+                               break;
+                       default:
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support This Cloud-Error-Code(%d) Exception", ci_err);
+                               //esm_get_network_status();  // Don't need to sign out on this session
+                               break;
+                       }
+               }
+
+               res = OC_STACK_DELETE_TRANSACTION;
+       }
+
+       return res;
+}
+
+static OCStackResult publish_resource_main_dev_into_cloud(things_resource_s **list, int length, timeout_s *timeout)
+{
+       es_error_code_e es_err = ES_ERRCODE_UNKNOWN;
+       OCStackResult res = OC_STACK_ERROR;
+
+       if (list == NULL || length < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Parameter Inserted");
+               es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+               return res;
+       } else {
+               if (es_cloud_state_set_and_notify(ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                       return res;
+               }
+
+               if (ci_connection_pre_check(NULL, NULL) == 0) {
+                       res = things_cloud_rsc_publish(g_cloud_address, list, length, handle_main_dev_publish_cb, handle_publish_timeout, timeout);
+               } else {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "AP is not connected to internet.");
+                       es_err = ES_ERRCODE_NO_INTERNETCONNECTION;
+               }
+
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Unable to publish user resources to cloud : %d", res);
+
+                       if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD, es_err, NULL, NULL) != 0) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                               return res;
+                       }
+
+                       return res;
+               }
+       }
+
+       return res;
+}
+
+OCStackResult publish_resource_into_cloud(rp_target_e target, timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       int sub_dev_pub_fail = -1;
+       OCStackResult res = OC_STACK_OK;
+
+       if (target == RSC_PUB_ALL || target == RSC_PUB_MAIN_ONLY) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Main-Device Resource Publish Start.");
+               res = publish_resource_main_dev_into_cloud(g_resource_lists, g_len, timeout);
+               usleep(10000);                  // 1 device resource-publish per 10 msec.
+       }
+
+       if (res == OC_STACK_OK && target != RSC_PUB_MAIN_ONLY) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Sub-Devices Resource Publish Start.");
+               int device_cnt = 0;
+               char *device_id = NULL;
+               st_device_s **dList = NULL;
+
+               if (1 == dm_get_device_information(&device_cnt, &dList) && device_cnt > 1) {
+                       for (int index = 1; index < device_cnt; index++) {
+                               // Get device id of hosted ones..
+                               if (dList[index]->is_physical == 1) {
+                                       if (sub_dev_pub_fail == -1) {
+                                               sub_dev_pub_fail = 0;
+                                       }
+
+                                       device_id = dList[index]->device_id;
+
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Sub-device ID=%s", device_id);
+                                       if (device_id == NULL || device_id[0] == 0) {
+                                               THINGS_LOG_D(THINGS_DEBUG, TAG, "not exist device ID. So, skip publish resource.");
+                                               sub_dev_pub_fail = 1;
+                                               continue;
+                                       }
+
+                                       OCStackResult result = things_cloud_rsc_publish_with_device_id(g_cloud_address,
+                                                                                  device_id,
+                                                                                  dList[index]->pchild_resources,
+                                                                                  dList[index]->capa_cnt,
+                                                                                  handle_sub_dev_publish_cb,
+                                                                                  handle_publish_timeout,
+                                                                                  timeout);
+                                       if (result != OC_STACK_OK) {
+                                               sub_dev_pub_fail = 1;
+                                       }
+
+                                       device_id = NULL;
+                                       usleep(10000);  // 1 device resource-publish per 10 msec.
+                               }
+                       }
+               }
+
+               if (dList) {
+                       things_free(dList);
+                       dList = NULL;
+               }
+
+               if (target == RSC_PUB_SUB_ALL || target == RSC_PUB_NEED_SUB_ONLY) {
+                       switch (sub_dev_pub_fail) {
+                       case 1:                 // occurred error
+                               THINGS_LOG_D(THINGS_INFO, TAG, "Sending-request is failed for Sub-device publish.");
+                               res = OC_STACK_ERROR;
+                               break;
+                       case -1:                        // not exist sub-dev
+                               THINGS_LOG_D(THINGS_INFO, TAG, "Not exist sub-device publish.");
+                               res = OC_STACK_ERROR;
+                               break;
+                       case 0:
+                               THINGS_LOG_D(THINGS_INFO, TAG, "Sending-request is Success for Sub-device publish.");
+                               res = OC_STACK_OK;
+                               break;
+                       }
+               }
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return res;
+}
+
+OCStackResult log_in_out_to_cloud(bool value, timeout_s *timeout)
+{
+       int port = 0;
+       char *ci_ip = NULL;
+       char *ci_domian = NULL;
+       es_error_code_e es_err = ES_ERRCODE_UNKNOWN;
+       OCStackResult res = OC_STACK_ERROR;
+       OCClientResponseHandler callback = NULL;
+       check_time_out_call_func calltimeout = NULL;
+
+       if (signed_up_data == NULL || signed_up_data->access_token == NULL || strlen(signed_up_data->access_token) < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "No Session Key Retrived from the Cloud ");
+               return res;
+       }
+
+       if (signed_up_data->domain != NULL && (signed_up_data->port == NULL || signed_up_data->port[0] == 0)) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "domain=%s but, not exist port number.(%s)", signed_up_data->domain, signed_up_data->port);
+               return res;
+       }
+
+       if (value == true) {
+               callback = handle_login_cb;
+               calltimeout = handle_signin_timeout;
+               if (es_cloud_state_set_and_notify(ES_STATE_REGISTERING_TO_CLOUD, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                       return res;
+               }
+
+               if (signed_up_data->domain != NULL) {
+                       ci_domian = strdup(signed_up_data->domain);
+               }
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "*********** Start Sign-IN ********** ci_domian : %s", ci_domian);
+       } else {
+               callback = handle_logout_cb;
+               calltimeout = NULL;
+               g_qis_cloud_thread_running = CISESS_SIGNOUT;
+               if (es_cloud_state_set_and_notify(ES_STATE_LOGOUT_FROM_CLOUD, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                       return res;
+               }
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "*********** Start Sign-OUT **********");
+       }
+
+       if (ci_connection_pre_check(ci_domian, &ci_ip) == 0) {
+               if (ci_ip != NULL) {
+                       if (make_cloud_address(ci_ip, signed_up_data->port, NULL) == NULL) {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Making CloudAddress is failed.");
+                               goto GOTO_OUT;
+                       }
+                       things_strncpy(g_cloud_ip, ci_ip, IP_PORT);
+                       things_strncpy(g_cloud_port, signed_up_data->port, IP_PORT);
+
+                       port = atoi(g_cloud_port);
+                       if (g_cloud_ip[0] == NULL || g_cloud_port[0] == NULL || 0 >= port || port > 65535) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Cloud info is invalid.(g_cloud_ip=%s, g_cloud_port=%s, port=%d)", g_cloud_ip, g_cloud_port, port);
+                               goto GOTO_OUT;
+                       }
+               }
+
+               if (g_cloud_address[0] == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "g_cloud_address is invalid.(0x%X)", g_cloud_address);
+                       goto GOTO_OUT;
+               }
+
+               THINGS_LOG_D(THINGS_INFO, TAG, "Cloud Addr : %s", g_cloud_address);
+               THINGS_LOG_D(THINGS_INFO, TAG, "device ID : %s", OCGetServerInstanceIDString());
+               THINGS_LOG_D(THINGS_INFO, TAG, "access_token : %s", signed_up_data->access_token);
+               THINGS_LOG_D(THINGS_INFO, TAG, "refresh token : %s", signed_up_data->refresh_token);
+               THINGS_LOG_D(THINGS_INFO, TAG, "user ID : %s", signed_up_data->uid);
+               THINGS_LOG_D(THINGS_INFO, TAG, "toke type : %s", signed_up_data->token_type);
+               THINGS_LOG_D(THINGS_INFO, TAG, "expire Time : %lld", signed_up_data->expire_time);
+               THINGS_LOG_D(THINGS_INFO, TAG, "certificate : %s", signed_up_data->certificate);
+               THINGS_LOG_D(THINGS_INFO, TAG, "redirect URI : %s", signed_up_data->redirect_uri);
+               THINGS_LOG_D(THINGS_INFO, TAG, "sid : %s", signed_up_data->sid);
+
+               if (value == true) {
+                       oic_ping_set_mask(g_cloud_ip, port, PING_ST_ISCLOUD);
+               } else {
+                       oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD | PING_ST_SIGNIN | PING_ST_TCPCONNECT);
+               }
+
+               res = things_cloud_session(g_cloud_address, signed_up_data->uid, OCGetServerInstanceIDString(), signed_up_data->access_token, value, callback, calltimeout, timeout);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OCCloudLogInOut return : %d", res);
+       } else {
+               THINGS_LOG_V(THINGS_INFO, TAG, "AP is not connected to internet.");
+               es_err = ES_ERRCODE_NO_INTERNETCONNECTION;
+       }
+
+GOTO_OUT:
+       if (ci_ip != NULL) {
+               things_free(ci_ip);
+               ci_ip = NULL;
+       }
+
+       if (ci_domian != NULL) {
+               things_free(ci_domian);
+               ci_domian = NULL;
+       }
+
+       if (res != OC_STACK_OK) {
+               if (value == true) {
+                       oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD);
+
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Cloud Server LogIn Failed : %d", res);
+                       if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, es_err, NULL, NULL) != 0) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                               return res;
+                       }
+               } else {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Cloud Server LogOut Failed : %d", res);
+                       esm_get_network_status();
+                       return res;
+               }
+       }
+
+       return res;
+}
+
+/**
+ * @brief                 Call function to send request for Finding myself-resource to Cloud.
+ * @return                Success return OC_STACK_OK (0) \n
+ *                        Failed  return other OCStackResult value (-)
+ */
+OCStackResult find_cloud_resource(void)
+{
+       OCStackResult ret = OC_STACK_ERROR;
+
+       char *sz_query_uri = NULL;
+       int length = MAX_CI_ADDRESS;
+       int length_query = 0;
+
+       length += strlen(RESOURCE_DISCOVERY_QUERY_DI);
+       length += strlen(OCGetServerInstanceIDString());
+       length_query = sizeof(char) * (length + 2);
+
+       if ((sz_query_uri = (char *)things_malloc(length_query)) == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "sz_query_uri memory allocation is failed.");
+               return OC_STACK_ERROR;
+       }
+
+       memset(sz_query_uri, 0, length_query);
+       if (things_strcat(sz_query_uri, length_query, g_cloud_address) == NULL) {
+               ret = OC_STACK_NO_MEMORY;
+       }
+       if (things_strcat(sz_query_uri, length_query, RESOURCE_DISCOVERY_QUERY_DI) == NULL) {
+               ret = OC_STACK_NO_MEMORY;
+       }
+       if (things_strcat(sz_query_uri, length_query, OCGetServerInstanceIDString()) == NULL) {
+               ret = OC_STACK_NO_MEMORY;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Find Resource to Cloud URI : %s", sz_query_uri);
+
+       OCCallbackData cb_data;
+       cb_data.cb = handle_find_resource_cb;
+       cb_data.context = (void *)DEFAULT_CONTEXT_VALUE;
+       cb_data.cd = NULL;
+
+       if (ret != OC_STACK_NO_MEMORY) {
+               ret = OCDoResource(NULL, OC_REST_DISCOVER, sz_query_uri, NULL, 0, CT_DEFAULT, OC_MEDIUM_QOS, &cb_data, NULL, 0);
+       }
+
+       if (ret != OC_STACK_OK) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Find Resource in Cloud is failed.");
+       }
+
+       things_free(sz_query_uri);
+
+       return ret;
+}
+
+static OCStackResult register_server_into_cloud(es_cloud_prov_data_s *event_data, timeout_s *timeout)
+{
+       OCStackResult res = OC_STACK_ERROR;
+
+       if (event_data == NULL || (event_data->auth_code[0] == 0 && event_data->accesstoken[0] == 0)) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid event_data.");
+               return res;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "AuthCode     : %s", event_data->auth_code);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Access Token : %s", event_data->accesstoken);
+
+       if (signed_up_data != NULL) {
+               es_cloud_signup_clear(signed_up_data);
+               signed_up_data = NULL;
+       }
+
+       int port = atoi(g_cloud_port);
+       if (g_cloud_ip[0] == NULL || g_cloud_port[0] == NULL || 0 >= port || port > 65535) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Cloud info is invalid.(g_cloud_ip=%s, g_cloud_port=%s, port=%d)", g_cloud_ip, g_cloud_port, port);
+               return res;
+       }
+
+       if (es_cloud_state_set_and_notify(ES_STATE_REGISTERING_TO_CLOUD, ES_ERRCODE_NO_ERROR, NULL, NULL) != 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+               return res;
+       }
+
+       oic_ping_set_mask(g_cloud_ip, (uint16_t) port, PING_ST_ISCLOUD);
+
+       // Get Session Key
+       res = things_cloud_signup(g_cloud_address, OCGetServerInstanceIDString(), event_data, handle_register_cb, handle_signup_timeout, timeout);
+
+       if (res != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Cloud Server Registration Failed : %d", res);
+               oic_ping_unset_mask(g_cloud_ip, PING_ST_ISCLOUD);
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ES_ERRCODE_UNKNOWN, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+                       return res;
+               }
+       }
+
+       return res;
+}
+
+OCStackResult refresh_token_into_cloud(void)
+{
+       OCStackResult res = OC_STACK_ERROR;
+       if (signed_up_data == NULL || signed_up_data->access_token == NULL || strlen(signed_up_data->access_token) < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "No Session Key Retrived from the Cloud ");
+       } else {
+               res = things_cloud_refresh(g_cloud_address, signed_up_data->uid, OCGetServerInstanceIDString(), signed_up_data->refresh_token, handle_refresh_token_cb);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OCCloud Refresh Token return : %d", res);
+       }
+
+       if (res != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Cloud access_token refresh Failed : %d", res);
+       }
+
+       return res;
+}
+
+int push_notification_to_cloud(const char *uri, OCRepPayload *payload)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ret = 0;
+
+       if (things_get_reset_mask(RST_NOTI_MODULE_DISABLE) == true) {
+               THINGS_LOG(THINGS_INFO, TAG, "Notification Module Disable.");
+               ret = 0;
+       } else if (NULL != payload) {
+               if (OC_STACK_OK == things_cloud_topic_publish_topic(g_cloud_address, uri, payload, handle_publish_topic_cb)) {
+                       ret = 1;
+               }
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return ret;
+}
+
+static char *make_cloud_address(char *ip, char *port, const char *ci_addr)
+{
+       char *delmem = NULL;
+       char *ipport = (char *)ci_addr;
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "ip=%s, port=%s, ci_addr=%s", ip, port, ci_addr);
+
+       if (ci_addr != NULL && strlen(ci_addr) > 0) {   // ci address.
+               char *point = strstr(ci_addr, DEFAULT_COAP_TCP_HOST);
+               if (point) {
+                       ipport = point + strlen(DEFAULT_COAP_TCP_HOST);
+               }
+       } else if ((ipport = make_ip_port(ip, port)) != NULL) { // ip , port coupling.
+               delmem = ipport;
+       } else {                                        // ext case.
+               ipport = DEFAULT_CI_HOST;
+       }
+
+       // Update Cloud Address.
+       memset(g_cloud_address, 0, MAX_CI_ADDRESS);
+       if (things_strcat(g_cloud_address, MAX_CI_ADDRESS, DEFAULT_COAP_TCP_HOST) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "things_strcat() is failed.");
+               if (delmem) {
+                       things_free(delmem);
+               }
+               return NULL;
+       }
+
+       if (things_strcat(g_cloud_address, MAX_CI_ADDRESS, ipport) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "things_strcat() is failed.");
+               if (delmem) {
+                       things_free(delmem);
+               }
+               return NULL;
+       }
+
+       if (delmem) {
+               things_free(delmem);
+       }
+
+       return g_cloud_address;
+}
+
+static int start_ci_connection(const char *cloud_adress, es_cloud_prov_data_s *event_data, things_resource_s **list, int length, timeout_s *timeout)
+{
+       int ret = 0;
+       OCStackResult result = OC_STACK_ERROR;
+
+       g_resource_lists = list;
+       g_len = length;
+
+       if (make_cloud_address(NULL, NULL, cloud_adress) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Making Cloud Address is failed.");
+               result = OC_STACK_NO_MEMORY;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr Addr         : %s", g_cloud_address);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr AuthCode     : %s", event_data->auth_code);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr Accesstoken  : %s", event_data->accesstoken);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr Uid          : %s", event_data->uid);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr AuthProvider : %s", event_data->auth_provider);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr client_id     : %s", event_data->client_id);
+
+       if (timeout != NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr timeout_cnt     : %d", timeout->cur_counter);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr timeout_cur_num : %d", timeout->cur_num);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CI Svr timeout_ori_num : %d", timeout->ori_num);
+       }
+
+       if (result != OC_STACK_NO_MEMORY) {
+               if (event_data != NULL && (event_data->auth_code[0] != 0 || event_data->accesstoken[0] != 0)) {
+                       result = register_server_into_cloud(event_data, timeout);
+               } else {
+                       if (es_cloud_signup_init(&signed_up_data) == true && (ret = dm_load_legacy_cloud_data(&signed_up_data)) == 1) {
+                               result = log_in_out_to_cloud(true, timeout);
+                       } else {
+                               THINGS_LOG_D(THINGS_INFO, TAG, "Sign-UP data load failed.");
+                       }
+               }
+       }
+
+       if (OC_STACK_OK != result) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "start_ci_connection() is failed.");
+       } else {
+               ret = 1;                                // Success.
+       }
+
+       return ret;
+}
+
+static void *ci_connection_init_loop(es_cloud_event_timeout_s *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int res = 0;
+       char *ci_ip = NULL;
+       char *ci_ip_port = NULL;
+       char *ci_host = NULL;
+       es_error_code_e es_err = ES_ERRCODE_UNKNOWN;
+
+       ci_cp_del_is_there_cp();
+
+       if (param == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] parameter is NULL.");
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "StateAndNotify is failed.");
+               }
+
+               force_session_stop(CISESS_NULL);
+               return NULL;
+       }
+
+       es_cloud_prov_data_s *event_data = &param->event;
+
+       if (event_data->host_name[0] != 0) {
+               ci_host = &(event_data->host_name[0]);
+       } else if (event_data->ip[0] != 0) {
+               ci_host = &(event_data->ip[0]);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "* param add= 0x%X *", param);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "* ci_host   = %s *", ci_host);
+
+       // Cross check if a network is available
+       if (esm_get_network_status()) {
+               if (g_server_builder != NULL) {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "##########################");
+                       THINGS_LOG_V(THINGS_INFO, TAG, "  Start Cloud Connection ");
+                       THINGS_LOG_V(THINGS_INFO, TAG, "##########################");
+
+                       if (ci_connection_pre_check(ci_host, &ci_ip) == 0) {
+                               ci_ip_port = make_ip_port(ci_ip, event_data->port);
+                               things_strncpy(g_cloud_ip, ci_ip, IP_PORT);
+                               things_strncpy(g_cloud_port, event_data->port, IP_PORT);
+
+                               pthread_mutex_lock(&g_es_mutex);
+                               res = start_ci_connection(dm_get_things_cloud_address(ci_ip_port), event_data, g_server_builder->gres_arr, g_server_builder->res_num, &param->timeOut);
+                               switch (res) {
+                               case 1:         // Success
+                                       usleep(500000); // 0.5 sec wait (need for Cloud CI Server cooling.)
+                                       break;
+                               case 0:         // Fail start_ci_connection.
+                                       es_err = ES_ERRCODE_UNKNOWN;
+                                       break;
+                               case -1:                // Json Parsing error. or Memory Alloc error. or Invalid argument error.
+                                       es_err = ER_ERRCODE_SYSTEM_ERROR;
+                                       break;
+                               case -2:                // Invalid Contents of Json file.
+                                       es_err = ER_ERRCODE_INVALID_SAVED_CLOUD_DATA;
+                                       break;
+                               }
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "res = %d, es_err = %d", res, es_err);
+                               pthread_mutex_unlock(&g_es_mutex);
+
+                               if (ci_ip_port) {
+                                       things_free(ci_ip_port);
+                                       ci_ip_port = NULL;
+                               }
+                               if (ci_ip) {
+                                       things_free(ci_ip);
+                                       ci_ip = NULL;
+                               }
+                       } else {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "AP is Not Connected to Internet.");
+                               es_err = ES_ERRCODE_NO_INTERNETCONNECTION;
+                       }
+               } else {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ServerBuilder is NULL.");
+                       es_err = ER_ERRCODE_SYSTEM_ERROR;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Device is not connected to AP.");
+               es_err = ES_ERRCODE_UNKNOWN;
+       }
+
+       if (res != 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "###################################");
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "  Exiting without Cloud Connection ");
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "###################################");
+
+               if (es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, es_err, NULL, NULL) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "StateAndNotify is failed.");
+               }
+
+               force_session_stop(CISESS_NULL);
+       }
+
+       things_free(param);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return NULL;
+}
+
+static void *ci_connection_waiting_loop(es_cloud_event_timeout_s *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Sleep before cloud_retry_sign_up");
+       sleep(1);
+       if (param == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] parameter is NULL.");
+               ci_cp_del_is_there_cp();
+               ci_cp_del_pended_data();
+               es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+               esm_get_network_status();       // State return
+               return NULL;
+       }
+
+       while (g_qis_cloud_thread_running != CISESS_STOP) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Waiting ...");
+               usleep(100000);
+       }
+
+       ci_cp_pend_event_data(&(param->event));
+       g_qis_cloud_thread_running = CISESS_BUSY;
+       THINGS_LOG(THINGS_DEBUG, TAG, "Create CloudInit thread");
+
+       ci_connection_init_loop(param);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return NULL;
+}
+
+void *cloud_data_cb_esm(es_cloud_prov_data_s *event_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "g_qis_cloud_thread_running = %d", g_qis_cloud_thread_running);
+
+       pthread_t cthread_handler;
+       es_cloud_event_timeout_s *cloned_data = NULL;
+#if 0                                                  // pkcloud
+       if (ci_cp_cas_is_there_cp_if_false() == true) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Already exist data of Cloud Provisioning.");
+               return NULL;
+       }
+#endif
+       switch (g_qis_cloud_thread_running) {
+       case CISESS_APDISCON:
+               // Backup loose try..
+               ci_cp_pend_event_data(event_data);
+               return NULL;
+       case CISESS_BUSY:                       // Occupied
+       case CISESS_STOP_TRIGGER:       // Re-Start triggered.
+       case CISESS_SIGNOUT:            // doing Auto Log-Out
+               break;
+       case CISESS_STOP:                       // can start.
+               del_all_request_handle();
+               send_cnt_sign_up = 0;
+               ci_cp_pend_event_data(event_data);
+               g_qis_cloud_thread_running = CISESS_BUSY;
+
+               if ((cloned_data = clone_data_add_timeout(event_data, NULL)) != NULL) {
+#ifdef __ST_THINGS_RTOS__
+                       int retp = pthread_create_rtos(&cthread_handler, NULL, (pthread_func_type) ci_connection_init_loop, (void *)cloned_data, THINGS_STACK_CICONNETION_INIT_THREAD);
+#else
+
+                       int retp = things_thread_create(&cthread_handler, NULL, (pthread_func_type) ci_connection_init_loop, (void *)cloned_data) != 0)
+#endif
+                       if (retp != 0) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Create thread is failed.");
+                               things_free(cloned_data);
+                               cloned_data = NULL;
+                               g_qis_cloud_thread_running = CISESS_STOP;
+                               es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+                       }
+               } else {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "clone_data_add_timeout is failed.");
+               }
+               return NULL;
+       default:
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not Surpport value(%d) of g_qis_cloud_thread_running.", g_qis_cloud_thread_running);
+               return NULL;
+       }
+
+       del_all_request_handle();
+       send_cnt_sign_up = 0;
+
+       if (cloud_retry_sign_up(event_data, NULL) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud_retry_sign_up is failed.");
+               ci_cp_del_pended_data();
+               ci_cp_del_is_there_cp();
+               es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+               esm_get_network_status();       // State return
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return NULL;
+}
+
+int cloud_retry_sign_in(timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       pthread_t cthread_handler;
+       es_cloud_prov_data_s dummy_data;
+       es_cloud_event_timeout_s *cloned_data = NULL;
+
+       if (ci_cp_get_is_there_cp() == true) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "There is a CloudProvisioning data. Cloud-retry is skiped.");
+               return 1;
+       }
+
+       force_session_stop(CISESS_NULL);
+
+       // Need to check the running state of the thread...
+       if (g_qis_cloud_thread_running == CISESS_STOP) {
+               g_qis_cloud_thread_running = CISESS_BUSY;
+               THINGS_LOG(THINGS_DEBUG, TAG, "Create CloudInit thread");
+
+               // cloud_data setting.
+               init_es_cloud_prov_data(&dummy_data);
+
+               if ((cloned_data = clone_data_add_timeout(&dummy_data, timeout)) == NULL ||
+#ifdef __ST_THINGS_RTOS__
+                       pthread_create_rtos(&cthread_handler, NULL, (pthread_func_type) ci_connection_init_loop, (void *)cloned_data, THINGS_STACK_CICONNETION_INIT_THREAD) != 0)
+#else
+                       things_thread_create(&cthread_handler, NULL, (pthread_func_type) ci_connection_init_loop, (void *)cloned_data) != 0)
+#endif
+               {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Create thread is failed.");
+                       things_free(cloned_data);
+                       cloned_data = NULL;
+                       g_qis_cloud_thread_running = CISESS_STOP;
+                       es_cloud_state_set_and_notify(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD, ER_ERRCODE_SYSTEM_ERROR, NULL, NULL);
+               }
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return 0;
+}
+
+static int cloud_retry_sign_up(es_cloud_prov_data_s *event_data, timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       pthread_t cthread_handler;
+       es_cloud_event_timeout_s *cloned_data = NULL;
+
+       if (event_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "event_data is NULL.");
+               return 0;
+       }
+
+       g_qis_cloud_thread_running = CISESS_STOP_TRIGGER;
+       esm_get_network_status();       // State return
+
+       if ((cloned_data = clone_data_add_timeout(event_data, timeout)) == NULL ||
+#ifdef __ST_THINGS_RTOS__
+               pthread_create_rtos(&cthread_handler, NULL, (pthread_func_type) ci_connection_waiting_loop, (void *)cloned_data, THINGS_STACK_CICONNETION_INIT_THREAD) != 0)
+#else
+               things_thread_create(&cthread_handler, NULL, (pthread_func_type) ci_connection_waiting_loop, (void *)cloned_data) != 0)
+#endif
+       {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Create thread is failed.");
+               things_free(cloned_data);
+               cloned_data = NULL;
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return 1;
+}
+
+static void cloud_request_retry_trigger(timeout_s *timeout)
+{
+       // Stored Backup data is base on time-out.
+       es_cloud_prov_data_s *pendedEvent = NULL;
+       if ((pendedEvent = ci_cp_get_pended_data()) != NULL) {
+               ci_cp_del_is_there_cp();
+               cloud_data_cb_esm(pendedEvent); // 1. Last Cloud Provisioning-ed data. or Last Send Failed data.(Sign-UP)
+       } else {
+               cloud_retry_sign_in(timeout);   // default. Cloud retry. (Sign-IN / Resource Publish failed data)
+       }
+}
+
+static es_cloud_prov_data_s *if_failed_then_retry(OCDoHandle handle, OCStackResult result, int *n_err)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "latestRequest 0x%X, RespCB:0x%X]", get_request_handle(), handle);
+
+       es_cloud_prov_data_s *pended_data = NULL;
+       es_cloud_prov_data_s *clone_data = NULL;
+       *n_err = 0;
+
+       ci_cp_enter_pend_data_block();
+       if (cas_request_handle(handle, NULL) == 1) {
+               if (result == OC_STACK_COMM_ERROR) {    // Don't Send Request Message.
+                       if (g_qis_cloud_thread_running != CISESS_APDISCON) {
+                               cloud_request_retry_trigger(NULL);
+                       }
+                       *n_err = 1;                     // communication error.
+               } else {
+                       del_all_request_handle();
+
+                       if ((pended_data = ci_cp_get_pended_data()) == NULL) {
+                               THINGS_LOG_V(THINGS_INFO, TAG, "Not exist Pended Event Data.");
+                               *n_err = 2;             // not exist pended_data.
+                               goto GOTO_OUT;
+                       }
+
+                       if ((clone_data = things_malloc(sizeof(es_cloud_prov_data_s))) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "memory allocation is failed for clone_data.");
+                               *n_err = 3;             // mem allocation error.
+                               goto GOTO_OUT;
+                       }
+
+                       clone_es_cloud_prov_data(clone_data, pended_data);
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Response Handle(0x%X) is not exist in the Request Handle list.", handle);
+               *n_err = 4;
+       }
+
+GOTO_OUT:
+       ci_cp_release_penddata_block();
+
+       if (*n_err != 1 && *n_err != 4) {
+               ci_cp_del_pended_data();
+       }
+
+       return clone_data;
+}
+
+void ci_stop_cloud_connection(void *CBfunc)
+{
+       force_session_stop(CISESS_NULL);
+       esm_get_network_status();       // State return
+       sleep(1);
+
+       things_res_cb_function = NULL;
+       if (CBfunc) {
+               things_res_cb_function = (things_cloud_con_result_func_type *) CBfunc;
+       }
+}
+static void force_session_stop(ci_session_level_e state)
+{
+       del_all_request_handle();
+       if (state == CISESS_SIGNOUT) {
+               g_qis_cloud_thread_running = CISESS_SIGNOUT;
+       } else {
+               g_qis_cloud_thread_running = CISESS_STOP_TRIGGER;
+       }
+       esm_get_network_status();       // State return
+}
+
+int ci_retry_stop_by_wifi_cb(bool is_retry)
+{
+       if (is_retry == true) {         // Last Failed Cloud Connection Retry. (Permanent setting)
+               del_all_request_handle();
+               g_qis_cloud_thread_running = CISESS_STOP;
+               cloud_request_retry_trigger(NULL);
+       } else if (is_retry == false) { // if Cloud Session valid, then Stop Cloud Connection. And Don't Retry.
+               del_all_request_handle();
+               g_qis_cloud_thread_running = CISESS_APDISCON;
+               esm_get_network_status();       // State return
+       }
+
+       return 1;
+}
+
+// -1 : System Error.  0 : No process.  1 : Sign-IN.
+int ci_retry_stop_by_tcp_cb(const char *addr_ip, const int port)
+{
+       int ret = 1;
+
+       pthread_mutex_lock(&g_es_tcp_session_mutex);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ci_port = 0;
+
+       if (g_qis_cloud_thread_running != CISESS_BUSY || g_cloud_port[0] == 0 || g_cloud_ip[0] == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Don't need something process. IP=%s, Port=%s, RunningState=%d", g_cloud_ip, g_cloud_port, g_qis_cloud_thread_running);
+               ret = 0;
+               goto GOTO_OUT;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IP = %s, port = %d", addr_ip, port);   // I expect that ( IP = 52.37.99.111, port = 443 )
+
+       if ((ci_port = atoi(g_cloud_port)) <= 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] Cloud Port is not invalid.(g_cloud_port = %s = %d)", g_cloud_port, ci_port);
+               ret = -1;
+               goto GOTO_OUT;
+       }
+
+       if (strncmp(g_cloud_ip, addr_ip, strlen(addr_ip)) != 0 || ci_port != port) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "We Support IP:Port is \"%s:%s\"", g_cloud_ip, g_cloud_port);
+               if (strncmp(g_cloud_ip, addr_ip, strlen(addr_ip)) != 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Delete OIC_Ping for IP=%s.(Cur_Cloud=%s)", addr_ip, g_cloud_ip);
+                       oic_ping_unset_mask(addr_ip, PING_ST_ISCLOUD);
+               }
+               ret = 0;
+               goto GOTO_OUT;
+       }
+       // Case Cloud Connection is BUSY & AP Connected.
+       if (es_get_cloud_login_state() == false) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "process Re-Transmission in Time-Out Process instated of this.");
+               ret = 0;
+               goto GOTO_OUT;
+       }
+       // Force Strong Re Sign-IN or new Sign-UP start.
+       force_session_stop(CISESS_SIGNOUT);
+       cloud_request_retry_trigger(NULL);
+
+GOTO_OUT:
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       pthread_mutex_unlock(&g_es_tcp_session_mutex);
+
+       return ret;
+}
+
+bool es_cloud_session_stop_trigger(things_es_enrollee_state_e es_state)
+{
+       //THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (g_qis_cloud_thread_running != CISESS_APDISCON) {
+               if ((g_qis_cloud_thread_running == CISESS_STOP_TRIGGER || (ES_STATE_INIT <= es_state && es_state <= ES_STATE_CONNECTED_TO_ENROLLER))
+                       && g_qis_cloud_thread_running != CISESS_SIGNOUT && es_get_cloud_login_state() == true) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Sign-Out Start.");
+                       log_in_out_to_cloud(false, NULL);
+                       return true;
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "es_state=%s, get_enrollee_state()=%s", get_prov_status(es_state), get_prov_status(get_enrollee_state()));
+
+               if (ES_STATE_INIT <= es_state && es_state <= ES_STATE_CONNECTED_TO_ENROLLER) {
+                       if (g_qis_cloud_thread_running != CISESS_BUSY && g_qis_cloud_thread_running != CISESS_APDISCON && es_get_cloud_login_state() == false) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Setting Cloud Semaphore init.");
+                               g_qis_cloud_thread_running = CISESS_STOP;
+                       }
+               }
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "g_qis_cloud_thread_running=%d", g_qis_cloud_thread_running);
+
+       //THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return false;
+}
+
+static int es_cloud_state_set_and_notify(things_cloud_status_e state, es_error_code_e es_err, OCClientResponse *response, ci_error_code_e *ci_err)
+{
+       const char *strState = get_prov_status(state);
+
+       if (strState == NULL || strncmp(strState, "UNKNOWN", strlen("UNKNOWN")) == 0 || state == ES_STATE_INIT || state == ES_STATE_CONNECTED_TO_ENROLLER) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "state is invalid value(%d)", state);
+               return -1;
+       }
+
+       if (es_set_state(state) == ES_ERROR) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Cloud State(%s) is failed.", strState);
+               return 1;
+       }
+
+       if (response != NULL && ci_err != NULL) {
+               // Method don't care because issue is not occurred by it.
+               if (get_cloud_code(response, OC_REST_POST, ci_err) == 0) {
+                       *ci_err = ERRCI_UNKNOWN;
+               }
+
+               es_set_cloud_error_code(*ci_err);
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Provisioning last_err_code = %d", es_err);
+               if (es_err == ES_ERRCODE_UNKNOWN) {
+                       es_set_cloud_error_code(ERRCI_UNKNOWN);
+               } else {
+                       es_set_error_code(es_err);
+               }
+       }
+
+       prov_rsc_notify_all_observers();
+
+       switch (state) {
+       case ES_STATE_FAILED_TO_REGISTER_TO_CLOUD:
+       case ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD:
+               ci_finish_cloud_con(0);
+               break;
+       case ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD:
+               ci_finish_cloud_con(1);
+               break;
+       }
+
+       return 0;
+}
+
+void es_cloud_signup_clear(es_cloud_signup_s *data)
+{
+       if (data == NULL) {
+               return;
+       }
+
+       if (data->domain != NULL) {
+               things_free(data->domain);
+               data->domain = NULL;
+       }
+
+       if (data->address != NULL) {
+               things_free(data->address);
+               data->address = NULL;
+       }
+
+       if (data->port != NULL) {
+               things_free(data->port);
+               data->port = NULL;
+       }
+
+       if (data->access_token != NULL) {
+               things_free(data->access_token);
+               data->access_token = NULL;
+       }
+
+       if (data->refresh_token != NULL) {
+               things_free(data->refresh_token);
+               data->refresh_token = NULL;
+       }
+
+       if (data->token_type != NULL) {
+               things_free(data->token_type);
+               data->token_type = NULL;
+       }
+
+       if (data->certificate != NULL) {
+               things_free(data->certificate);
+               data->certificate = NULL;
+       }
+
+       if (data->redirect_uri != NULL) {
+               things_free(data->redirect_uri);
+               data->redirect_uri = NULL;
+       }
+
+       if (data->sid != NULL) {
+               things_free(data->sid);
+               data->sid = NULL;
+       }
+
+       if (data->uid != NULL) {
+               things_free(data->uid);
+               data->uid = NULL;
+       }
+
+       data->expire_time = CLOUD_EXPIRESIN_INVALID;
+
+       things_free(data);
+}
+
+bool es_cloud_signup_init(es_cloud_signup_s **data)
+{
+       if (data == NULL) {
+               return false;
+       }
+
+       if (*data != NULL) {
+               es_cloud_signup_clear(*data);
+               *data = NULL;
+       }
+
+       *data = (es_cloud_signup_s *) things_malloc(sizeof(es_cloud_signup_s));
+       if (*data == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "ESCloud_SignedUp struct data is NULL.");
+               return false;
+       }
+
+       (*data)->domain = NULL;
+       (*data)->address = NULL;
+       (*data)->port = NULL;
+       (*data)->access_token = NULL;
+       (*data)->refresh_token = NULL;
+       (*data)->certificate = NULL;
+       (*data)->expire_time = CLOUD_EXPIRESIN_INVALID;
+       (*data)->redirect_uri = NULL;
+       (*data)->sid = NULL;
+       (*data)->token_type = NULL;
+       (*data)->uid = NULL;
+
+       return true;
+}
+
+void *es_cloud_init(things_server_builder_s *server_builder)
+{
+       unsigned int time_v = (unsigned int)time(NULL);
+
+       if (time_v == -1) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "Random Number Initialization is Failed.");
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Random Number Initialization is Success.");
+               srand(time_v);
+       }
+
+       if (oic_ping_init() == false) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OICPing init is failed.");
+               return NULL;
+       }
+
+       del_all_request_handle();
+       memset(g_cloud_ip, 0, IP_PORT);
+       memset(g_cloud_port, 0, IP_PORT);
+       g_server_builder = server_builder;
+       g_resource_lists = NULL;
+       g_len = 0;
+//    gDelDeviceCompletFunc = NULL;
+       send_cnt_sign_up = 0;
+       retranslate_rsc_publish_cnt = 0;
+
+       ci_cp_init_event_pend();
+
+       CARegisterNetworkMonitorHandler((CAAdapterStateChangedCB) things_adapter_state_cb, (CAConnectionStateChangedCB) things_tcp_session_state_cb);
+
+       return (void *)g_server_builder;
+}
+
+void es_cloud_terminate(void)
+{
+       force_session_stop(CISESS_NULL);
+       ci_cp_del_pended_data();
+       ci_cp_del_is_there_cp();
+
+       CAUnregisterNetworkMonitorHandler((CAAdapterStateChangedCB) things_adapter_state_cb, (CAConnectionStateChangedCB) things_tcp_session_state_cb);
+
+       esm_get_network_status();
+
+       es_cloud_signup_clear(signed_up_data);
+       signed_up_data = NULL;
+       memset(g_cloud_address, 0, MAX_CI_ADDRESS);
+       memset(g_cloud_ip, 0, IP_PORT);
+       memset(g_cloud_port, 0, IP_PORT);
+
+       g_server_builder = NULL;
+       g_resource_lists = NULL;
+       g_len = 0;
+
+//    gDelDeviceCompletFunc = NULL;
+       send_cnt_sign_up = 0;
+       retranslate_rsc_publish_cnt = 0;
+
+       oic_ping_terminate();
+}
+static int get_cloud_code(OCClientResponse *response, OCMethod method, ci_error_code_e *err)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter");
+
+       int ret = 0;
+       OCRepPayloadValue *val = NULL;
+       CAResponseResult_t rawResult = CA_EMPTY;
+
+       if (response == NULL || response->payload == NULL || err == NULL || method == OC_REST_NOMETHOD) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "response(0x%X) or err(0x%X) is NULL", response, err);
+               return ret;
+       }
+
+       rawResult = things_result_to_network_result(response->result, method);
+       *err = rawResult * ERR_UPPER_UNIT;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "result = %d, rawResult = %d, method = %d, *err = %d", response->result, rawResult, method, *err);
+
+       val = ((OCRepPayload *) response->payload)->values;
+
+       while (val != NULL) {
+               if (strncmp(val->name, CLOUD_ERROR_CODE, strlen(CLOUD_ERROR_CODE)) == 0) {
+                       if (val->type != OCREP_PROP_INT) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DataType of Cloud-Err-Code is not Integer.");
+                       } else {
+                               *err += (ci_error_code_e) val->i;
+                               ret = 1;
+                       }
+
+                       break;
+               }
+
+               val = val->next;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "*err = %d, ret = %d", *err, ret);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit");
+       return ret;
+}
+
+static CAResponseResult_t things_result_to_network_result(OCStackResult oc_code, OCMethod method)
+{
+       CAResponseResult_t ret = CA_EMPTY;
+
+       switch (oc_code) {
+       case OC_STACK_OK:
+               switch (method) {
+               case OC_REST_PUT:
+               case OC_REST_POST:
+                       // This Response Code is like HTTP 204 "No Content" but only used in
+                       // response to POST and PUT requests.
+                       ret = CA_CHANGED;
+                       break;
+               case OC_REST_GET:
+                       // This Response Code is like HTTP 200 "OK" but only used in response to
+                       // GET requests.
+                       ret = CA_CONTENT;
+                       break;
+               default:
+                       // This should not happen but,
+                       // give it a value just in case but output an error
+                       ret = CA_CONTENT;
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Unexpected OC_STACK_OK return code for method [%d].", method);
+               }
+               break;
+       case OC_STACK_RESOURCE_CREATED:
+               ret = CA_CREATED;
+               break;
+       case OC_STACK_RESOURCE_DELETED:
+               ret = CA_DELETED;
+               break;
+       case OC_STACK_RESOURCE_CHANGED:
+               ret = CA_CHANGED;
+               break;
+       case OC_STACK_INVALID_QUERY:
+               ret = CA_BAD_REQ;
+               break;
+       case OC_STACK_INVALID_OPTION:
+               ret = CA_BAD_OPT;
+               break;
+       case OC_STACK_FORBIDDEN_REQ:
+               ret = CA_FORBIDDEN_REQ;
+               break;
+       case OC_STACK_NO_RESOURCE:
+               ret = CA_NOT_FOUND;
+               break;
+       case OC_STACK_COMM_ERROR:
+               ret = CA_RETRANSMIT_TIMEOUT;
+               break;
+       case OC_STACK_UNAUTHORIZED_REQ:
+               ret = CA_UNAUTHORIZED_REQ;
+               break;
+       case OC_STACK_INTERNAL_SERVER_ERROR:
+               ret = CA_INTERNAL_SERVER_ERROR;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+static char *make_ip_port(char *p_ip, char *p_port)
+{
+       char *ipport = NULL;
+       int length = 0;
+
+       if (p_ip == NULL || p_port == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "IP=%s, or Port=%s is NULL.", p_ip, p_port);
+               return NULL;
+       }
+
+       length = strlen(p_ip) + strlen(p_port) + 2;
+       if ((ipport = (char *)things_malloc(length)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Memory allocation is failed.");
+               return NULL;
+       }
+
+       memset(ipport, 0, length);
+       if (things_strcat(ipport, length, p_ip) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "things_strcat is failed.");
+               things_free(ipport);
+               return NULL;
+       }
+       ipport[strlen(p_ip)] = ':';
+       if (things_strcat(ipport, length, p_port) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "things_strcat is failed.");
+               things_free(ipport);
+               return NULL;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IP=%s, Port=%s, ipport=%s", p_ip, p_port, ipport);
+       return ipport;
+}
+
+static es_cloud_event_timeout_s *clone_data_add_timeout(es_cloud_prov_data_s *cloud_data, timeout_s *timeout)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       es_cloud_event_timeout_s *cloned_data = NULL;
+
+       if (cloud_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud_data is NULL.");
+               return NULL;
+       }
+
+       if ((cloned_data = (es_cloud_event_timeout_s *) things_malloc(sizeof(es_cloud_event_timeout_s) * 1)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Memory allocation is failed.");
+               return NULL;
+       }
+
+       clone_es_cloud_prov_data(&cloned_data->event, cloud_data);
+
+       if (timeout == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Default Setting to cloned Cloud Data.");
+               cloned_data->timeOut.cur_counter = DEFAULT_TIMEOUT;
+               cloned_data->timeOut.cur_num = DEFAULT_TIMEOUT;
+               cloned_data->timeOut.ori_num = DEFAULT_TIMEOUT;
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Custom Setting to cloned Cloud Data.");
+               cloned_data->timeOut.cur_counter = timeout->cur_counter;
+               cloned_data->timeOut.cur_num = timeout->cur_num;
+               cloned_data->timeOut.ori_num = timeout->ori_num;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cur_counter = %d, cur_num = %d, ori_num = %d", cloned_data->timeOut.cur_counter, cloned_data->timeOut.cur_num, cloned_data->timeOut.ori_num);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cloned_data add= 0x%X", cloned_data);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return cloned_data;
+}
+
+static void ci_finish_cloud_con(int result)
+{
+       char *domain = NULL;
+       char *access_token = NULL;
+       es_cloud_signup_s *Cloud_data = NULL;
+
+       if (things_res_cb_function) {
+               dm_load_legacy_cloud_data(&Cloud_data); // TODO read Cloud-Data.
+               if (Cloud_data != NULL) {
+                       if (Cloud_data->domain != NULL) {
+                               domain = strdup(Cloud_data->domain);
+                       }
+                       if (Cloud_data->access_token != NULL) {
+                               access_token = strdup(Cloud_data->access_token);
+                       }
+               }
+
+               things_res_cb_function(result, domain, access_token);
+               things_res_cb_function = NULL;
+       }
+
+       if (domain) {
+               things_free(domain);
+               domain = NULL;
+       }
+
+       if (access_token) {
+               things_free(access_token);
+               access_token = NULL;
+       }
+}
+
+static void publish_dev_profile_into_cloud(timeout_s *timeout)
+{
+       if (things_cloud_dev_profile_publish(g_cloud_address, handle_dev_profile_cb, handle_dev_profile_timeout, timeout) != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Publish Device Profile request is failed.");
+       }
+}
diff --git a/framework/src/st_things/things_stack/src/common/cloud/inc/cloud_connector.h b/framework/src/st_things/things_stack/src/common/cloud/inc/cloud_connector.h
new file mode 100644 (file)
index 0000000..d3095da
--- /dev/null
@@ -0,0 +1,97 @@
+/****************************************************************************\r
+ *\r
+ * Copyright 2017 Samsung Electronics All Rights Reserved.\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,\r
+ * software distributed under the License is distributed on an\r
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
+ * either express or implied. See the License for the specific\r
+ * language governing permissions and limitations under the License.\r
+ *\r
+ ****************************************************************************/\r
+\r
+#ifndef _CLOUD_CONNECTOR_H_\r
+#define _CLOUD_CONNECTOR_H_\r
+\r
+#include "ocstack.h"\r
+#include "things_resource.h"\r
+#include "things_wait_handler.h"\r
+#include "es_common.h"\r
+\r
+#define DEFAULT_CONTEXT_VALUE   0x99\r
+\r
+#define KEY_TOKEN_ACCESS           "accesstoken"       // mandatory\r
+#define KEY_TOKEN_ACCESS_REFRESH   "refreshtoken"      // mandatory\r
+#define KEY_TOKEN_TYPE                    "token_type" // mandatory\r
+#define KEY_EXPIRE_TIME                           "expiresin"  // mandatory\r
+#define KEY_ID_USER                "uid"       // mandatory\r
+#define KEY_SERVER_REDIRECT_URI    "redirect_uri"      // option\r
+#define KEY_CERTIFICATE_FILE       "certificate"       // option\r
+#define KEY_SERVER_ID              "sid"       // option\r
+#define KEY_ID_DEVICE              "di"\r
+#define KEY_LOGINOUT               "login"\r
+#define KEY_ICORE_VER              "coreversion"\r
+#define KEY_IOTIVITY_VER           "verticalversion"\r
+#define KEY_TYPE_GRANT             "granttype"\r
+#define CLOUD_ERROR_CODE            "code"\r
+#define VALUE_TYPE_GRANT_TOKEN     "refresh_token"\r
+\r
+\r
+int ci_connection_pre_check(const char *domain_name, char **p_ip);\r
+\r
+\r
+OCStackResult things_cloud_signup(const char *host,\r
+                                                                 const char *device_id,\r
+                                                                 const es_cloud_prov_data_s *event_data,\r
+                                                                 OCClientResponseHandler response,\r
+                                                                 check_time_out_call_func timeout_handler,\r
+                                                                 timeout_s *timeout);\r
+\r
+OCStackResult things_cloud_session(const char *host,\r
+                                                                  const char *uId,\r
+                                                                  const char *device_id,\r
+                                                                  const char *accesstoken,\r
+                                                                  bool is_login,\r
+                                                                  OCClientResponseHandler response,\r
+                                                                  check_time_out_call_func timeout_handler,\r
+                                                                  timeout_s *timeout);\r
+\r
+OCStackResult things_cloud_rsc_publish(char *host,\r
+                                                                          things_resource_s **list,\r
+                                                                          int length,\r
+                                                                          OCClientResponseHandler response,\r
+                                                                          check_time_out_call_func timeout_handler,\r
+                                                                          timeout_s *timeout);\r
+\r
+OCStackResult things_cloud_rsc_publish_with_device_id(char *host,\r
+               const char *id,\r
+               things_resource_s **list,\r
+               int length,\r
+               OCClientResponseHandler response,\r
+               check_time_out_call_func timeout_handler,\r
+               timeout_s *timeout);\r
+\r
+OCStackResult things_cloud_dev_profile_publish(char *host,\r
+               OCClientResponseHandler response,\r
+               check_time_out_call_func timeout_handler,\r
+               timeout_s *timeout);\r
+\r
+OCStackResult things_cloud_refresh(const char *host,\r
+                                                                  const char *uId,\r
+                                                                  const char *device_id,\r
+                                                                  const char *refreshtoken,\r
+                                                                  OCClientResponseHandler response);\r
+\r
+extern OCStackResult things_cloud_topic_publish_topic(const char *host,\r
+               const char *topic,\r
+               OCRepPayload *payload,\r
+               OCClientResponseHandler response);\r
+\r
+#endif /* \r
+ */\r
diff --git a/framework/src/st_things/things_stack/src/common/cloud/inc/cloud_evtpend.h b/framework/src/st_things/things_stack/src/common/cloud/inc/cloud_evtpend.h
new file mode 100644 (file)
index 0000000..6d2dde6
--- /dev/null
@@ -0,0 +1,49 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef CLOUD_EVENTDATA_PENDING_PROCESS
+#define CLOUD_EVENTDATA_PENDING_PROCESS
+
+#include "es_common.h"
+
+typedef struct es_cloud_pending_event_s {
+       bool exist;
+       bool is_there_ci_prov;
+       int using_count;
+       es_cloud_prov_data_s event;
+} es_cloud_pending_event_s;
+
+void ci_cp_init_event_pend(void);
+
+es_cloud_prov_data_s *ci_cp_get_pended_data(void);
+
+bool ci_cp_get_is_there_cp(void);
+
+bool ci_cp_cas_is_there_cp_if_false(void);
+
+void ci_cp_del_pended_data(void);
+
+void ci_cp_del_is_there_cp(void);
+
+int ci_cp_pend_event_data(es_cloud_prov_data_s *event_data);
+
+int ci_cp_enter_pend_data_block(void);
+
+int ci_cp_release_penddata_block(void);
+
+#endif                                                 // CLOUD_EVENTDATA_PENDING_PROCESS
diff --git a/framework/src/st_things/things_stack/src/common/cloud/inc/cloud_manager.h b/framework/src/st_things/things_stack/src/common/cloud/inc/cloud_manager.h
new file mode 100644 (file)
index 0000000..8f5b4e3
--- /dev/null
@@ -0,0 +1,94 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _CLOUD_MANAGER_H_
+#define _CLOUD_MANAGER_H_
+
+#include "things_resource.h"
+#include "es_common.h"
+#include "cloud_connector.h"
+#include "things_server_builder.h"
+#include <stdint.h>
+
+#define CI_COMMON_REFRESH_TIME      12 // access token Refresh period time without accesstoken-expire. (unit: hour)
+#define CI_TOKEN_EXPIRECHECK_TIME   3000       // access token Check period time whether it's expired or available. (unit: second)
+
+#define CLOUD_EXPIRESIN_INVALID                -1
+
+#ifdef __SECURED__
+#define DEFAULT_COAP_TCP_HOST "coaps+tcp://"
+#define UNSUPPORT_COAP_TCP_HOST "coap+tcp://"
+#define DEFAULT_COAP_PORT "443"
+#else
+#define DEFAULT_COAP_TCP_HOST "coap+tcp://"
+#define UNSUPPORT_COAP_TCP_HOST "coaps+tcp://"
+#define DEFAULT_COAP_PORT "5683"
+#endif
+
+typedef enum rp_target_e {
+       RSC_PUB_ALL = 0,
+       RSC_PUB_MAIN_ONLY = 1,
+       RSC_PUB_SUB_ALL = 2,
+       RSC_PUB_NEED_SUB_ONLY = 3,
+} rp_target_e;
+
+typedef struct es_cloud_signup_s {
+       char *domain;
+       char *address;
+       char *port;
+       char *access_token;
+       char *refresh_token;
+       char *token_type;
+       int64_t expire_time;
+       char *uid;
+       char *redirect_uri;
+       char *certificate;
+       char *sid;
+} es_cloud_signup_s;
+
+void *es_cloud_init(things_server_builder_s *server_builder);
+
+void es_cloud_terminate(void);
+
+void es_cloud_signup_clear(es_cloud_signup_s *data);
+
+bool es_cloud_signup_init(es_cloud_signup_s **data);
+
+bool es_cloud_session_stop_trigger(things_es_enrollee_state_e es_state);
+
+OCStackResult publish_resource_into_cloud(rp_target_e target, timeout_s *timeout);
+
+OCStackResult log_in_out_to_cloud(bool value, timeout_s *timeout);
+
+OCStackResult find_cloud_resource(void);
+
+OCStackResult refresh_token_into_cloud(void);
+
+void *cloud_data_cb_esm(es_cloud_prov_data_s *event_data);
+
+int cloud_retry_sign_in(timeout_s *timeout);
+
+int ci_retry_stop_by_wifi_cb(bool is_retry);
+
+int ci_retry_stop_by_tcp_cb(const char *addr_ip, const int port);
+
+int push_notification_to_cloud(const char *uri, OCRepPayload *payload);
+
+void ci_stop_cloud_connection(void *cb_func);
+
+#endif                                                 // _CLOUD_MANAGER_H_
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/Make.defs b/framework/src/st_things/things_stack/src/common/easy-setup/Make.defs
new file mode 100644 (file)
index 0000000..304d7dc
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += easysetup.c easysetup_manager.c resource_handler.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/easy-setup
+VPATH += :src/st_things/things_stack/src/common/easy-setup
\ No newline at end of file
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/easysetup.c b/framework/src/st_things/things_stack/src/common/easy-setup/easysetup.c
new file mode 100644 (file)
index 0000000..ae99917
--- /dev/null
@@ -0,0 +1,305 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "octypes.h"
+#include "easysetup.h"
+#include "things_logger.h"
+#include "resource_handler.h"
+#include "oic_string.h"
+#include "cloud_manager.h"
+#include "things_api.h"
+
+#define ES_ENROLLEE_TAG "[easysetup]"
+
+static bool g_is_secured = false;
+
+static es_provisioning_callbacks_s g_es_provisioning_cb;
+static es_device_property g_es_device_property;
+static things_get_easysetup_state_func_type g_notify_easysetup_state = NULL;
+
+void es_register_notify_easysetup_state(void *func)
+{
+       g_notify_easysetup_state = (things_get_easysetup_state_func_type) func;
+}
+
+void ESWiFiRsrcCallback(es_result_e es_result, es_wifi_prov_data_s *event_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "ESWiFiRsrcCallback IN");
+
+       if (es_result != ES_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "ESWiFiRsrcCallback ES_ERROR Occured");
+               return;
+       }
+       // deliver data to es_provisioning_callbacks_s
+       if (g_es_provisioning_cb.wifi_prov_cb != NULL) {
+               g_es_provisioning_cb.wifi_prov_cb(event_data);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "wifi_prov_cb is NULL");
+               return;
+       }
+}
+
+void ESCloudRsrcCallback(es_result_e es_resoult, es_cloud_prov_data_s *event_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "ESCloudRsrcCallback IN");
+
+       if (es_resoult != ES_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "ESCloudRsrcCallback ES_ERROR Occured");
+               return;
+       }
+
+       if (g_es_provisioning_cb.cloud_data_prov_cb != NULL) {
+               g_es_provisioning_cb.cloud_data_prov_cb(event_data);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "cloud_data_prov_cb is NULL");
+               return;
+       }
+}
+
+void ESDevconfRsrcallback(es_result_e es_resoult, es_dev_conf_prov_data_s *event_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "ESDevconfRsrcallback IN");
+
+       if (es_resoult != ES_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "ESDevconfRsrcallback ES_ERROR Occured");
+               return;
+       }
+
+       if (g_es_provisioning_cb.dev_conf_prov_cb != NULL) {
+               g_es_provisioning_cb.dev_conf_prov_cb(event_data);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "dev_conf_prov_cb is NULL");
+               return;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "ESDevconfRsrcallback OUT");
+}
+
+es_result_e es_init_enrollee(bool is_secured, es_resource_mask_e resource_mask, es_provisioning_callbacks_s callbacks)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_init_enrollee IN");
+
+       g_is_secured = is_secured;
+       g_es_provisioning_cb.wifi_prov_cb = NULL;
+       g_es_provisioning_cb.dev_conf_prov_cb = NULL;
+       g_es_provisioning_cb.cloud_data_prov_cb = NULL;
+
+       if ((resource_mask & ES_WIFI_RESOURCE) == ES_WIFI_RESOURCE) {
+               if (callbacks.wifi_prov_cb != NULL) {
+                       g_es_provisioning_cb.wifi_prov_cb = callbacks.wifi_prov_cb;
+                       register_wifi_rsrc_event_callback(ESWiFiRsrcCallback);
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "wifi_prov_cb NULL");
+                       return ES_ERROR;
+               }
+       }
+       if ((resource_mask & ES_DEVCONF_RESOURCE) == ES_DEVCONF_RESOURCE) {
+               if (callbacks.dev_conf_prov_cb != NULL) {
+                       g_es_provisioning_cb.dev_conf_prov_cb = callbacks.dev_conf_prov_cb;
+                       register_dev_conf_rsrc_event_callback(ESDevconfRsrcallback);
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "dev_conf_prov_cb NULL");
+                       return ES_ERROR;
+               }
+       }
+       if ((resource_mask & ES_CLOUD_RESOURCE) == ES_CLOUD_RESOURCE) {
+               if (callbacks.cloud_data_prov_cb != NULL) {
+                       g_es_provisioning_cb.cloud_data_prov_cb = callbacks.cloud_data_prov_cb;
+                       register_cloud_rsrc_event_callback(ESCloudRsrcCallback);
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "cloud_data_prov_cb NULL");
+                       return ES_ERROR;
+               }
+       }
+
+       if (create_easysetup_resources(g_is_secured, resource_mask) != OC_STACK_OK) {
+               unregister_resource_event_callback();
+
+               if (delete_easysetup_resources() != OC_STACK_OK) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "Deleting prov resource ES_ERROR!!");
+               }
+
+               return ES_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_init_enrollee OUT");
+       return ES_OK;
+}
+
+things_es_enrollee_state_e es_get_state(void)
+{
+       return get_enrollee_state();
+}
+
+bool es_get_cloud_login_state(void)
+{
+       switch (get_enrollee_state()) {
+       case ES_STATE_REGISTERED_TO_CLOUD:
+       case ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD:
+       case ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD:
+       case ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD:
+               return true;
+       }
+
+       return false;
+}
+
+es_result_e es_set_device_property(es_device_property *device_property)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_device_property IN");
+
+       if (set_device_property(device_property) != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "es_set_device_property ES_ERROR");
+               return ES_ERROR;
+       }
+
+       int mode_idx = 0;
+       while ((device_property->WiFi).mode[mode_idx] != WiFi_EOF) {
+               (g_es_device_property.WiFi).mode[mode_idx] = (device_property->WiFi).mode[mode_idx];
+               THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "WiFi Mode : %d", (g_es_device_property.WiFi).mode[mode_idx]);
+               mode_idx++;
+       }
+       (g_es_device_property.WiFi).freq = (device_property->WiFi).freq;
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "WiFi Freq : %d", (g_es_device_property.WiFi).freq);
+
+       things_strncpy((g_es_device_property.dev_conf_s).device_name, (device_property->dev_conf_s).device_name, MAX_DEVICELEN);
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "Device Name : %s", (g_es_device_property.dev_conf_s).device_name);
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_device_property OUT");
+       return ES_OK;
+}
+
+es_result_e es_set_state(things_es_enrollee_state_e es_state)
+{
+       //THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_state IN");
+       OCStackResult res = OC_STACK_ERROR;
+
+       if (es_state < ES_STATE_INIT || es_state >= ES_STATE_EOF) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "Invalid things_es_enrollee_state_e : %d", es_state);
+               return ES_ERROR;
+       }
+
+       if (es_cloud_session_stop_trigger(es_state) == true) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "Cloud Connection Log-Out ing...");
+               return ES_ERROR;
+       }
+
+       if ((res = set_enrollee_state(es_state)) == OC_STACK_ERROR) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "es_set_state setting is failed.");
+               return ES_ERROR;
+       }
+
+       if (g_notify_easysetup_state != NULL && res == OC_STACK_OK) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "Notify Easy-Setup State to THINGS_APP. %d", es_state);
+               g_notify_easysetup_state(es_state);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "Set ESState succesfully : %d", es_state);
+       //THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_state OUT");
+       return ES_OK;
+}
+
+static es_error_code_e ci_errcode_to_es_errcode(ci_error_code_e cm_err_code)
+{
+       es_error_code_e es_err_code = ES_ERRCODE_NO_ERROR;
+
+       switch (cm_err_code) {
+       case ERRCI_NO_ERROR:
+       case ERRCI_SUCCESS:
+               es_err_code = ES_ERRCODE_NO_ERROR;
+               break;
+       case ERRCI_SAMSUNG_ACCOUNT_AUTHORIZATION_FAILED:
+       case ERRCI_SAMSUNG_ACCOUNT_UNAUTHORIZED_TOKEN:
+               es_err_code = ES_ERRCODE_INVALID_AUTHCODE;
+               break;
+       case ERRCI_TOKEN_VALIDATION_FAILED:
+               es_err_code = ES_ERRCODE_INVALID_ACCESSTOKEN;
+               break;
+       case ERRCI_DEVICE_NOT_FOUND:
+               es_err_code = ES_ERRCODE_FAILED_TO_FIND_REGISTERED_DEVICE_IN_CLOUD;
+               break;
+       case ERRCI_USER_NOT_FOUND:
+               es_err_code = ES_ERRCODE_FAILED_TO_FIND_REGISTERED_USER_IN_CLOUD;
+               break;
+       default:
+               es_err_code = ES_ERRCODE_UNKNOWN;
+               break;
+       }
+
+       return es_err_code;
+}
+
+es_result_e es_set_error_code(es_error_code_e es_err_code)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_error_code IN");
+
+       if (es_err_code < ES_ERRCODE_NO_ERROR || es_err_code > ES_ERRCODE_UNKNOWN) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "Invalid es_set_error_code : %d", es_err_code);
+               return ES_ERROR;
+       }
+
+       if (set_enrollee_err_code(es_err_code) != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "es_set_error_code ES_ERROR");
+               return ES_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "Set es_error_code_e successfully : %d", es_err_code);
+       return ES_OK;
+}
+
+es_result_e es_set_cloud_error_code(ci_error_code_e es_err_code)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_cloud_error_code IN");
+
+       es_error_code_e esError = ES_ERRCODE_NO_ERROR;
+
+       if (es_err_code < ERRCI_NO_ERROR || es_err_code > ERRCI_UNKNOWN) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "Invalid es_set_cloud_error_code : %d", es_err_code);
+               return ES_ERROR;
+       }
+
+       esError = ci_errcode_to_es_errcode(es_err_code);
+
+       if (set_cloud_err_code(es_err_code) != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "es_set_cloud_error_code ES_ERROR");
+               return ES_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "Set es_error_code_e successfully : %d", es_err_code);
+
+       es_set_error_code(esError);
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_set_cloud_error_code OUT");
+       return ES_OK;
+}
+
+es_result_e es_terminate_enrollee()
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_terminate_enrollee IN");
+
+       unregister_resource_event_callback();
+
+       //Delete Prov resource
+       if (delete_easysetup_resources() != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_ENROLLEE_TAG, "Deleting prov resource ES_ERROR!!");
+               return ES_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_ENROLLEE_TAG, "es_terminate_enrollee success");
+       return ES_OK;
+}
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/easysetup_manager.c b/framework/src/st_things/things_stack/src/common/easy-setup/easysetup_manager.c
new file mode 100644 (file)
index 0000000..0b9310b
--- /dev/null
@@ -0,0 +1,979 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#define _BSD_SOURCE                            // for the usleep
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/select.h>
+
+#include "../utils/inc/things_network.h"
+#include "things_wait_handler.h"
+#include "easysetup_manager.h"
+#include "resource_handler.h"
+#include "cloud_manager.h"
+#include "easysetup.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+
+#include "things_thread.h"
+#include "things_rtos_util.h"
+
+#ifdef __SECURED__
+#include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
+#endif                                                 // #ifdef __SECURED__
+
+#define TAG "[ezsetup-mg]"
+#define MAX_REFRESHCHECK_CNT    30     // 30 times
+
+es_dev_conf_prov_data_s *g_dev_conf_prov_data = NULL;
+es_wifi_prov_data_s *g_wifi_prov_data = NULL;
+es_cloud_prov_data_s *g_cloud_prov_data = NULL;
+
+static things_server_builder_s *g_server_builder = NULL;
+static things_update_dev_prov_data_func_type g_update_dev_prov_data = NULL;
+static pin_generated_func_type g_pin_generated_cb = NULL;
+static pin_close_func_type g_pin_close_cb = NULL;
+static user_confirm_result_func_type g_user_confirm_cb = NULL;
+
+int esm_continue = 0;
+#ifdef __ST_THINGS_RTOS__
+int ci_token_expire_fds[2] = { -1, -1 };
+#endif
+static pthread_t gthread_id_network_status_check = 0;
+static pthread_t gthread_id_cloud_refresh_check = 0;
+
+static const int i_common_sleep_sec = CI_TOKEN_EXPIRECHECK_TIME;
+static const int i_fail_sleep_sec = 60;        // 60 sec
+static pthread_mutex_t g_es_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static bool is_set_device_property = false;
+static es_device_property device_property;
+static const char *def_device_name = "ST_Things Device";
+
+void wifi_prov_cb_in_app(es_wifi_prov_data_s *event_data);
+void dev_conf_prov_cb_in_app(es_dev_conf_prov_data_s *event_data);
+void cloud_data_prov_cb_in_app(es_cloud_prov_data_s *event_data);
+
+typedef void (*callback_to_app)(es_cloud_prov_data_s *);
+callback_to_app g_cloud_data_cb_to_app = NULL;
+
+es_provisioning_callbacks_s g_callbacks = {
+       .wifi_prov_cb = &wifi_prov_cb_in_app,
+       .dev_conf_prov_cb = &dev_conf_prov_cb_in_app,
+       .cloud_data_prov_cb = &cloud_data_prov_cb_in_app
+};
+
+static void *wifi_prov_set_loop(void *param);
+static void *cloud_refresh_check_loop(void *param);
+static void *wifi_prov_timeout_handler(timeout_s *param);
+
+#ifdef __SECURED__
+void generate_pin_cb(char *pin, size_t pin_size)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (NULL == pin || pin_size <= 0) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "INVALID PIN");
+               return;
+       }
+
+       THINGS_LOG_V(THINGS_INFO, TAG, "PIN CODE : %s", pin);
+
+       // TODO: print out pin number using display panel - ysy
+       if (g_pin_generated_cb) {
+               g_pin_generated_cb(pin, pin_size);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "PIN GENERATED CB Not Registered~!!!");
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+void pin_close_cb(void)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       // TODO: print out pin number using display panel - ysy
+       if (g_pin_close_cb) {
+               g_pin_close_cb();
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "PIN GENERATED CB Not Registered~!!!");
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+OCStackResult get_user_confirmation(void *ctx)
+{
+       OCStackResult ret = OC_STACK_USER_DENIED_REQ;
+
+       if (g_user_confirm_cb) {
+               int result = g_user_confirm_cb();
+
+               switch (result) {
+               case 1: {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "User Confirmed~!!");
+                       ret = OC_STACK_OK;
+                       break;
+               }
+               default: {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "User Denied~!! : [ %d ]", result);
+                       break;
+               }
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "MUTUAL AUTHENTICATION CONFIRM CB Not Registered~!!!");
+       }
+
+       THINGS_LOG_V(THINGS_INFO, TAG, "User Confirm Result : [ %d ]", ret);
+
+       return ret;
+}
+
+#endif                                                 //#ifdef __SECURED__
+
+/*******************************************************************
+ *
+ * st_things API Function register
+ *
+ *******************************************************************/
+void esm_register_update_dev_prov_data_func(things_update_dev_prov_data_func_type func)
+{
+       g_update_dev_prov_data = func;
+}
+
+int esm_set_device_property_by_app(char *name, const wifi_mode_e *mode, int ea_mode, const wifi_freq_e freq)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       int i = 0;
+
+       if (mode == NULL || ea_mode < 1 || WiFi_24G > freq || freq >= WiFi_FREQ_EOF) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Input Arguments.(mode=0x%X, ea_mode=%d, freq=%d)", mode, ea_mode, freq);
+               return 0;
+       }
+
+       if (name == NULL) {
+               name = def_device_name;
+       }
+
+       if (ea_mode > NUM_WIFIMODE - 1) {
+               ea_mode = NUM_WIFIMODE - 1;
+       }
+
+       things_strncpy(device_property.dev_conf_s.device_name, name, sizeof(device_property.dev_conf_s.device_name));
+       device_property.WiFi.freq = freq;
+       for (i = 0; i < ea_mode; i++) {
+               device_property.WiFi.mode[i] = mode[i];
+       }
+       device_property.WiFi.mode[ea_mode] = WiFi_EOF;
+       is_set_device_property = true;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "device_name=%s, WiFi_frequence=%d, count of WiFi_mode=%d", device_property.dev_conf_s.device_name, device_property.WiFi.freq, ea_mode);
+       for (i = 0; i <= ea_mode; i++) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "WiFi_mode[%d]=%d", i, device_property.WiFi.mode[i]);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.(result=%d)", is_set_device_property);
+       return 1;
+}
+
+esm_result_e esm_init_easysetup(int restart_flag, things_server_builder_s *server_builder)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "Init EasySetup");
+
+       wifi_mode_e wifi_mode[5] = { 0, };
+       wifi_freq_e wifi_freq = dm_get_wifi_property_freq();
+       int wifiIntf = dm_get_wifi_property_interface();
+       int mode_count = 0;
+
+       if (wifiIntf) {
+               if (wifiIntf & 0x01) {
+                       wifi_mode[mode_count++] = WiFi_11A;
+               }
+               if (wifiIntf & 0x02) {
+                       wifi_mode[mode_count++] = WiFi_11B;
+               }
+               if (wifiIntf & 0x04) {
+                       wifi_mode[mode_count++] = WiFi_11G;
+               }
+               if (wifiIntf & 0x08) {
+                       wifi_mode[mode_count++] = WiFi_11N;
+               }
+               if (wifiIntf & 0x10) {
+                       wifi_mode[mode_count++] = WiFi_11AC;
+               }
+       }
+       esm_set_device_property_by_app(NULL, wifi_mode, mode_count, wifi_freq);
+
+       if (is_set_device_property == false) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "[Error] Please Check whether you call \"OICSetDeviceProperty\" API.(We need value of WiFi-property.)");
+               return ESM_ERROR;
+       }
+
+       if (restart_flag == 1 || g_dev_conf_prov_data || g_wifi_prov_data || g_cloud_prov_data) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "Restart EasySetup");
+               esm_continue = 0;
+               if (gthread_id_cloud_refresh_check) {
+#ifdef __ST_THINGS_RTOS__
+                       if (ci_token_expire_fds[1] != -1) {
+                               ssize_t len = 0;
+                               do {
+                                       len = write(ci_token_expire_fds[1], "w", 1);
+                               } while ((len == -1) && (errno == EINTR));
+                               if ((len == -1) && (errno != EINTR) && (errno != EPIPE)) {
+                                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "write failed: %s", strerror(errno));
+                                       return ESM_ERROR;
+                               }
+                       }
+                       pthread_join(gthread_id_cloud_refresh_check, NULL);
+                       close(ci_token_expire_fds[0]);
+                       close(ci_token_expire_fds[1]);
+                       ci_token_expire_fds[0] = -1;
+                       ci_token_expire_fds[1] = -1;
+#else
+                       pthread_join(gthread_id_cloud_refresh_check, NULL);
+#endif
+                       gthread_id_cloud_refresh_check = 0;
+               }
+
+               if (gthread_id_network_status_check) {
+                       pthread_join(gthread_id_network_status_check, NULL);
+                       gthread_id_network_status_check = 0;
+               }
+
+               if (es_terminate_enrollee() == ES_ERROR) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Init EasySetup Failed");
+                       return ESM_ERROR;
+               }
+
+               if (g_dev_conf_prov_data) {
+                       things_free(g_dev_conf_prov_data);
+                       g_dev_conf_prov_data = NULL;
+               }
+
+               if (g_wifi_prov_data) {
+                       things_free(g_wifi_prov_data);
+                       g_wifi_prov_data = NULL;
+               }
+
+               if (g_cloud_prov_data) {
+                       things_free(g_cloud_prov_data);
+                       g_cloud_prov_data = NULL;
+               }
+       }
+
+       g_dev_conf_prov_data = (es_dev_conf_prov_data_s *) things_malloc(sizeof(es_dev_conf_prov_data_s));
+       g_wifi_prov_data = (es_wifi_prov_data_s *) things_malloc(sizeof(es_wifi_prov_data_s));
+       g_cloud_prov_data = (es_cloud_prov_data_s *) things_malloc(sizeof(es_cloud_prov_data_s));
+
+       if (g_dev_conf_prov_data == NULL || g_wifi_prov_data == NULL || g_cloud_prov_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Easy Setup Memory allocation is failed.");
+               return ESM_ERROR;
+       }
+//    es_device_property device_property = {
+//        {{WiFi_11G, WiFi_11N, WiFi_11AC, WiFi_EOF}, WiFi_5G}, {"Test Device"}
+//    };
+
+       if (server_builder != NULL) {
+               g_server_builder = server_builder;
+       }
+
+       if (g_server_builder == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] g_server_builder is NULL.");
+               return ESM_ERROR;
+       }
+#ifdef __SECURED__
+       bool g_is_secured = true;
+#else
+       bool g_is_secured = false;
+#endif
+
+       es_resource_mask_e resourcem_mask = ES_WIFI_RESOURCE | ES_CLOUD_RESOURCE | ES_DEVCONF_RESOURCE;
+       // Easy Setup Module Initiation
+
+       if (es_init_enrollee(g_is_secured, resourcem_mask, g_callbacks) != ES_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "StartEasySetup and onboarding Fail!!");
+               return ESM_ERROR;
+       }
+
+       es_set_state(ES_STATE_INIT);
+       es_set_error_code(ES_ERRCODE_NO_ERROR);
+
+       if (es_set_device_property(&device_property) == ES_ERROR) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "es_set_device_property funtion Failed");
+       }
+#ifdef __SECURED__
+
+       if (OC_STACK_OK != SetRandomPinPolicy(8, NUM_PIN)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Set to Non-Numerical PIN Generation~!!!!!");
+       } else {
+               THINGS_LOG(THINGS_INFO, TAG, "Set to Numerical PIN Generation~!!!!!");
+       }
+
+       SetGeneratePinCB(&generate_pin_cb);
+       SetClosePinDisplayCB(&pin_close_cb);
+       SetUserConfirmCB(NULL, get_user_confirmation);
+       SetVerifyOption(USER_CONFIRM);
+
+#endif                                                 //#ifdef __SECURED__
+       if (gthread_id_cloud_refresh_check == 0) {
+               int ret = pipe(ci_token_expire_fds);
+               if (-1 == ret) {
+                       close(ci_token_expire_fds[0]);
+                       close(ci_token_expire_fds[1]);
+                       ci_token_expire_fds[0] = -1;
+                       ci_token_expire_fds[1] = -1;
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "pipe failed: %s", strerror(errno));
+                       return ESM_ERROR;
+               }
+               esm_continue = 1;
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Create cloud_refresh_check_loop thread");
+#ifdef __ST_THINGS_RTOS__
+               pthread_create_rtos(&gthread_id_cloud_refresh_check, NULL, cloud_refresh_check_loop, (void *)&esm_continue, THINGS_STACK_CLOUD_REFRESH_THREAD);
+#else
+               things_thread_create(&gthread_id_cloud_refresh_check, NULL, cloud_refresh_check_loop, (void *)&esm_continue);
+#endif
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return ESM_OK;
+}
+
+esm_result_e esm_terminate_easysetup()
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Terminate EasySetup");
+       esm_continue = 0;
+       if (gthread_id_cloud_refresh_check) {
+#ifdef __ST_THINGS_RTOS__
+               if (ci_token_expire_fds[1] != -1) {
+                       ssize_t len = 0;
+                       do {
+                               len = write(ci_token_expire_fds[1], "w", 1);
+                       } while ((len == -1) && (errno == EINTR));
+                       if ((len == -1) && (errno != EINTR) && (errno != EPIPE)) {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "write failed: %s", strerror(errno));
+                               return ESM_ERROR;
+                       }
+               }
+               pthread_join(gthread_id_cloud_refresh_check, NULL);
+               close(ci_token_expire_fds[0]);
+               close(ci_token_expire_fds[1]);
+               ci_token_expire_fds[0] = -1;
+               ci_token_expire_fds[1] = -1;
+#else
+               pthread_join(gthread_id_cloud_refresh_check, NULL);
+#endif
+               gthread_id_cloud_refresh_check = 0;
+       }
+       if (gthread_id_network_status_check) {
+               pthread_join(gthread_id_network_status_check, NULL);
+               gthread_id_network_status_check = 0;
+       }
+
+       if (es_terminate_enrollee() != ES_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Terminate EasySetup Error");
+               return ESM_ERROR;
+       }
+
+       if (g_dev_conf_prov_data) {
+               things_free(g_dev_conf_prov_data);
+               g_dev_conf_prov_data = NULL;
+       }
+
+       if (g_wifi_prov_data) {
+               things_free(g_wifi_prov_data);
+               g_wifi_prov_data = NULL;
+       }
+
+       if (g_cloud_prov_data) {
+               things_free(g_cloud_prov_data);
+               g_cloud_prov_data = NULL;
+       }
+
+       g_server_builder = NULL;
+       esm_continue = 0;
+
+       return ESM_MODULE_TERMINATED;
+}
+
+static int checkRefresh(int *hour_cnt_24)
+{
+       OCStackResult ret = OC_STACK_ERROR;
+       int sleep_sec = 0;
+
+       if (*hour_cnt_24 >= CI_COMMON_REFRESH_TIME) {
+               if ((ret = refresh_token_into_cloud()) != OC_STACK_OK) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "refresh_token_into_cloud is failed in cloud_refresh_check_loop");
+               } else {
+                       *hour_cnt_24 = 0;
+               }
+       } else {
+               // Find Resource & if accesstoken is expireded then refresh process is called.
+               if ((ret = find_cloud_resource()) != OC_STACK_OK) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "find_cloud_resource is failed in cloud_refresh_check_loop");
+               }
+       }
+
+       if (ret != OC_STACK_OK) {
+               sleep_sec = i_fail_sleep_sec;
+       } else {
+               sleep_sec = i_common_sleep_sec;
+               (*hour_cnt_24)++;
+       }
+
+       return sleep_sec;
+}
+
+static void *cloud_refresh_check_loop(void *param)
+{
+#ifdef __ST_THINGS_RTOS__
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cloud_refresh_check_loop Close Loop Enter.");
+       int i_failed_cnt = 0;
+       int *i_continue = (int *)param;
+       int hour_cnt_24 = 0;
+       int ret = -1;
+       fd_set readFds;
+       struct timeval timeout;
+
+       timeout.tv_sec = i_common_sleep_sec;
+       timeout.tv_usec = 0;
+       int maxFd = ci_token_expire_fds[0];
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "device ID = %s", OCGetServerInstanceIDString());
+
+       // Close Loop Thread.
+       while (*i_continue) {
+               if (es_get_state() != ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD) {
+                       hour_cnt_24++;
+                       timeout.tv_sec = i_common_sleep_sec;
+                       FD_ZERO(&readFds);
+                       FD_SET(ci_token_expire_fds[0], &readFds);
+                       ret = select(maxFd + 1, &readFds, NULL, NULL, &timeout);
+                       if (ret == 0) {
+                               continue;
+                       }
+                       if (FD_ISSET(ci_token_expire_fds[0], &readFds)) {
+                               char buf[2] = { 0 };
+                               ssize_t len = read(ci_token_expire_fds[0], buf, sizeof(buf));
+                               if (len > 0 && buf[0] == 'w') {
+                                       break;
+                               }
+                               continue;
+                       }
+                       continue;
+               }
+               if ((timeout.tv_sec = checkRefresh(&hour_cnt_24)) == i_fail_sleep_sec) {
+                       i_failed_cnt++;
+               } else {
+                       i_failed_cnt = 0;
+               }
+
+               if (i_failed_cnt >= MAX_REFRESHCHECK_CNT) {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Refresh checking routin is Failed. Return cloud state to INIT.");
+                       i_failed_cnt = 0;
+                       esm_get_network_status();       // State return
+               }
+               FD_ZERO(&readFds);
+               FD_SET(ci_token_expire_fds[0], &readFds);
+               ret = select(maxFd + 1, &readFds, NULL, NULL, &timeout);
+               if (ret == 0) {
+                       continue;
+               }
+               if (FD_ISSET(ci_token_expire_fds[0], &readFds)) {
+                       char buf[2] = { 0 };
+                       ssize_t len = read(ci_token_expire_fds[0], buf, sizeof(buf));
+                       if (len > 0 && buf[0] == 'w') {
+                               break;
+                       }
+               }
+       }
+       FD_CLR(ci_token_expire_fds[0], &readFds);
+       FD_CLR(ci_token_expire_fds[1], &readFds);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cloud_refresh_check_loop Close Loop Exit.");
+       return NULL;
+#else
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cloud_refresh_check_loop Close Loop Enter.");
+
+       int i_failed_cnt = 0;
+       int sleep_sec = i_common_sleep_sec;
+       int *i_continue = (int *)param;
+       int hour_cnt_24 = 0;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "device ID = %s", OCGetServerInstanceIDString());
+
+       // Close Loop Thread.
+       while (*i_continue) {
+               if (es_get_state() != ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD) {
+                       hour_cnt_24++;
+                       sleep_sec = i_common_sleep_sec;
+                       sleep(sleep_sec);
+                       continue;
+               }
+
+               if ((sleep_sec = checkRefresh(&hour_cnt_24)) == i_fail_sleep_sec) {
+                       i_failed_cnt++;
+               } else {
+                       i_failed_cnt = 0;
+               }
+
+               if (i_failed_cnt >= MAX_REFRESHCHECK_CNT) {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Refresh checking routin is Failed. Return cloud state to INIT.");
+                       i_failed_cnt = 0;
+                       esm_get_network_status();       // State return
+               }
+
+               sleep(sleep_sec);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cloud_refresh_check_loop Close Loop Exit.");
+
+       return NULL;
+#endif
+}
+
+static int OICUpdateDevProvData(es_dev_conf_prov_data_s *dev_prov_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       if (dev_prov_data == NULL) {
+               return -1;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Country=%s, DateTime=%s, Language=%s", dev_prov_data->country, dev_prov_data->datetime, dev_prov_data->language);
+
+       if (g_update_dev_prov_data == NULL) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "st_things API is not registered.(gUpdateDateTime)");
+               return -1;
+       }
+
+       return g_update_dev_prov_data(dev_prov_data);
+}
+
+static void *wifi_prov_set_loop(void *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Open Loop Enter.");
+
+       static int timeout_handle_num = 100;
+       timeout_s timeout;
+
+       es_set_state(ES_STATE_CONNECTING_TO_ENROLLER);
+       set_wifi_prov_state(WIFI_READY);
+
+       while (get_wifi_prov_state() == WIFI_READY) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "waiting... WIFI_RESPONSE-Done for wifi provisioning.");
+               usleep(50000);
+       }
+
+       if (get_wifi_prov_state() != WIFI_RESPONSE) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "WiFi Response is failed.");
+               set_wifi_prov_state(WIFI_INIT);
+               things_free((access_point_info_s *) param);
+               return 0;
+       }
+       // Notify DevConfProvData to THINGS_App.
+       OICUpdateDevProvData(g_dev_conf_prov_data);
+
+       usleep(50000);
+
+       int res = things_set_ap_connection((access_point_info_s *) param);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Set AP Connection Result : %d", res);
+
+       if (res != 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Wifi Provisioning is Failed");
+               es_set_state(ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER);
+               things_free((access_point_info_s *) param);
+               set_wifi_prov_state(WIFI_INIT);
+               return 0;
+       }
+
+       things_wifi_state_changed_cb_init();
+       set_wifi_prov_state(WIFI_SET);
+       things_free((access_point_info_s *) param);
+
+       if (add_request_handle((OCDoHandle) timeout_handle_num) != NULL) {
+               timeout.cur_num = 300;  // 5 min    because, st_things-App wait AP-Connecting for 5 min.
+               timeout.cur_counter = timeout.cur_num;
+               create_time_out_process((OCDoHandle) timeout_handle_num++, wifi_prov_timeout_handler, &timeout);
+       }
+
+       gthread_id_network_status_check = 0;
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Open Loop Exit.");
+
+       return NULL;
+}
+
+static void *wifi_prov_timeout_handler(timeout_s *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "WiFi Setting of Provisioning data was Time-Out.");
+
+       es_set_state(ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER);
+       es_set_error_code(ES_ERRCODE_NO_INTERNETCONNECTION);
+
+       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "es_set_state ES_STATE_CONNECTED_FAIL_TO_ENROLLER");
+
+       if (ESM_OK != esm_init_easysetup(1, NULL)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Easy-Setup Module Initialization failed");
+               things_stop();
+               return NULL;
+       }
+
+       PROFILING_TIME("WiFi Provisioning End.");
+
+       set_wifi_prov_state(WIFI_INIT);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+
+       return NULL;
+}
+
+int esm_wifi_prov_check_cb(int enabled, char *ssid, char *addr)
+{
+       int ret = -1;
+
+       if (get_wifi_prov_state() != WIFI_SET) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "WiFi Provisioning State is Not WIFI_SET step.(%d)", get_wifi_prov_state());
+               return 0;
+       }
+
+       if (enabled != 1 || ssid == NULL || addr == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "enabled=%d, ssid=%s, addr=%s", enabled, ssid, addr);
+               return 0;
+       }
+
+       pthread_mutex_lock(&g_es_mutex);
+       if (strncmp(ssid, g_wifi_prov_data->ssid, strlen(g_wifi_prov_data->ssid)) == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CONNECTED TO TARGET AP  %s ", ssid);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "GET IP ADDR  : %s ", addr);
+               ret = 1;
+       } else {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "SSID is not Targeted One : (%s), (%s)", ssid, g_wifi_prov_data->ssid);
+               ret = 0;
+       }
+       pthread_mutex_unlock(&g_es_mutex);
+
+       if (ret == 1) {
+               es_set_state(ES_STATE_CONNECTED_TO_ENROLLER);
+               set_wifi_prov_state(WIFI_DONE);
+               THINGS_LOG(THINGS_DEBUG, TAG, "es_set_state ES_STATE_CONNECTED_TO_ENROLLER");
+
+               if (g_server_builder->broadcast_presence(g_server_builder, 20) == 1) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Broadcast Presence Failed.");
+                       ret = 0;
+               }
+
+               del_all_request_handle();       // clear time-out thread.
+               PROFILING_TIME("WiFi Provisioning End.");
+
+               set_wifi_prov_state(WIFI_INIT);
+       }
+
+       return ret;
+}
+
+void wifi_prov_cb_in_app(es_wifi_prov_data_s *event_data)
+{
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "Enter");
+       access_point_info_s *p_info = NULL;
+
+       if (event_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "es_wifi_prov_data_s Data Is NULL");
+               return;
+       }
+
+       if (things_is_net_initialize() != 1) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Network API Is not ready.");
+               return;
+       }
+
+       p_info = (access_point_info_s *) things_malloc(sizeof(access_point_info_s));
+       if (p_info == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "access_point_info_s memory allocation is failed.");
+               return;
+       }
+
+       pthread_mutex_lock(&g_es_mutex);
+       memcpy(g_wifi_prov_data, event_data, sizeof(es_wifi_prov_data_s));
+       pthread_mutex_unlock(&g_es_mutex);
+
+       // Attention : when 64bit linux Build, runtime-error occur. (memset () at ../sysdeps/x86_64/memset.S: Not Found File or Directory)
+       // It's because of p_info.(64 bit malloc internal code flow is not support that character array data-type of access_point_info_s)
+       // TODO : Fix Bug for 64bit support.
+       memset(p_info->e_ssid, 0, MAX_ESSID);
+       memset(p_info->security_key, 0, MAX_SECUIRTYKEY);
+       memset(p_info->enc_type, 0, MAX_TYPE_ENC);
+       memset(p_info->auth_type, 0, MAX_TYPE_AUTH);
+       memset(p_info->channel, 0, MAX_CHANNEL);
+       memset(p_info->bss_id, 0, MAX_BSSID);
+       memset(p_info->signal_level, 0, MAX_LEVEL_SIGNAL);
+
+       if (strlen(event_data->ssid) > 0) {
+               things_strncpy(p_info->e_ssid, event_data->ssid, strlen(event_data->ssid));
+       }
+
+       if (strlen(event_data->pwd) > 0) {
+               things_strncpy(p_info->security_key, event_data->pwd, strlen(event_data->pwd));
+       }
+
+       if (event_data->authtype >= NONE_AUTH && event_data->authtype <= WPA2_PSK) {
+               switch (event_data->authtype) {
+               case WEP:
+                       things_strncpy(p_info->auth_type, "WEP", strlen("WEP"));
+                       break;
+               case WPA_PSK:
+                       things_strncpy(p_info->auth_type, "WPA-PSK", strlen("WPA-PSK"));
+                       break;
+               case WPA2_PSK:
+                       things_strncpy(p_info->auth_type, "WPA2-PSK", strlen("WPA2-PSK"));
+                       break;
+               case NONE_AUTH:
+               default:
+                       things_strncpy(p_info->auth_type, "NONE", strlen("NONE"));
+                       break;
+               }
+       } else {
+               things_strncpy(p_info->auth_type, "NONE", strlen("NONE"));
+       }
+
+       if (event_data->enctype >= NONE_ENC && event_data->enctype <= TKIP_AES) {
+               switch (event_data->enctype) {
+               case WEP_64:
+                       things_strncpy(p_info->enc_type, "WEP_64", strlen("WEP_64"));
+                       break;
+               case WEP_128:
+                       things_strncpy(p_info->enc_type, "WEP_128", strlen("WEP_128"));
+                       break;
+               case TKIP:
+                       things_strncpy(p_info->enc_type, "TKIP", strlen("TKIP"));
+                       break;
+               case AES:
+                       things_strncpy(p_info->enc_type, "AES", strlen("AES"));
+                       break;
+               case TKIP_AES:
+                       things_strncpy(p_info->enc_type, "TKIP_AES", strlen("TKIP_AES"));
+                       break;
+               default:
+                       things_strncpy(p_info->enc_type, "NONE", strlen("NONE"));
+                       break;
+               }
+       } else {
+               things_strncpy(p_info->enc_type, "NONE", strlen("NONE"));
+       }
+
+       if (event_data->discovery_channel != -1) {
+               snprintf(p_info->channel, MAX_CHANNEL, "%d", event_data->discovery_channel);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "e_ssid : %s", p_info->e_ssid);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "security_key : %s", p_info->security_key);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "auth_type : %s", p_info->auth_type);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "enc_type : %s", p_info->enc_type);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "channel : %s", p_info->channel);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Copied ssid = %s", g_wifi_prov_data->ssid);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Copied pwd = %s", g_wifi_prov_data->pwd);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Copied enctype = %d", g_wifi_prov_data->enctype);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Copied discovery_channel = %d", g_wifi_prov_data->discovery_channel);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Copied authtype = %d", g_wifi_prov_data->authtype);
+
+       // Connect to AP
+       if (gthread_id_network_status_check == 0) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Create NetworkStatusCheck thread");
+               del_all_request_handle();       // clear time-out thread.
+               set_wifi_prov_state(WIFI_INIT);
+
+#ifdef __ST_THINGS_RTOS__
+               pthread_create_rtos(&gthread_id_network_status_check, NULL, wifi_prov_set_loop, (void *)p_info, THINGS_STACK_CLOUD_REFRESH_THREAD);
+#else
+               things_thread_create(&gthread_id_network_status_check, NULL, wifi_prov_set_loop, (void *)p_info);
+#endif
+               set_wifi_prov_state(WIFI_READY);
+       } else {
+               things_free(p_info);
+       }
+
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "Exit");
+}
+
+void dev_conf_prov_cb_in_app(es_dev_conf_prov_data_s *event_data)
+{
+       if (event_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "es_dev_conf_prov_data_s Is NULL");
+               return;
+       }
+
+       pthread_mutex_lock(&g_es_mutex);
+       memcpy(g_dev_conf_prov_data, event_data, sizeof(es_dev_conf_prov_data_s));
+       pthread_mutex_unlock(&g_es_mutex);
+
+       if (strlen(event_data->language) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Language : %s", event_data->language);
+       }
+
+       if (strlen(event_data->country) > 0) {
+               // check payload
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Country : %s", event_data->country);
+       }
+
+       if (strlen(event_data->datetime) > 0) {
+               // check payload
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Datetime : %s", event_data->datetime);
+       }
+}
+
+void cloud_data_prov_cb_in_app(es_cloud_prov_data_s *event_data)
+{
+       if (event_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "es_cloud_prov_data_s Data Is NULL");
+               return;
+       }
+
+       pthread_mutex_lock(&g_es_mutex);
+       memcpy(g_cloud_prov_data, event_data, sizeof(es_cloud_prov_data_s));
+       pthread_mutex_unlock(&g_es_mutex);
+
+       if (strlen(event_data->auth_code) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "AuthCode : %s", g_cloud_prov_data->auth_code);
+       }
+
+       if (strlen(event_data->accesstoken) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Accesstoken : %s", g_cloud_prov_data->accesstoken);
+       }
+
+       if (strlen(event_data->refreshtoken) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Refreshtoken : %s", g_cloud_prov_data->refreshtoken);
+       }
+
+       if (strlen(event_data->uid) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Uid : %s", g_cloud_prov_data->uid);
+       }
+
+       if (strlen(event_data->auth_provider) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "AuthProvider : %s", g_cloud_prov_data->auth_provider);
+       }
+
+       if (strlen(event_data->host_name) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CIHostName : %s", g_cloud_prov_data->host_name);
+       }
+
+       if (strlen(event_data->ip) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CIip : %s", g_cloud_prov_data->ip);
+       }
+
+       if (strlen(event_data->port) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CIPort : %s", g_cloud_prov_data->port);
+       }
+
+       if (strlen(event_data->ci_server) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CIServer : %s", g_cloud_prov_data->ci_server);
+       }
+
+       if (strlen(event_data->server_id) > 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Server ID : %s", g_cloud_prov_data->server_id);
+       }
+
+       g_cloud_data_cb_to_app(g_cloud_prov_data);
+       // CB to things_stack.c
+       // Need to check the running state of the thread...
+}
+
+bool esm_get_network_status(void)
+{
+       //THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       bool is_ok = false;
+
+       if (things_is_net_initialize() != 1) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Network API is not initialized.");
+               return false;
+       }
+
+       if (things_is_connected_ap() == true) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Connected to AP");
+               es_set_state(ES_STATE_CONNECTED_TO_ENROLLER);
+
+               if (g_server_builder != NULL && g_server_builder->broadcast_presence != NULL) {
+                       if (g_server_builder->broadcast_presence(g_server_builder, 20) == 1) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Broadcast Presence Failed.");
+                               return is_ok;
+                       }
+               } else {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "ServerBuilder is not initialized.");
+               }
+
+               is_ok = true;
+       } else {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Disconnected to AP");
+               es_set_state(ES_STATE_INIT);
+       }
+
+       //THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+       return is_ok;
+}
+
+void *esm_register_cloud_cb(void *func)
+{
+       g_cloud_data_cb_to_app = func;
+       return NULL;
+}
+
+esm_result_e esm_set_wifi_conn_rrr(void)
+{
+       es_set_state(ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER);
+       es_set_error_code(ES_ERRCODE_UNKNOWN);
+       return ESM_OK;
+}
+
+int esm_register_pin_generated_cb(pin_generated_func_type func)
+{
+       if (func) {
+               g_pin_generated_cb = func;
+               // SetGeneratePinCB(generate_pin_cb);
+               return 1;
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Invalid PINGeneratedCB function");
+               return 0;
+       }
+}
+
+int esm_register_pin_close_cb(pin_close_func_type func)
+{
+       if (func) {
+               g_pin_close_cb = func;
+               // SetGeneratePinCB(generate_pin_cb);
+               return 1;
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Invalid PINGeneratedCB function");
+               return 0;
+       }
+}
+
+int esm_register_user_confirm_cb(user_confirm_result_func_type func)
+{
+       if (func) {
+               g_user_confirm_cb = func;
+
+               // SetUserConfirmCB(NULL, get_user_confirmation);
+               return 1;
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Invalid UserConformCB function");
+               return 0;
+       }
+}
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/inc/easysetup.h b/framework/src/st_things/things_stack/src/common/easy-setup/inc/easysetup.h
new file mode 100644 (file)
index 0000000..4696ab5
--- /dev/null
@@ -0,0 +1,50 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef EASYSETUP_ENROLLEE_H__
+#define EASYSETUP_ENROLLEE_H__
+
+#include "es_common.h"
+
+typedef void (*es_enrollee_event_callback)(es_result_e es_result, things_es_enrollee_state_e enrolleeState);
+
+typedef struct {
+       void (*wifi_prov_cb)(es_wifi_prov_data_s *);
+       void (*dev_conf_prov_cb)(es_dev_conf_prov_data_s *);
+       void (*cloud_data_prov_cb)(es_cloud_prov_data_s *);
+} es_provisioning_callbacks_s;
+
+es_result_e es_init_enrollee(bool is_secured, es_resource_mask_e resource_mask, es_provisioning_callbacks_s callbacks);
+
+void es_register_notify_easysetup_state(void *func);
+
+things_es_enrollee_state_e es_get_state(void);
+
+bool es_get_cloud_login_state(void);
+
+es_result_e es_set_device_property(es_device_property *device_property);
+
+es_result_e es_set_state(things_es_enrollee_state_e es_state);
+
+es_result_e es_set_error_code(es_error_code_e es_err_code);
+
+es_result_e es_set_cloud_error_code(ci_error_code_e es_err_code);
+
+es_result_e es_terminate_enrollee();
+
+#endif                                                 /* EASYSETUP_ENROLLEE_H__ */
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/inc/easysetup_manager.h b/framework/src/st_things/things_stack/src/common/easy-setup/inc/easysetup_manager.h
new file mode 100644 (file)
index 0000000..2ae7919
--- /dev/null
@@ -0,0 +1,65 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+
+#ifndef _EASYSETUP_MANAGER_H_
+#define _EASYSETUP_MANAGER_H_
+
+#include "things_api.h"
+#include "es_common.h"
+#include "things_server_builder.h"
+
+typedef enum {
+       ESM_OK = 0,
+       ESM_ERROR,
+       ESM_PARAM_INVAIND,
+       ESM_MODULE_STARTED,
+       ESM_MODULE_TERMINATED,
+       ESM_REQ_DENIED
+} esm_result_e;
+
+typedef void (*pin_generated_func_type)(char *pin_data, size_t pin_size);
+
+typedef int (*pin_close_func_type)(void);
+
+typedef int (*user_confirm_result_func_type)(void);
+
+int esm_set_device_property_by_app(char *name, const wifi_mode_e *mode, int ea_mode, const wifi_freq_e freq);
+
+esm_result_e esm_init_easysetup(int restart_flag, things_server_builder_s *server_builder);
+
+esm_result_e esm_terminate_easysetup(void);
+
+esm_result_e esm_set_wifi_conn_rrr(void);
+
+bool esm_get_network_status(void);
+
+void *esm_register_cloud_cb(void *);
+
+void esm_register_update_dev_prov_data_func(things_update_dev_prov_data_func_type func);
+
+int esm_register_pin_generated_cb(pin_generated_func_type func);
+
+int esm_register_pin_close_cb(pin_close_func_type func);
+
+int esm_register_user_confirm_cb(user_confirm_result_func_type func);
+
+int esm_wifi_prov_check_cb(int enabled, char *ssid, char *addr);
+
+#endif                                                 // _EASYSETUP_MANAGER_H_
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/inc/es_common.h b/framework/src/st_things/things_stack/src/common/easy-setup/inc/es_common.h
new file mode 100644 (file)
index 0000000..242a100
--- /dev/null
@@ -0,0 +1,302 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef ES_COMMON_H_
+#define ES_COMMON_H_
+
+#include "ocstack.h"
+#include "octypes.h"
+#include "things_types.h"
+
+#define THINGS_STRING_MAX_HOSTNAME 256
+#define THINGS_STRING_MAX_VALUE    100
+#define IP_PORT                 22
+
+/**
+ * Attributes used to form a proper easysetup conforming JSON message.
+ */
+#define OC_RSRVD_ES_PROVSTATUS             "ps"
+#define OC_RSRVD_ES_LAST_ERRORCODE         "lec"
+#define OC_RSRVD_ES_LINKS                  "links"
+#define OC_RSRVD_ES_SUPPORTEDWIFIMODE      "swmt"
+#define OC_RSRVD_ES_SUPPORTEDWIFIFREQ      "swf"
+#define OC_RSRVD_ES_SSID                   "tnn"
+#define OC_RSRVD_ES_CRED                   "cd"
+#define OC_RSRVD_ES_AUTHTYPE               "wat"
+#define OC_RSRVD_ES_ENCTYPE                "wet"
+#define OC_RSRVD_ES_AUTHCODE               "ac"
+#define OC_RSRVD_ES_AUTHPROVIDER           "apn"
+#define OC_RSRVD_ES_CISERVER               "cis"
+#define OC_RSRVD_ES_SERVERID               "sid"
+#define OC_RSRVD_ES_CLIENTID               "clientid"
+#define OC_RSRVD_ES_DEVNAME                "dn"
+#define OC_RSRVD_ES_LANGUAGE               "lang"
+#define OC_RSRVD_ES_COUNTRY                "ctry"
+#define OC_RSRVD_ES_VENDOR_DEVTYPE         "x.com.samsung.dt"
+#define OC_RSRVD_ES_VENDOR_DEVSUBTYPE      "x.com.samsung.sdt"
+#define OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL "x.com.samsung.chn"
+#define OC_RSRVD_ES_VENDOR_CLIENTID         "x.com.samsung.clientid"
+#define OC_RSRVD_ES_VENDOR_ERRORCODE        "x.com.samsung.vd.errcode"
+#define OC_RSRVD_ES_VENDOR_ACCESS_TOKEN     "at"
+#define OC_RSRVD_ES_VENDOR_ACCESS_TOKEN_TYPE "att"
+#define SC_RSRVD_ES_VENDOR_REFRESH_TOKEN    "x.com.samsung.refreshtoken"
+#define OC_RSRVD_ES_VENDOR_USER_ID          "x.com.samsung.uid"
+#define OC_RSRVD_ES_VENDOR_UTC_DATE_TIME    "x.com.samsung.datetime"
+
+/**
+ * Easysetup defined resoruce types and uris.
+ */
+#define OC_RSRVD_ES_RES_TYPE_PROV         "oic.r.easysetup"    //"oic.wk.prov"
+#define OC_RSRVD_ES_URI_PROV              "/EasySetupResURI"   //"/ProvisioningResURI"
+#define OC_RSRVD_ES_RES_TYPE_WIFI         "oic.r.wificonf"     //"oic.wk.wifi"
+#define OC_RSRVD_ES_URI_WIFI              "/WiFiConfResURI"    //"/WiFiProvisioningResURI"
+#define OC_RSRVD_ES_RES_TYPE_CLOUDSERVER  "oic.r.coapcloudconf"        //"oic.wk.cloudserver"
+#define OC_RSRVD_ES_URI_CLOUDSERVER       "/CoapCloudConfResURI"       //"/CloudServerProvisioningResURI"
+#define OC_RSRVD_ES_RES_TYPE_DEVCONF      "oic.r.devconf"      //"oic.wk.devconf"
+#define OC_RSRVD_ES_URI_DEVCONF           "/DevConfResURI"     //"/DevConfProvisioningResURI"
+
+#define NUM_WIFIMODE    10
+
+#define MAX_DEVICELEN   100
+
+typedef enum {
+       ES_ERROR = -1,
+       ES_OK = 0,
+       ES_NETWORKFOUND = 1,
+       ES_NETWORKCONNECTED,
+       ES_NETWORKNOTCONNECTED,
+       ES_RESOURCECREATED = 11,
+       ES_RECVREQOFPROVRES = 21,
+       ES_RECVREQOFNETRES,
+       ES_RECVUPDATEOFPROVRES,
+       ES_RECVTRIGGEROFPROVRES,
+       ES_UNAUTHORIZED = 31
+} es_result_e;
+
+typedef enum {
+       ES_WIFI_RESOURCE = 0x01,
+       ES_CLOUD_RESOURCE = 0x02,
+       ES_DEVCONF_RESOURCE = 0x04
+} es_resource_mask_e;
+
+typedef struct {
+       struct {
+               wifi_mode_e mode[NUM_WIFIMODE];
+               wifi_freq_e freq;
+       } WiFi;
+       struct {
+               char device_name[MAX_DEVICELEN];
+               char device_type[THINGS_STRING_MAX_VALUE];
+               char device_sub_type[THINGS_STRING_MAX_VALUE];
+       } dev_conf_s;
+} es_device_property;
+
+/**
+ * @brief Indicate last error code to describe a reason of error during easy setup.
+ */
+typedef enum {
+       /**
+        * Initialize 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 occurred about wifi provisioning.
+        */
+       ES_ERRCODE_TIMEOUT,
+
+       /**
+        * Error Code that cloud server is not reachable due to wrong URL of cloud server, for example.
+        */
+       ES_ERRCODE_FAILED_TO_ACCESS_CLOUD_SERVER,
+
+       /**
+        * Error Code that no response is arrived from cloud server
+        */
+       ES_ERRCODE_NO_RESPONSE_FROM_CLOUD_SERVER,
+
+       /**
+        * Error Code that a delivered authcode is not valid.
+        */
+       ES_ERRCODE_INVALID_AUTHCODE,
+
+       /**
+        * Error Code that a given access token is not valid due to its expiration, for example.
+        */
+       ES_ERRCODE_INVALID_ACCESSTOKEN,
+
+       /**
+        * Error Code that a refresh of expired access token is failed due to some reasons.
+        */
+       ES_ERRCODE_FAILED_TO_REFRESH_ACCESSTOKEN,
+
+       /**
+        * Error Code that a target device is not discovered in cloud server
+        */
+       ES_ERRCODE_FAILED_TO_FIND_REGISTERED_DEVICE_IN_CLOUD,
+
+       /**
+        * Error Code that a target user does not exist in cloud server.
+        */
+       ES_ERRCODE_FAILED_TO_FIND_REGISTERED_USER_IN_CLOUD,
+
+       /**
+        * Cloud Provisioning Error
+        */
+       ER_ERRCODE_INVALID_PROV_PAYLOAD = 100,
+
+       /**
+        * Cloud Data invalid in provisioning.json file.
+        */
+       ER_ERRCODE_INVALID_SAVED_CLOUD_DATA = 101,
+
+       /**
+        * Device System Error.
+        */
+       ER_ERRCODE_SYSTEM_ERROR = 102,  // System Error of device.
+
+       /**
+        * Error Code that Unknown error occurred
+        */
+       ES_ERRCODE_UNKNOWN = 255
+} es_error_code_e;
+
+/*
+ * * Used HTTP Status Code
+ *      200 : OK
+ *      201 : Created
+ *      400 : Bad Request
+ *      401 : Unauthorized
+ *      403 : Forbidden
+ *      404 : Not Found
+ *      500 : Internal Server Error
+ *
+ *
+ * * Serial Number
+ *      00xx : Common
+ *      01xx : User
+ *      02xx : Device
+ *      03xx : RD (ResourceDirectory)
+ *      04xx : RD Link
+ *      05xx : Group
+ *      06xx : ACL
+ *      07xx : CI (Cloud Interface)
+ *      08xx : Push
+ *
+ * * Sub-Serial Number
+ *      xx00 : Not Found.
+ *      xx01 : Duplicated.
+ *      xx02 : Invalid Param.
+ *
+ *  * Result Code is made by
+ *      HTTP Status Code(xxx) + Serial Number(xxxx)
+ */
+
+typedef enum {
+       // No error
+       ERRCI_NO_ERROR = 0,
+
+       /**
+        * Cloud Error Code
+        */
+       // No error
+       ERRCI_SUCCESS = 2000000,
+
+       //COMMON
+       ERRCI_SAMSUNG_ACCOUNT_AUTHORIZATION_FAILED = 4010001,   // Invalid authcode value.
+       ERRCI_TOKEN_VALIDATION_FAILED = 4000002,
+       ERRCI_FORBIDDEN = 4030003,
+       ERRCI_TOKEN_EXPIRED = 4000004,
+       ERRCI_AUTHORIZATION_FAILED = 4000005,
+       ERRCI_UNSUPPORTED_REQ = 4000901,
+       ERRCI_NOT_ACCEPTABLE = 4060001,
+
+       //USER
+       ERRCI_USER_DUPLICATE_PARAM = 4000101,
+       ERRCI_USER_INVALID_PARAM = 4000102,
+       ERRCI_USER_NOT_FOUND = 4040100,
+       ERRCI_UNAUTHORIZED_TOKEN = 4010200,
+       ERRCI_SAMSUNG_ACCOUNT_UNAUTHORIZED_TOKEN = 4010201,     // Already registered device for other user.
+
+       //DEVICE
+       ERRCI_DEVICE_DUPLICATE_PARAM = 4000201,
+       ERRCI_DEVICE_INVALID_PARAM = 4000202,
+       ERRCI_DEVICE_NOT_CONNECTED = 4010900,
+       ERRCI_DEVICE_NOT_FOUND = 4040200,
+
+       //RD
+       ERRCI_RD_DUPLICATE_PARAM = 4000301,
+       ERRCI_RD_INVALID_PARAM = 4000302,
+       ERRCI_RD_NOT_FOUND = 4040300,
+
+       //RD LINK
+       ERRCI_RDLINK_DUPLICATE_PARAM = 4000401,
+       ERRCI_RDLINK_INVALID_PARAM = 4000402,
+       ERRCI_RDLINK_NOT_FOUND = 4040400,
+
+       //GROUP
+       ERRCI_GROUP_DUPLICATE_PARAM = 4000501,
+       ERRCI_GROUP_INVALID_PARAM = 4000502,
+       ERRCI_GROUP_NOT_FOUND = 4040500,
+
+       //ACL
+       ERRCI_ACL_DUPLICATE_PARAM = 4000601,
+       ERRCI_ACL_INVALID_PARAM = 4000602,
+       ERRCI_ACL_NOT_FOUND = 4040600,
+
+       //CI
+       ERRCI_CI_DUPLICATE_PARAM = 4000701,
+       ERRCI_CI_INVALID_PARAM = 4000702,
+       ERRCI_CI_NOT_FOUND = 4040700,
+
+       //PUSH
+       ERRCI_PUSH_DUPLICATE_PARAM = 4000801,
+       ERRCI_PUSH_INVALID_PARAM = 4000802,
+       ERRCI_PUSH_NOT_FOUND = 4040800,
+
+       //COMMON
+       ERRCI_INTERNAL_SERVER_ERROR = 5000000,
+       ERRCI_DB_CONNECTION_FAIL = 5000002,
+
+       /**
+       * Error Code that Unknown error occurred
+       */
+       ERRCI_UNKNOWN = 6000000
+} ci_error_code_e;
+
+#endif                                                 //ES_COMMON_H_
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/inc/resource_handler.h b/framework/src/st_things/things_stack/src/common/easy-setup/inc/resource_handler.h
new file mode 100644 (file)
index 0000000..e197fcc
--- /dev/null
@@ -0,0 +1,110 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 <string.h>
+#include "ocstack.h"
+#include "es_common.h"
+#include "octypes.h"
+
+#ifndef ES_RESOURCE_HANDLER_H_
+#define ES_RESOURCE_HANDLER_H_
+
+typedef enum {
+       WIFI_INIT = 0,
+       WIFI_READY = 1,
+       WIFI_RESPONSE = 2,
+       WIFI_SET = 3,
+       WIFI_DONE
+} wifi_prov_state_e;
+
+typedef void (*es_wifi_cb)(es_result_e, es_wifi_prov_data_s *);
+typedef void (*es_cloud_cb)(es_result_e, es_cloud_prov_data_s *);
+typedef void (*es_dev_conf_cb)(es_result_e, es_dev_conf_prov_data_s *);
+
+/* Structure to represent a Light resource */
+typedef struct prov_resource_s {
+       OCResourceHandle handle;
+       things_prov_status_e status;            // provisiong status
+       es_error_code_e last_err_code;
+       ci_error_code_e vd_err_code;
+} prov_resource_s;
+
+typedef struct {
+       OCResourceHandle handle;
+       wifi_mode_e supported_mode[NUM_WIFIMODE];
+       uint8_t num_mode;                       // the number of device's supported wifi modes
+       wifi_freq_e supported_freq;
+       char ssid[MAX_SSIDLEN];         // target network name, i.e. SSID for WLAN, MAC address for BT.
+       char cred[MAX_CREDLEN];         // credential information.
+       wifi_auth_type_e auth_type;
+       wifi_enc_type_e enc_type;
+       int discovery_channel;
+} wifi_resource_s;
+
+typedef struct {
+       OCResourceHandle handle;
+       char auth_code[THINGS_STRING_MAX_VALUE];
+       char auth_provider[THINGS_STRING_MAX_VALUE];
+       char ci_server[THINGS_STRING_MAX_VALUE];
+       char server_id[THINGS_STRING_MAX_VALUE];
+       char client_id[THINGS_STRING_MAX_VALUE];
+       char accesstoken[THINGS_STRING_MAX_VALUE];
+       int actoken_type;
+       char refreshtoken[THINGS_STRING_MAX_VALUE];
+       char uid[THINGS_STRING_MAX_VALUE];
+} cloud_resource_s;
+
+typedef struct {
+       OCResourceHandle handle;
+       char devName[MAX_DEVICELEN];
+       char language[THINGS_STRING_MAX_VALUE];
+       char country[THINGS_STRING_MAX_VALUE];
+       char device_type[THINGS_STRING_MAX_VALUE];
+       char device_sub_type[THINGS_STRING_MAX_VALUE];
+       char datetime[THINGS_STRING_MAX_VALUE];
+} dev_conf_resource_s;
+
+void set_ssid_in_wifi_resource(const char *ssid);
+void init_es_cloud_prov_data(es_cloud_prov_data_s *p_cloud_data);
+void clone_es_cloud_prov_data(es_cloud_prov_data_s *des, es_cloud_prov_data_s *src);
+void set_wifi_prov_state(wifi_prov_state_e value);
+wifi_prov_state_e get_wifi_prov_state(void);
+
+OCStackResult create_easysetup_resources(bool is_secured, es_resource_mask_e resource_mask);
+OCStackResult delete_easysetup_resources();
+OCStackResult prov_rsc_notify_all_observers(void);
+
+things_es_enrollee_state_e get_enrollee_state(void);
+
+OCStackResult set_device_property(es_device_property *device_property);
+OCStackResult set_enrollee_state(things_es_enrollee_state_e es_state);
+OCStackResult set_enrollee_err_code(es_error_code_e es_err_code);
+
+void get_target_network_info_from_prov_resource(char *, char *);
+void register_wifi_rsrc_event_callback(es_wifi_cb);
+void register_cloud_rsrc_event_callback(es_cloud_cb);
+void register_dev_conf_rsrc_event_callback(es_dev_conf_cb);
+void unregister_resource_event_callback(void);
+
+const char *get_result(OCStackResult result);
+const char *get_prov_status(things_es_enrollee_state_e status);
+const char *get_prov_errcode(es_error_code_e last_errcode);
+
+bool start_cloud_provisioning(void *CIinfo);
+
+#endif                                                 //ES_RESOURCE_HANDLER_H_
diff --git a/framework/src/st_things/things_stack/src/common/easy-setup/resource_handler.c b/framework/src/st_things/things_stack/src/common/easy-setup/resource_handler.c
new file mode 100644 (file)
index 0000000..dc82065
--- /dev/null
@@ -0,0 +1,1981 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 "resource_handler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#ifdef __ST_THINGS_RTOS__
+#include <net/lwip/ipv4/inet.h>
+#else
+#include <arpa/inet.h>
+#endif
+#include "things_api.h"
+#include "octypes.h"
+#include "ocpayload.h"
+#include "oic_string.h"
+#include "things_logger.h"
+#include "cloud_manager.h"
+#include "things_string_util.h"
+#include "things_malloc.h"
+#include "cautilinterface.h"
+#include "things_common.h"
+
+#include "../utils/inc/things_network.h"
+#include <time.h>
+
+#define ES_RH_TAG "[ezsetup-RH]"
+
+static prov_resource_s g_prov_resource;
+static wifi_resource_s g_wifi_resource;
+static cloud_resource_s g_cloud_resource;
+static dev_conf_resource_s g_dev_conf_resource;
+
+/**
+ * @var g_wifi_data
+ * @brief Structure for holding the target information required to
+ * connect to the target network
+ */
+static es_wifi_prov_data_s g_wifi_data;
+
+/**
+ * @var g_dev_conf_data
+ * @brief Structure for holding the device information
+ */
+static es_dev_conf_prov_data_s g_dev_conf_data;
+
+/**
+ * @var g_cloud_data
+ * @brief Structure for holding the cloud information required to
+ * connect to CI Server
+ */
+static es_cloud_prov_data_s g_cloud_data;
+
+static wifi_prov_state_e es_wifi_prov_state = WIFI_INIT;
+
+static pthread_mutex_t g_status_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+//-----------------------------------------------------------------------------
+// Private internal function prototypes
+//-----------------------------------------------------------------------------
+OCEntityHandlerResult things_entity_handler_cb(OCEntityHandlerFlag flag, OCEntityHandlerRequest *eh_request, void *callback);
+OCEntityHandlerResult process_get_request(OCEntityHandlerRequest *eh_request, OCRepPayload **payload);
+OCEntityHandlerResult process_put_request(OCEntityHandlerRequest *eh_request, OCRepPayload **payload);
+OCEntityHandlerResult process_post_request(OCEntityHandlerRequest *eh_request, OCRepPayload **payload);
+void update_prov_resource(OCEntityHandlerRequest *eh_request, OCRepPayload *input);
+void update_wifi_resource(OCRepPayload *input);
+bool update_cloud_resource(OCRepPayload *input);
+void update_dev_conf_resource(OCRepPayload *input);
+static int check_ci_server_ipv4(char *ci_server, es_cloud_prov_data_s *cloud_data);
+
+es_wifi_cb g_wifi_rsrc_evt_cb = NULL;
+es_cloud_cb g_cloud_rsrc_evt_cb = NULL;
+es_dev_conf_cb g_dev_conf_rsrc_evt_cb = NULL;
+
+static inline void delete_child_payload(OCRepPayload *payload)
+{
+       if (payload == NULL) {
+               return;
+       }
+
+       delete_child_payload(payload->next);
+       OCPayloadDestroy((OCPayload *) payload);
+}
+
+static bool compare_resource_interface(const char *from, const char *iface)
+{
+       bool ret = false;
+       char *str = NULL;
+       char *ptr = NULL;
+
+       if (from == NULL || iface == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "invalid input data.(from=%s, iface=%s)", from, iface);
+               return ret;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Input data.(from=%s, iface=%s)", from, iface);
+
+       if ((str = OICStrdup(from)) == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "OICStrdup function is failed.");
+               return ret;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "strFrom=%s", str);
+
+       ptr = str;
+       while ((ptr = strtok(ptr, ";")) != NULL) {
+               if (strstr(ptr, ".if.")) {
+                       char *if_ptr = NULL;
+                       if_ptr = strtok(ptr, "=");
+                       if_ptr = strtok(NULL, "=");
+
+                       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "if_ptr=%s", if_ptr);
+
+                       if (if_ptr != NULL && !strncmp(if_ptr, iface, strlen(iface))) {
+                               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Found interface.(%s)", iface);
+                               ret = true;
+                               break;
+                       }
+               }
+
+               ptr = NULL;
+       }
+
+       free(str);
+       return ret;
+}
+
+static OCRepPayload *make_rep_payload(OCResourceHandle rsc_handle, OCDevAddr *dev_addr)
+{
+       OCRepPayload *add = NULL;
+       char *resource_type[1] = { NULL, };
+       char *resource_interface[1] = { NULL, };
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+
+       if (rsc_handle == NULL || dev_addr == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "Invalid input data.(rsc_handle=0x%X, dev_addr=0x%X)", rsc_handle, dev_addr);
+               return NULL;
+       }
+
+       if ((add = OCRepPayloadCreate()) == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               return NULL;
+       }
+
+       add->base.type = PAYLOAD_TYPE_REPRESENTATION;
+
+       if (rsc_handle == g_wifi_resource.handle) {
+               resource_type[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFI);
+               resource_interface[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_WIFI);
+       } else if (rsc_handle == g_dev_conf_resource.handle) {
+               resource_type[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_DEVCONF);
+               resource_interface[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_DEVCONF);
+       } else if (rsc_handle == g_cloud_resource.handle) {
+               resource_type[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+               resource_interface[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_CLOUDSERVER);
+       } else {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "Not supported resource handler(rsc_handle=0x%X)", rsc_handle);
+               OCPayloadDestroy((OCPayload *) add);
+               return NULL;
+       }
+
+       OCRepPayloadSetStringArray(add, OC_RSRVD_RESOURCE_TYPE, (const char **)resource_type, dimensions);
+       OCRepPayloadSetStringArray(add, OC_RSRVD_INTERFACE, (const char **)resource_interface, dimensions);
+       /*! Added by st_things for Memory leak fix */
+       if (resource_type[0]) {
+               free(resource_type[0]);
+       }
+       if (resource_interface[0]) {
+               free(resource_interface[0]);
+       }
+
+       OCResourceProperty p = OCGetResourceProperties(rsc_handle);
+       OCRepPayload *policy = OCRepPayloadCreate();
+       if (!policy) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               OCPayloadDestroy((OCPayload *) add);
+               return NULL;
+       }
+
+       OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE)));
+       if (p & OC_SECURE) {
+               OCRepPayloadSetPropBool(policy, OC_RSRVD_SECURE, p & OC_SECURE);
+               uint16_t securePort = CAGetAssignedPortNumber(dev_addr->adapter, dev_addr->flags);
+               OCRepPayloadSetPropInt(policy, OC_RSRVD_HOSTING_PORT, securePort);
+       }
+
+       OCRepPayloadSetPropObject(add, OC_RSRVD_POLICY, policy);
+       OCPayloadDestroy((OCPayload *) policy);
+
+       return add;
+}
+
+void set_wifi_prov_state(wifi_prov_state_e value)
+{
+       if (es_wifi_prov_state == (value - 1) || value == WIFI_INIT) {
+               es_wifi_prov_state = value;
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Set wifi_prov_state_e=%d", es_wifi_prov_state);
+       }
+}
+
+wifi_prov_state_e get_wifi_prov_state(void)
+{
+       return es_wifi_prov_state;
+}
+
+void register_wifi_rsrc_event_callback(es_wifi_cb cb)
+{
+       g_wifi_rsrc_evt_cb = cb;
+}
+
+void register_cloud_rsrc_event_callback(es_cloud_cb cb)
+{
+       g_cloud_rsrc_evt_cb = cb;
+}
+
+void register_dev_conf_rsrc_event_callback(es_dev_conf_cb cb)
+{
+       g_dev_conf_rsrc_evt_cb = cb;
+}
+
+void unregister_resource_event_callback()
+{
+       if (g_wifi_rsrc_evt_cb) {
+               g_wifi_rsrc_evt_cb = NULL;
+       }
+       if (g_cloud_rsrc_evt_cb) {
+               g_cloud_rsrc_evt_cb = NULL;
+       }
+       if (g_dev_conf_rsrc_evt_cb) {
+               g_dev_conf_rsrc_evt_cb = NULL;
+       }
+}
+
+void get_target_network_info_from_prov_resource(char *name, char *pass)
+{
+       if (name != NULL && pass != NULL) {
+               things_strncpy(name, g_wifi_resource.ssid, MAX_SSIDLEN);
+               things_strncpy(pass, g_wifi_resource.cred, MAX_CREDLEN);
+       }
+}
+
+OCStackResult initProvResource(bool is_secured)
+{
+       es_set_state(ES_STATE_INIT);
+       g_prov_resource.last_err_code = ES_ERRCODE_NO_ERROR;
+       g_prov_resource.vd_err_code = ERRCI_NO_ERROR;
+
+       OCStackResult res = OC_STACK_ERROR;
+       if (is_secured) {
+               res = OCCreateResource(&g_prov_resource.handle, OC_RSRVD_ES_RES_TYPE_PROV, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_PROV, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+       } else {
+               res = OCCreateResource(&g_prov_resource.handle, OC_RSRVD_ES_RES_TYPE_PROV, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_PROV, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+       }
+       if (res) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created Prov resource with result: %s", get_result(res));
+               return res;
+       }
+
+       res = OCBindResourceTypeToResource(g_prov_resource.handle, OC_RSRVD_RESOURCE_TYPE_COLLECTION);
+       if (res) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Binding Resource type with result: %s", get_result(res));
+               return res;
+       }
+
+       res = OCBindResourceInterfaceToResource(g_prov_resource.handle, OC_RSRVD_INTERFACE_LL);
+       if (res) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created Prov resource with result: %s", get_result(res));
+               return res;
+       }
+       res = OCBindResourceInterfaceToResource(g_prov_resource.handle, OC_RSRVD_INTERFACE_BATCH);
+       if (res) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created Prov resource with result: %s", get_result(res));
+               return res;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created Prov resource with result: %s", get_result(res));
+       return res;
+}
+
+OCStackResult initWiFiResource(bool is_secured)
+{
+       OCStackResult res = OC_STACK_ERROR;
+
+       g_wifi_resource.supported_freq = WiFi_BOTH;
+       g_wifi_resource.supported_mode[0] = WiFi_11A;
+       g_wifi_resource.supported_mode[1] = WiFi_11B;
+       g_wifi_resource.supported_mode[2] = WiFi_11G;
+       g_wifi_resource.supported_mode[3] = WiFi_11N;
+       g_wifi_resource.supported_mode[4] = WiFi_11AC;
+       g_wifi_resource.num_mode = 5;
+       g_wifi_resource.auth_type = NONE_AUTH;
+       g_wifi_resource.enc_type = NONE_ENC;
+       memset(g_wifi_resource.ssid, 0, sizeof(char) *MAX_SSIDLEN);
+       memset(g_wifi_resource.cred, 0, sizeof(char) *MAX_CREDLEN);
+       g_wifi_resource.discovery_channel = 1;
+
+       if (is_secured) {
+               res = OCCreateResource(&g_wifi_resource.handle, OC_RSRVD_ES_RES_TYPE_WIFI, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_WIFI, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+       } else {
+               res = OCCreateResource(&g_wifi_resource.handle, OC_RSRVD_ES_RES_TYPE_WIFI, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_WIFI, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+       }
+
+       things_apply_current_ap();
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created WiFi resource with result: %s", get_result(res));
+       return res;
+
+}
+
+static void initCloudResourceData(cloud_resource_s *p_cloud_resource)
+{
+       if (p_cloud_resource == NULL) {
+               return;
+       }
+
+       memset(p_cloud_resource->auth_code, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_resource->auth_provider, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_resource->ci_server, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_resource->server_id, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_resource->client_id, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_resource->accesstoken, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       p_cloud_resource->actoken_type = 0;
+       memset(p_cloud_resource->refreshtoken, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_resource->uid, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+
+}
+
+void init_es_cloud_prov_data(es_cloud_prov_data_s *p_cloud_data)
+{
+       if (p_cloud_data == NULL) {
+               return;
+       }
+
+       memset(p_cloud_data->auth_code, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->auth_provider, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->ci_server, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->host_name, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->ip, 0, sizeof(char) *IP_PORT);
+       memset(p_cloud_data->port, 0, sizeof(char) *IP_PORT);
+       memset(p_cloud_data->server_id, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->client_id, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->accesstoken, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       p_cloud_data->actoken_type = 0;
+       memset(p_cloud_data->refreshtoken, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(p_cloud_data->uid, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+}
+
+void clone_es_cloud_prov_data(es_cloud_prov_data_s *des, es_cloud_prov_data_s *src)
+{
+       if (des == NULL || src == NULL) {
+               return;
+       }
+
+       memcpy(des->auth_code, src->auth_code, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->auth_provider, src->auth_provider, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->ci_server, src->ci_server, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->host_name, src->host_name, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->ip, src->ip, sizeof(char) *IP_PORT);
+       memcpy(des->port, src->port, sizeof(char) *IP_PORT);
+       memcpy(des->server_id, src->server_id, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->client_id, src->client_id, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->accesstoken, src->accesstoken, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       des->actoken_type = src->actoken_type;
+       memcpy(des->refreshtoken, src->refreshtoken, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memcpy(des->uid, src->uid, sizeof(char) *THINGS_STRING_MAX_VALUE);
+}
+
+static void initESWiFiProvData(es_wifi_prov_data_s *p_wifi_data)
+{
+       if (p_wifi_data == NULL) {
+               return;
+       }
+
+       memset(p_wifi_data->ssid, 0, sizeof(char) *MAX_SSIDLEN);
+       memset(p_wifi_data->pwd, 0, sizeof(char) *MAX_CREDLEN);
+       p_wifi_data->authtype = -1;
+       p_wifi_data->enctype = -1;
+       p_wifi_data->discovery_channel = -1;
+}
+
+void set_ssid_in_wifi_resource(const char *ssid)
+{
+       if (ssid == NULL) {
+               memset(g_wifi_resource.ssid, 0, sizeof(char) *MAX_SSIDLEN);
+               memset(g_wifi_resource.cred, 0, sizeof(char) *MAX_CREDLEN);
+               g_wifi_resource.auth_type = NONE_AUTH;
+               g_wifi_resource.enc_type = NONE_ENC;
+               g_wifi_resource.discovery_channel = 0;
+       } else if (strncmp(ssid, g_wifi_data.ssid, strlen(g_wifi_data.ssid)) == 0) {
+               things_strncpy(g_wifi_resource.ssid, g_wifi_data.ssid, sizeof(char) *MAX_SSIDLEN);
+               things_strncpy(g_wifi_resource.cred, g_wifi_data.pwd, sizeof(char) *MAX_CREDLEN);
+               g_wifi_resource.auth_type = g_wifi_data.authtype;
+               g_wifi_resource.enc_type = g_wifi_data.enctype;
+               g_wifi_resource.discovery_channel = g_wifi_data.discovery_channel;
+       } else {
+               things_strncpy(g_wifi_resource.ssid, ssid, sizeof(char) *MAX_SSIDLEN);
+               memset(g_wifi_resource.cred, 0, sizeof(char) *MAX_CREDLEN);
+               g_wifi_resource.auth_type = NONE_AUTH;
+               g_wifi_resource.enc_type = NONE_ENC;
+               g_wifi_resource.discovery_channel = 1;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Connected SSID=%s", ssid);
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_data.ssid=%s", g_wifi_data.ssid);
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_resource.ssid=%s", g_wifi_resource.ssid);
+}
+
+OCStackResult initCloudServerResource(bool is_secured)
+{
+       OCStackResult res = OC_STACK_ERROR;
+
+       initCloudResourceData(&g_cloud_resource);
+
+       if (is_secured) {
+               res = OCCreateResource(&g_cloud_resource.handle, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_CLOUDSERVER, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+       } else {
+               res = OCCreateResource(&g_cloud_resource.handle, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_CLOUDSERVER, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created CloudServer resource with result: %s", get_result(res));
+       return res;
+
+}
+
+OCStackResult initDevConfResource(bool is_secured)
+{
+       OCStackResult res = OC_STACK_ERROR;
+
+       memset(g_dev_conf_resource.devName, 0, sizeof(char) *MAX_DEVICELEN);
+       memset(g_dev_conf_resource.country, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(g_dev_conf_resource.language, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(g_dev_conf_resource.device_type, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(g_dev_conf_resource.device_sub_type, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+       memset(g_dev_conf_resource.datetime, 0, sizeof(char) *THINGS_STRING_MAX_VALUE);
+
+       if (is_secured) {
+               res = OCCreateResource(&g_dev_conf_resource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_DEVCONF, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+       } else {
+               res = OCCreateResource(&g_dev_conf_resource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF, OC_RSRVD_INTERFACE_DEFAULT, OC_RSRVD_ES_URI_DEVCONF, things_entity_handler_cb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created dev_conf_s resource with result: %s", get_result(res));
+       return res;
+
+}
+
+void update_prov_resource(OCEntityHandlerRequest *eh_request, OCRepPayload *input)
+{
+       THINGS_LOG_V(THINGS_INFO, ES_RH_TAG, "g_prov_resource.status %d", get_enrollee_state());
+
+       if (eh_request->query) {
+               if (strstr(eh_request->query, OC_RSRVD_INTERFACE_BATCH)) {
+                       // When Provisioning resource has a POST with BatchInterface
+                       update_cloud_resource(input);
+                       update_wifi_resource(input);
+                       update_dev_conf_resource(input);
+               }
+       }
+}
+
+void update_wifi_resource(OCRepPayload *input)
+{
+       initESWiFiProvData(&g_wifi_data);
+
+       char *ssid = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_SSID, &ssid) == false || ssid == NULL) {
+               return;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Current AP SSID: %s", g_wifi_resource.ssid);
+       if (strncmp(ssid, g_wifi_resource.ssid, strlen(g_wifi_resource.ssid)) == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Already connected SSID(%s).", ssid);
+               free(ssid);
+               return;
+       }
+
+       things_strncpy(g_wifi_data.ssid, ssid, sizeof(g_wifi_data.ssid));
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_data.ssid : %s", g_wifi_data.ssid);
+
+       char *cred = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CRED, &cred)) {
+               things_strncpy(g_wifi_data.pwd, cred, sizeof(g_wifi_data.pwd));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_data.pwd %s", g_wifi_data.pwd);
+       }
+
+       int64_t auth_type = -1;
+       if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_AUTHTYPE, &auth_type)) {
+               g_wifi_data.authtype = auth_type;
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_data.authtype %u", g_wifi_data.authtype);
+       }
+
+       int64_t enc_type = -1;
+       if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_ENCTYPE, &enc_type)) {
+               g_wifi_data.enctype = enc_type;
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_data.enctype %u", g_wifi_data.enctype);
+       }
+
+       int64_t channel = -1;
+       if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL, &channel)) {
+               g_wifi_data.discovery_channel = channel;
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_wifi_data.discovery_channel %u", g_wifi_data.discovery_channel);
+       }
+
+       if (ssid || cred || auth_type != -1 || enc_type != -1) {
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Send WiFiRsrc Callback To ES");
+               PROFILING_TIME("WiFi Provisioning Start.");
+
+               // TODO : Need to check appropriateness of g_wifi_data
+               if (g_wifi_rsrc_evt_cb != NULL) {
+                       g_wifi_rsrc_evt_cb(ES_OK, &g_wifi_data);
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "g_wifi_rsrc_evt_cb is NULL");
+               }
+       }
+
+       /*! Added by st_things for memory Leak fix
+        */
+       if (ssid) {
+               free(ssid);
+       }
+       if (cred) {
+               free(cred);
+       }
+}
+
+bool update_cloud_resource(OCRepPayload *input)
+{
+       bool res = false;
+       initCloudResourceData(&g_cloud_resource);
+       init_es_cloud_prov_data(&g_cloud_data);
+
+       char *auth_code = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHCODE, &auth_code)) {
+               things_strncpy(g_cloud_resource.auth_code, auth_code, sizeof(g_cloud_resource.auth_code));
+               things_strncpy(g_cloud_data.auth_code, auth_code, sizeof(g_cloud_data.auth_code));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.auth_code %s", g_cloud_resource.auth_code);
+       }
+
+       char *accesstoken = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_VENDOR_ACCESS_TOKEN, &accesstoken)) {
+               things_strncpy(g_cloud_resource.accesstoken, accesstoken, sizeof(g_cloud_resource.accesstoken));
+               things_strncpy(g_cloud_data.accesstoken, accesstoken, sizeof(g_cloud_data.accesstoken));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.accesstoken %s", g_cloud_resource.accesstoken);
+       }
+
+       int accesstokenType = NULL;
+       if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_VENDOR_ACCESS_TOKEN_TYPE, &accesstokenType)) {
+               g_cloud_resource.actoken_type = accesstokenType;
+               g_cloud_data.actoken_type = accesstokenType;
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.actoken_type %d", g_cloud_resource.actoken_type);
+       }
+
+       char *refreshtoken = NULL;
+       if (OCRepPayloadGetPropString(input, SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, &refreshtoken)) {
+               things_strncpy(g_cloud_resource.refreshtoken, refreshtoken, sizeof(g_cloud_resource.refreshtoken));
+               things_strncpy(g_cloud_data.refreshtoken, refreshtoken, sizeof(g_cloud_data.refreshtoken));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.refreshtoken %s", g_cloud_resource.refreshtoken);
+       }
+
+       char *uid = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_VENDOR_USER_ID, &uid)) {
+               things_strncpy(g_cloud_resource.uid, uid, sizeof(g_cloud_resource.uid));
+               things_strncpy(g_cloud_data.uid, uid, sizeof(g_cloud_data.uid));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.uid %s", g_cloud_resource.uid);
+       }
+
+       char *auth_provider = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHPROVIDER, &auth_provider)) {
+               things_strncpy(g_cloud_resource.auth_provider, auth_provider, sizeof(g_cloud_resource.auth_provider));
+               things_strncpy(g_cloud_data.auth_provider, auth_provider, sizeof(g_cloud_data.auth_provider));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.auth_provider %s", g_cloud_resource.auth_provider);
+       }
+
+       char *ci_server = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CISERVER, &ci_server)) {
+               if (check_ci_server_ipv4(ci_server, &g_cloud_data) == 1) {
+                       things_strncpy(g_cloud_resource.ci_server, ci_server, sizeof(g_cloud_resource.ci_server));
+                       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.ci_server %s", g_cloud_resource.ci_server);
+               } else {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "check_ci_server_ipv4 is failed.");
+                       g_prov_resource.last_err_code = ER_ERRCODE_INVALID_PROV_PAYLOAD;
+                       g_prov_resource.vd_err_code = ERRCI_NO_ERROR;
+               }
+       }
+
+       char *server_id = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_SERVERID, &server_id)) {
+               things_strncpy(g_cloud_resource.server_id, server_id, sizeof(g_cloud_resource.server_id));
+               things_strncpy(g_cloud_data.server_id, server_id, sizeof(g_cloud_data.server_id));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.server_id %s", g_cloud_resource.server_id);
+       }
+
+       char *client_id = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_VENDOR_CLIENTID, &client_id)) {
+               things_strncpy(g_cloud_resource.client_id, client_id, sizeof(g_cloud_resource.client_id));
+               things_strncpy(g_cloud_data.client_id, client_id, sizeof(g_cloud_data.client_id));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_cloud_resource.client_id %s", g_cloud_resource.client_id);
+       }
+
+       if ((g_cloud_data.auth_code[0] || (g_cloud_data.accesstoken[0] && g_cloud_data.refreshtoken[0])) && g_cloud_data.auth_provider[0] && g_cloud_data.ci_server[0]) {
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Send CloudRsrc Callback To ES");
+               PROFILING_TIME("Cloud Provisioning Start.");
+
+               if (g_cloud_rsrc_evt_cb != NULL) {
+                       es_set_state(ES_STATE_INIT);
+                       g_prov_resource.last_err_code = ERRCI_NO_ERROR;
+                       g_prov_resource.vd_err_code = ERRCI_NO_ERROR;
+
+                       g_cloud_rsrc_evt_cb(ES_OK, &g_cloud_data);
+                       res = true;
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "g_cloud_rsrc_evt_cb is NULL");
+                       g_prov_resource.last_err_code = ER_ERRCODE_SYSTEM_ERROR;
+                       g_prov_resource.vd_err_code = ERRCI_NO_ERROR;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Cloud Provisioning Data is invalid: auth_code=%s auth_provider=%s ci_server=%s", g_cloud_data.auth_code, g_cloud_data.auth_provider, g_cloud_data.ci_server);
+       }
+
+       if (auth_code) {
+               things_free(auth_code);
+       }
+
+       if (accesstoken) {
+               things_free(accesstoken);
+       }
+
+       /*! Added by st_things for leak fix */
+       if (refreshtoken) {
+               things_free(refreshtoken);
+       }
+       if (uid) {
+               things_free(uid);
+       }
+
+       if (auth_provider) {
+               things_free(auth_provider);
+       }
+
+       if (ci_server) {
+               things_free(ci_server);
+       }
+
+       if (server_id) {
+               things_free(server_id);
+       }
+
+       if (client_id) {
+               things_free(client_id);
+       }
+
+       return res;
+}
+
+void update_dev_conf_resource(OCRepPayload *input)
+{
+       char *country = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_COUNTRY, &country)) {
+               things_strncpy(g_dev_conf_resource.country, country, sizeof(g_dev_conf_resource.country));
+               things_strncpy(g_dev_conf_data.country, country, sizeof(g_dev_conf_data.country));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_dev_conf_resource.country %s", g_dev_conf_resource.country);
+       }
+
+       char *language = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_LANGUAGE, &language)) {
+               things_strncpy(g_dev_conf_resource.language, language, sizeof(g_dev_conf_resource.language));
+               things_strncpy(g_dev_conf_data.language, language, sizeof(g_dev_conf_data.language));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_dev_conf_resource.language %s", g_dev_conf_resource.language);
+       }
+
+       char *datetime = NULL;
+       if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_VENDOR_UTC_DATE_TIME, &datetime)) {
+               things_strncpy(g_dev_conf_resource.datetime, datetime, sizeof(g_dev_conf_resource.datetime));
+               things_strncpy(g_dev_conf_data.datetime, datetime, sizeof(g_dev_conf_data.datetime));
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "g_dev_conf_resource.datetime %s", g_dev_conf_resource.datetime);
+
+               //Added by THINGS to set time in appliance yyyy-mm-ddThh-mm-ss
+               char chYear[5], chMonth[3], chDay[3], chHour[3], chMin[3], chSec[3];
+               struct tm stTime;
+               memset(&stTime, 0, sizeof(stTime));
+
+               int itr = 0;
+               for (; itr < 4; itr++) {
+                       chYear[itr] = g_dev_conf_resource.datetime[itr];
+               }
+               chYear[itr] = '\0';
+               stTime.tm_year = (atoi(chYear) - 1900);
+
+               chMonth[0] = g_dev_conf_resource.datetime[++itr];
+               chMonth[1] = g_dev_conf_resource.datetime[++itr];
+               chMonth[2] = '\0';
+               stTime.tm_mon = (atoi(chMonth) - 1);
+
+               itr++;
+               chDay[0] = g_dev_conf_resource.datetime[++itr];
+               chDay[1] = g_dev_conf_resource.datetime[++itr];
+               chDay[2] = '\0';
+               stTime.tm_mday = atoi(chDay);
+
+               itr++;
+               chHour[0] = g_dev_conf_resource.datetime[++itr];
+               chHour[1] = g_dev_conf_resource.datetime[++itr];
+               chHour[2] = '\0';
+               stTime.tm_hour = atoi(chHour);
+
+               itr++;
+               chMin[0] = g_dev_conf_resource.datetime[++itr];
+               chMin[1] = g_dev_conf_resource.datetime[++itr];
+               chMin[2] = '\0';
+               stTime.tm_min = atoi(chMin);
+
+               itr++;
+               chSec[0] = g_dev_conf_resource.datetime[++itr];
+               chSec[1] = g_dev_conf_resource.datetime[++itr];
+               chSec[2] = '\0';
+               stTime.tm_sec = atoi(chSec);
+
+               unsigned int epTime = (unsigned int)mktime(&stTime);
+
+               struct timespec current_time;
+
+               current_time.tv_sec = epTime;
+               current_time.tv_nsec = 0;
+
+               if (clock_settime(CLOCK_REALTIME, &current_time) != 0) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to clock_settime");
+               }
+       }
+
+       if (country || language || datetime) {
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Send DevConfRsrc Callback To ES");
+
+               // TODO : Need to check appropriateness of g_dev_conf_data
+               if (g_dev_conf_rsrc_evt_cb != NULL) {
+                       g_dev_conf_rsrc_evt_cb(ES_OK, &g_dev_conf_data);
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "g_dev_conf_rsrc_evt_cb is NULL");
+               }
+       }
+
+       /*! Added by st_things for memory Leak fix
+        */
+       if (country) {
+               free(country);
+       }
+       if (language) {
+               free(language);
+       }
+       if (datetime) {
+               free(datetime);
+       }
+}
+
+OCRepPayload *construct_response_of_wifi(const char *interface)
+{
+       OCRepPayload *payload = OCRepPayloadCreate();
+       if (!payload) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               return NULL;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "constructResponse wifi res");
+       OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_WIFI);
+
+       OCRepPayload *rep_payload = NULL;
+       OCRepPayload *tempPayload = NULL;
+       if (interface != NULL && !strncmp(interface, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {     // Temporary Code.
+               char *interfaces[1] = { NULL, };
+               char *resource_types[1] = { NULL, };
+               size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+               size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+
+               rep_payload = OCRepPayloadCreate();
+               if (!rep_payload) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate rep_payload");
+                       goto GOTO_ERROR;
+               }
+               // Swap
+               tempPayload = payload;
+               payload = rep_payload;
+
+               interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE, (const char **)interfaces, interfacesDimensions);
+
+               resource_types[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFI);
+               OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE, (const char **)resource_types, resourceTypesDimensions);
+               /*! Added by st_things for memory Leak fix
+                */
+               if (interfaces[0]) {
+                       free(interfaces[0]);
+               }
+               if (resource_types[0]) {
+                       free(resource_types[0]);
+               }
+       } else {
+               OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_WIFI);
+       }
+
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { g_wifi_resource.num_mode, 0, 0 };
+       int64_t *modes_64 = (int64_t *)malloc(g_wifi_resource.num_mode * sizeof(int64_t));
+       for (int i = 0; i < g_wifi_resource.num_mode; ++i) {
+               modes_64[i] = g_wifi_resource.supported_mode[i];
+       }
+
+       OCRepPayloadSetIntArray(payload, OC_RSRVD_ES_SUPPORTEDWIFIMODE, (int64_t *) modes_64, dimensions);
+       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_SUPPORTEDWIFIFREQ, g_wifi_resource.supported_freq);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_SSID, g_wifi_resource.ssid);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CRED, g_wifi_resource.cred);
+       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_AUTHTYPE, (int)g_wifi_resource.auth_type);
+       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_ENCTYPE, (int)g_wifi_resource.enc_type);
+       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL, (int)g_wifi_resource.discovery_channel);
+
+       if (interface != NULL && !strncmp(interface, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {
+               payload = tempPayload;
+               OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, rep_payload);
+               OCPayloadDestroy((OCPayload *) rep_payload);
+               rep_payload = NULL;
+               tempPayload = NULL;
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (tempPayload != NULL) {
+               OCPayloadDestroy((OCPayload *) tempPayload);
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (modes_64 != NULL) {
+               free(modes_64);
+       }
+
+       return payload;
+
+GOTO_ERROR:
+       if (payload != NULL) {
+               OCPayloadDestroy((OCPayload *) payload);
+               payload = NULL;
+       }
+
+       return NULL;
+}
+
+OCRepPayload *construct_response_of_cloud(const char *interface)
+{
+       OCRepPayload *payload = OCRepPayloadCreate();
+       if (!payload) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               return NULL;
+       }
+
+       THINGS_LOG(THINGS_INFO, ES_RH_TAG, "constructResponse cloud res");
+       OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_CLOUDSERVER);
+
+       OCRepPayload *rep_payload = NULL;
+       OCRepPayload *tempPayload = NULL;
+       if (interface != NULL && !strncmp(interface, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {     // Temporary Code.
+               char *interfaces[1] = { NULL, };
+               char *resource_types[1] = { NULL, };
+               size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+               size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+
+               rep_payload = OCRepPayloadCreate();
+               if (!rep_payload) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate rep_payload");
+                       goto GOTO_ERROR;
+               }
+               // Swap
+               tempPayload = payload;
+               payload = rep_payload;
+
+               interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE, (const char **)interfaces, interfacesDimensions);
+
+               resource_types[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+               OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE, (const char **)resource_types, resourceTypesDimensions);
+               /*! Added by st_things for memory Leak fix
+                */
+               if (interfaces[0]) {
+                       free(interfaces[0]);
+               }
+               if (resource_types[0]) {
+                       free(resource_types[0]);
+               }
+       } else {
+               OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+       }
+
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHCODE, g_cloud_resource.auth_code);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHPROVIDER, g_cloud_resource.auth_provider);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CISERVER, g_cloud_resource.ci_server);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_SERVERID, g_cloud_resource.server_id);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_CLIENTID, g_cloud_resource.client_id);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_ACCESS_TOKEN, g_cloud_resource.accesstoken);
+       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_VENDOR_ACCESS_TOKEN_TYPE, g_cloud_resource.actoken_type);
+       OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, g_cloud_resource.refreshtoken);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_USER_ID, g_cloud_resource.uid);
+
+       if (interface != NULL && !strncmp(interface, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {
+               payload = tempPayload;
+               OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, rep_payload);
+               OCPayloadDestroy((OCPayload *) rep_payload);
+               rep_payload = NULL;
+               tempPayload = NULL;
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (tempPayload != NULL) {
+               OCPayloadDestroy((OCPayload *) tempPayload);
+       }
+
+       return payload;
+
+GOTO_ERROR:
+       if (payload != NULL) {
+               OCPayloadDestroy((OCPayload *) payload);
+               payload = NULL;
+       }
+
+       return NULL;
+}
+
+OCRepPayload *construct_response_of_dev_conf(const char *interface)
+{
+       OCRepPayload *payload = OCRepPayloadCreate();
+       if (!payload) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               return NULL;
+       }
+
+       THINGS_LOG(THINGS_INFO, ES_RH_TAG, "constructResponse devConf res");
+       OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_DEVCONF);
+
+       OCRepPayload *rep_payload = NULL;
+       OCRepPayload *tempPayload = NULL;
+       if (interface != NULL && !strncmp(interface, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {     // Temporary Code.
+               char *interfaces[1] = { NULL, };
+               char *resource_types[1] = { NULL, };
+               size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+               size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
+
+               rep_payload = OCRepPayloadCreate();
+               if (!rep_payload) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate rep_payload");
+                       goto GOTO_ERROR;
+               }
+               // Swap
+               tempPayload = payload;
+               payload = rep_payload;
+
+               interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE, (const char **)interfaces, interfacesDimensions);
+
+               resource_types[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_DEVCONF);
+               OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE, (const char **)resource_types, resourceTypesDimensions);
+               /*! Added by st_things for memory Leak fix
+                */
+               if (interfaces[0]) {
+                       free(interfaces[0]);
+               }
+               if (resource_types[0]) {
+                       free(resource_types[0]);
+               }
+       } else {
+               OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
+               OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_DEVCONF);
+       }
+
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_DEVNAME, g_dev_conf_resource.devName);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_LANGUAGE, g_dev_conf_resource.language);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_COUNTRY, g_dev_conf_resource.country);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_DEVTYPE, g_dev_conf_resource.device_type);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_DEVSUBTYPE, g_dev_conf_resource.device_sub_type);
+       OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_UTC_DATE_TIME, g_dev_conf_resource.datetime);
+
+       if (interface != NULL && !strncmp(interface, OC_RSRVD_INTERFACE_BATCH, strlen(OC_RSRVD_INTERFACE_BATCH))) {
+               payload = tempPayload;
+               OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, rep_payload);
+               OCPayloadDestroy((OCPayload *) rep_payload);
+               rep_payload = NULL;
+               tempPayload = NULL;
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (tempPayload != NULL) {
+               OCPayloadDestroy((OCPayload *) tempPayload);
+       }
+
+       return payload;
+
+GOTO_ERROR:
+       if (payload != NULL) {
+               OCPayloadDestroy((OCPayload *) payload);
+               payload = NULL;
+       }
+
+       return NULL;
+}
+
+OCRepPayload *construct_response_of_prov(OCEntityHandlerRequest *eh_request)
+{
+       int childResCnt = 0;
+       const OCRepPayload *arrayPayload[3] = { NULL, };
+       OCRepPayload *payload = NULL;
+
+       if (g_wifi_resource.handle == NULL || g_dev_conf_resource.handle == NULL || g_cloud_resource.handle == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "mandatory Resource handle is NULL.(WiFi=0x%X, dev_conf_s=0x%X, Cloud=0x%X)", g_wifi_resource.handle, g_dev_conf_resource.handle, g_cloud_resource.handle);
+               return NULL;
+       }
+
+       if ((payload = OCRepPayloadCreate()) == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               return NULL;
+       }
+       // Requested interface is Link list interface
+       if (!eh_request->query || (eh_request->query && !strncmp(eh_request->query, "", strlen(""))) || (eh_request->query && compare_resource_interface(eh_request->query, OC_RSRVD_INTERFACE_LL)) || (eh_request->query && compare_resource_interface(eh_request->query, OC_RSRVD_INTERFACE_DEFAULT))) {
+               if ((arrayPayload[childResCnt] = make_rep_payload(g_wifi_resource.handle, &eh_request->devAddr)) == NULL) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "It's failed making payload of wifi_resource_s-Representation");
+                       goto GOTO_FAILED;
+               }
+               childResCnt++;
+
+               if ((arrayPayload[childResCnt] = make_rep_payload(g_dev_conf_resource.handle, &eh_request->devAddr)) == NULL) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "It's failed making payload of dev_conf_resource_s-Representation");
+                       goto GOTO_FAILED;
+               }
+               childResCnt++;
+
+               if ((arrayPayload[childResCnt] = make_rep_payload(g_cloud_resource.handle, &eh_request->devAddr)) == NULL) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "It's failed making payload of cloud_resource_s-Representation");
+                       goto GOTO_FAILED;
+               }
+               childResCnt++;
+
+               size_t dimensions[MAX_REP_ARRAY_DEPTH] = { childResCnt, 0, 0 };
+
+               if (!eh_request->query || !strncmp(eh_request->query, "", strlen("")) || compare_resource_interface(eh_request->query, OC_RSRVD_INTERFACE_LL) == false) {
+                       THINGS_LOG(THINGS_INFO, ES_RH_TAG, "constructResponse prov res");
+                       OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
+                       OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
+                       OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_LL);
+                       OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_BATCH);
+                       OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_PROV);
+                       OCRepPayloadAddResourceType(payload, OC_RSRVD_RESOURCE_TYPE_COLLECTION);
+
+                       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PROVSTATUS, get_enrollee_state());
+                       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_LAST_ERRORCODE, g_prov_resource.last_err_code);
+                       OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_VENDOR_ERRORCODE, g_prov_resource.vd_err_code);
+               }
+
+               OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ES_LINKS, arrayPayload, dimensions);
+
+               for (int i = 0; i < childResCnt; i++) {
+                       OCPayloadDestroy((OCPayload *) arrayPayload[i]);
+               }
+
+       } else if (eh_request->query && compare_resource_interface(eh_request->query, OC_RSRVD_INTERFACE_BATCH)) {
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "constructResponse prov res");
+               OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
+
+               OCRepPayload *rep_payload = NULL;
+               char *interfaces[3] = { NULL, };
+               char *resource_types[2] = { NULL, };
+               size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0 };
+               size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = { 2, 0, 0 };
+
+               rep_payload = OCRepPayloadCreate();
+               if (!rep_payload) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate rep_payload");
+                       goto GOTO_FAILED;
+               }
+
+               interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
+               interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_LL);
+               interfaces[2] = OICStrdup(OC_RSRVD_INTERFACE_BATCH);
+               OCRepPayloadSetStringArray(rep_payload, OC_RSRVD_INTERFACE, (const char **)interfaces, interfacesDimensions);
+
+               resource_types[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_PROV);
+               resource_types[1] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_COLLECTION);
+               OCRepPayloadSetStringArray(rep_payload, OC_RSRVD_RESOURCE_TYPE, (const char **)resource_types, resourceTypesDimensions);
+
+               OCRepPayloadSetPropInt(rep_payload, OC_RSRVD_ES_PROVSTATUS, get_enrollee_state());
+               OCRepPayloadSetPropInt(rep_payload, OC_RSRVD_ES_LAST_ERRORCODE, g_prov_resource.last_err_code);
+               OCRepPayloadSetPropInt(rep_payload, OC_RSRVD_ES_VENDOR_ERRORCODE, g_prov_resource.vd_err_code);
+
+               OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, rep_payload);
+               OCPayloadDestroy((OCPayload *) rep_payload);
+               /*! Added by st_things for memory Leak fix
+                */
+               if (interfaces[0]) {
+                       free(interfaces[0]);
+               }
+               if (interfaces[1]) {
+                       free(interfaces[1]);
+               }
+               if (interfaces[2]) {
+                       free(interfaces[2]);
+               }
+               if (resource_types[0]) {
+                       free(resource_types[0]);
+               }
+               if (resource_types[1]) {
+                       free(resource_types[1]);
+               }
+       }
+
+       if (eh_request->query) {
+               if (compare_resource_interface(eh_request->query, OC_RSRVD_INTERFACE_BATCH)) {  // When Provisioning resource has a GET with BatchInterface
+                       OCRepPayload *head = payload;
+
+                       payload->next = construct_response_of_wifi(OC_RSRVD_INTERFACE_BATCH);
+                       if (payload->next == NULL) {
+                               goto GOTO_FAILED;
+                       }
+
+                       payload = payload->next;
+                       payload->next = construct_response_of_cloud(OC_RSRVD_INTERFACE_BATCH);
+                       if (payload->next == NULL) {
+                               payload = head;
+                               goto GOTO_FAILED;
+                       }
+
+                       payload = payload->next;
+                       payload->next = construct_response_of_dev_conf(OC_RSRVD_INTERFACE_BATCH);
+                       if (payload->next == NULL) {
+                               payload = head;
+                               goto GOTO_FAILED;
+                       }
+
+                       payload = head;
+               }
+       }
+
+       return payload;
+
+GOTO_FAILED:
+       for (int i = 0; i < childResCnt; i++) {
+               OCPayloadDestroy((OCPayload *) arrayPayload[i]);
+       }
+
+       delete_child_payload(payload);
+
+       return NULL;
+}
+
+OCStackResult create_easysetup_resources(bool is_secured, es_resource_mask_e resource_mask)
+{
+       OCStackResult res = OC_STACK_ERROR;
+       bool maskFlag = false;
+
+       res = initProvResource(is_secured);
+       if (res != OC_STACK_OK) {
+               // TODO: destroy logic will be added
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "initProvResource result: %s", get_result(res));
+
+               return res;
+       }
+
+       if ((resource_mask & ES_WIFI_RESOURCE) == ES_WIFI_RESOURCE) {
+               maskFlag = true;
+               res = initWiFiResource(is_secured);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "initWiFiResource result: %s", get_result(res));
+                       return res;
+               }
+
+               res = OCBindResource(g_prov_resource.handle, g_wifi_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "bind wifi_resource_s result: %s", get_result(res));
+                       return res;
+               }
+
+       }
+
+       if ((resource_mask & ES_CLOUD_RESOURCE) == ES_CLOUD_RESOURCE) {
+               maskFlag = true;
+               res = initCloudServerResource(is_secured);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "initCloudResource result: %s", get_result(res));
+                       return res;
+               }
+
+               res = OCBindResource(g_prov_resource.handle, g_cloud_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "bind cloud_resource_s result: %s", get_result(res));
+                       return res;
+               }
+       }
+
+       if ((resource_mask & ES_DEVCONF_RESOURCE) == ES_DEVCONF_RESOURCE) {
+               maskFlag = true;
+               res = initDevConfResource(is_secured);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "initDevConf result: %s", get_result(res));
+                       return res;
+               }
+
+               res = OCBindResource(g_prov_resource.handle, g_dev_conf_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "bind dev_conf_resource_s result: %s", get_result(res));
+                       return res;
+               }
+       }
+
+       if (maskFlag == false) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Invalid ResourceMask");
+               return OC_STACK_ERROR;
+
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Created all resources with result: %s", get_result(res));
+
+       return res;
+}
+
+OCStackResult delete_provisioning_resource()
+{
+       OCStackResult res = OCDeleteResource(g_prov_resource.handle);
+       if (res != OC_STACK_OK) {
+               THINGS_LOG_V(THINGS_INFO, ES_RH_TAG, "Deleting Prov resource error with result: %s", get_result(res));
+       }
+
+       return res;
+}
+
+OCStackResult delete_easysetup_resources()
+{
+       OCStackResult res = OC_STACK_ERROR;
+       if (g_wifi_resource.handle != NULL) {
+               res = OCUnBindResource(g_prov_resource.handle, g_wifi_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Unbind wifi_resource_s error with result: %s", get_result(res));
+               }
+       }
+       if (g_cloud_resource.handle != NULL) {
+               res = OCUnBindResource(g_prov_resource.handle, g_cloud_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Unbind cloud_resource_s error with result: %s", get_result(res));
+               }
+       }
+       if (g_dev_conf_resource.handle != NULL) {
+               res = OCUnBindResource(g_prov_resource.handle, g_dev_conf_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Unbind dev_conf_resource_s error with result: %s", get_result(res));
+               }
+       }
+
+       if (g_wifi_resource.handle != NULL) {
+               res = OCDeleteResource(g_wifi_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Deleting WiFi resource error with result: %s", get_result(res));
+               }
+       }
+
+       if (g_cloud_resource.handle != NULL) {
+               res = OCDeleteResource(g_cloud_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Deleting CloudServer resource error with result: %s", get_result(res));
+               }
+       }
+
+       if (g_dev_conf_resource.handle != NULL) {
+               res = OCDeleteResource(g_dev_conf_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Deleting dev_conf_s resource error with result: %s", get_result(res));
+               }
+       }
+
+       if (g_prov_resource.handle != NULL) {
+               res = OCDeleteResource(g_prov_resource.handle);
+               if (res != OC_STACK_OK) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Deleting Prov resource error with result: %s", get_result(res));
+               }
+       }
+
+       return res;
+}
+
+OCEntityHandlerResult process_get_request(OCEntityHandlerRequest *eh_request, OCRepPayload **payload)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+       if (!eh_request) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Request is Null");
+               return eh_result;
+       }
+       if (eh_request->payload && eh_request->payload->type != PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Incoming payload not a representation");
+               return eh_result;
+       }
+
+       OCRepPayload *getResp = NULL;
+
+       if (eh_request->resource == g_prov_resource.handle) {
+               getResp = construct_response_of_prov(eh_request);
+       } else if (eh_request->resource == g_wifi_resource.handle) {
+               getResp = construct_response_of_wifi(OC_RSRVD_INTERFACE_DEFAULT);
+       } else if (eh_request->resource == g_cloud_resource.handle) {
+               getResp = construct_response_of_cloud(OC_RSRVD_INTERFACE_DEFAULT);
+       } else if (eh_request->resource == g_dev_conf_resource.handle) {
+               getResp = construct_response_of_dev_conf(OC_RSRVD_INTERFACE_DEFAULT);
+       }
+
+       if (!getResp) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "constructResponse failed");
+               return OC_EH_ERROR;
+       }
+
+       *payload = getResp;
+       eh_result = OC_EH_OK;
+       //eh_result = OC_EH_CONTENT;
+
+       return eh_result;
+}
+
+OCEntityHandlerResult process_post_request(OCEntityHandlerRequest *eh_request, OCRepPayload **payload)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "process_post_request enter");
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+       if (eh_request->payload && eh_request->payload->type != PAYLOAD_TYPE_REPRESENTATION) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Incoming payload not a representation");
+               return eh_result;
+       }
+
+       OCRepPayload *input = (OCRepPayload *)(eh_request->payload);
+       if (!input) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to parse");
+               return eh_result;
+       }
+       // TBD : Discuss about triggering flag (to be existed or not)
+       // ES_PS_PROVISIONING_COMPLETED state indicates that already provisioning is completed.
+       // A new request for provisioning means overriding existing network provisioning information.
+
+       if (eh_request->resource == g_prov_resource.handle) {
+               update_prov_resource(eh_request, input);
+       } else if (eh_request->resource == g_wifi_resource.handle) {
+               update_wifi_resource(input);
+       } else if (eh_request->resource == g_cloud_resource.handle) {
+               update_cloud_resource(input);
+       } else if (eh_request->resource == g_dev_conf_resource.handle) {
+               update_dev_conf_resource(input);
+       }
+
+       OCRepPayload *getResp = NULL;
+       if (eh_request->resource == g_prov_resource.handle) {
+               getResp = construct_response_of_prov(eh_request);
+       } else if (eh_request->resource == g_wifi_resource.handle) {
+               getResp = construct_response_of_wifi(OC_RSRVD_INTERFACE_DEFAULT);
+       } else if (eh_request->resource == g_cloud_resource.handle) {
+               getResp = construct_response_of_cloud(OC_RSRVD_INTERFACE_DEFAULT);
+       } else if (eh_request->resource == g_dev_conf_resource.handle) {
+               getResp = construct_response_of_dev_conf(OC_RSRVD_INTERFACE_DEFAULT);
+       }
+
+       if (!getResp) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "constructResponse failed");
+               return OC_EH_ERROR;
+       }
+
+       *payload = getResp;
+       eh_result = OC_EH_OK;
+       //eh_result = OC_EH_CHANGED;
+
+       return eh_result;
+}
+
+OCEntityHandlerResult process_put_request(OCEntityHandlerRequest *eh_request, OCRepPayload **payload)
+{
+       (void)eh_request;
+       (void)payload;
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       return eh_result;
+}
+
+/**
+ * This is the entity handler for the registered resource.
+ * This is invoked by OCStack whenever it recevies a request for this resource.
+ */
+OCEntityHandlerResult things_entity_handler_cb(OCEntityHandlerFlag flag, OCEntityHandlerRequest *entity_handler_request, void *callback)
+{
+       (void)callback;
+       OCEntityHandlerResult eh_ret = OC_EH_ERROR;
+       OCEntityHandlerResponse response;
+       OCRepPayload *payload = NULL;
+
+       THINGS_LOG(THINGS_DEBUG, ES_RH_TAG, "Called OCEntityHandler.");
+
+       // Validate pointer
+       if (!entity_handler_request) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Invalid request pointer");
+               return OC_EH_ERROR;
+       }
+
+       if (flag & OC_REQUEST_FLAG) {
+               if (things_get_reset_mask(RST_EASY_SETUP_DISABLE) == true) {
+                       THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Easy Setup Disable.");
+                       eh_ret = OC_EH_NOT_ACCEPTABLE;
+               } else if (g_prov_resource.handle != NULL) {
+                       if (OC_REST_GET == entity_handler_request->method) {
+                               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Received GET request");
+
+                               eh_ret = process_get_request(entity_handler_request, &payload);
+
+                       }
+//        else if (OC_REST_PUT == entity_handler_request->method)
+//        {
+//            THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Received PUT request");
+//
+//            //PUT request will be handled in the internal implementation
+//            if (g_prov_resource.handle != NULL)
+//            {
+//                eh_ret = process_put_request(entity_handler_request, &payload);
+//            }
+//            else
+//            {
+//                THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Cannot process put");
+//                eh_ret = OC_EH_ERROR;
+//            }
+//        }
+                       else if (OC_REST_POST == entity_handler_request->method) {
+                               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Received OC_REST_POST from client");
+
+                               eh_ret = process_post_request(entity_handler_request, &payload);
+                       } else {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "Not yet Supported Request case(%d).", entity_handler_request->method);
+                               eh_ret = OC_EH_ERROR;
+                       }
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "EZ-Setup Resource not Registered Yet~!!!!!");
+               }
+               // By default it is ==> eh_ret = OC_EH_ERROR;
+               //
+
+               // If the result isn't an error or forbidden, send response
+               //if (!((eh_ret == OC_EH_ERROR) || (eh_ret == OC_EH_FORBIDDEN)))
+               {
+                       THINGS_LOG_V(THINGS_INFO, ES_RH_TAG, "\t\tRespone : (%d) ", (int)eh_ret);
+
+                       response.numSendVendorSpecificHeaderOptions = 0;
+                       memset(response.sendVendorSpecificHeaderOptions, 0, sizeof(response.sendVendorSpecificHeaderOptions));
+                       memset(response.resourceUri, 0, sizeof(response.resourceUri));
+
+                       // Format the response.  Note this requires some info about the request
+                       response.requestHandle = entity_handler_request->requestHandle;
+                       response.resourceHandle = entity_handler_request->resource;
+                       response.ehResult = eh_ret;
+                       response.payload = (OCPayload *)(payload);
+                       // Indicate that response is NOT in a persistent buffer
+                       response.persistentBufferFlag = 0;
+
+                       // Send the response
+                       if (OCDoResponse(&response) != OC_STACK_OK) {
+                               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Error sending response");
+                               eh_ret = OC_EH_ERROR;
+                       }
+                       /*! Added by st_things for memory Leak fix
+                        */
+                       if (payload) {
+                               OCPayloadDestroy((OCPayload *) payload);
+                       }
+                       payload = NULL;
+               }
+               // else
+               // {
+               //     THINGS_LOG_D_ERROR(THINGS_ERROR, ES_RH_TAG, "Return value of Request Process has a error(%d).", eh_ret);
+               // }
+       }
+
+       if (flag & OC_OBSERVE_FLAG) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Flag includes OC_OBSERVE_FLAG");
+               if (OC_OBSERVE_REGISTER == entity_handler_request->obsInfo.action) {
+                       THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Received OC_OBSERVE_REGISTER from client");
+               } else if (OC_OBSERVE_DEREGISTER == entity_handler_request->obsInfo.action) {
+                       THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Received OC_OBSERVE_DEREGISTER from client");
+               }
+       }
+
+       THINGS_LOG(THINGS_DEBUG, ES_RH_TAG, "Common Exit OCEntityHandler.");
+
+       set_wifi_prov_state(WIFI_RESPONSE);
+
+       return eh_ret;
+}
+
+OCStackResult prov_rsc_notify_all_observers(void)
+{
+       OCStackResult ret = OCNotifyAllObservers(g_prov_resource.handle, OC_HIGH_QOS);
+
+       switch (ret) {
+       case OC_STACK_OK:
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Sent notification to Cloud Resource Observers");
+               break;
+       case OC_STACK_NO_OBSERVERS:
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "There is no exist registered Observer client.");
+               break;
+       default:
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Send notification Error : %d", ret);
+               break;
+       }
+
+       ret = OCNotifyAllObservers(g_cloud_resource.handle, OC_HIGH_QOS);
+
+       switch (ret) {
+       case OC_STACK_OK:
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "Sent notification to Cloud Resource Observers");
+               break;
+       case OC_STACK_NO_OBSERVERS:
+               THINGS_LOG(THINGS_INFO, ES_RH_TAG, "There is no exist registered Observer client.");
+               break;
+       default:
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Send notification Error : %d", ret);
+               break;
+       }
+
+       return ret;
+}
+
+things_es_enrollee_state_e get_enrollee_state(void)
+{
+       things_es_enrollee_state_e Status = ES_STATE_INIT;
+
+       pthread_mutex_lock(&g_status_mutex);
+       Status = g_prov_resource.status;
+       pthread_mutex_unlock(&g_status_mutex);
+
+       return Status;
+}
+
+OCStackResult set_device_property(es_device_property *device_property)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_device_property IN");
+
+       g_wifi_resource.supported_freq = (device_property->WiFi).freq;
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "WiFi Freq : %d", g_wifi_resource.supported_freq);
+
+       int mode_idx = 0;
+       while ((device_property->WiFi).mode[mode_idx] != WiFi_EOF) {
+               g_wifi_resource.supported_mode[mode_idx] = (device_property->WiFi).mode[mode_idx];
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "WiFi Mode : %d", g_wifi_resource.supported_mode[mode_idx]);
+               mode_idx++;
+       }
+       g_wifi_resource.num_mode = mode_idx;
+
+       things_strncpy(g_dev_conf_resource.devName, (device_property->dev_conf_s).device_name, MAX_DEVICELEN);
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Device Name : %s", g_dev_conf_resource.devName);
+
+       things_strncpy(g_dev_conf_resource.device_type, (device_property->dev_conf_s).device_type, THINGS_STRING_MAX_VALUE);
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Device device_type : %s", g_dev_conf_resource.device_type);
+
+       things_strncpy(g_dev_conf_resource.device_sub_type, (device_property->dev_conf_s).device_sub_type, THINGS_STRING_MAX_VALUE);
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Device device_sub_type : %s", g_dev_conf_resource.device_sub_type);
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_device_property OUT");
+       return OC_STACK_OK;
+}
+
+OCStackResult set_enrollee_state(things_es_enrollee_state_e es_state)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_enrollee_state IN");
+
+       pthread_mutex_lock(&g_status_mutex);
+       OCStackResult result = OC_STACK_ERROR;
+       things_es_enrollee_state_e preState = g_prov_resource.status;
+
+       if (g_prov_resource.last_err_code == ER_ERRCODE_SYSTEM_ERROR) {
+               g_prov_resource.status = ES_STATE_INIT;
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Please Check your System.(Status=%s , ErrCode=%s)", get_prov_status(g_prov_resource.status), get_prov_errcode(g_prov_resource.last_err_code));
+               goto GOTO_OUT;
+       }
+
+       switch (es_state) {
+       case ES_STATE_REGISTERING_TO_CLOUD:
+               if (preState != ES_STATE_CONNECTED_TO_ENROLLER && preState != es_state) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "State(%s) is not allowed by Status Policy.(pre-status: %s)", get_prov_status(es_state), get_prov_status(g_prov_resource.status));
+                       goto GOTO_OUT;
+               }
+               break;
+       case ES_STATE_REGISTERED_TO_CLOUD:
+               if (preState != ES_STATE_REGISTERING_TO_CLOUD && preState != es_state) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "State(%s) is not allowed by Status Policy.(pre-status: %s)", get_prov_status(es_state), get_prov_status(g_prov_resource.status));
+                       goto GOTO_OUT;
+               }
+               break;
+       case ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD:
+               if (preState != ES_STATE_REGISTERED_TO_CLOUD && preState != ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD && preState != es_state) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "State(%s) is not allowed by Status Policy.(pre-status: %s)", get_prov_status(es_state), get_prov_status(g_prov_resource.status));
+                       goto GOTO_OUT;
+               }
+               break;
+       case ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD:
+               if (preState != ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD && preState != es_state) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "State(%s) is not allowed by Status Policy.(pre-status: %s)", get_prov_status(es_state), get_prov_status(g_prov_resource.status));
+                       goto GOTO_OUT;
+               }
+               break;
+       }
+
+       if (g_prov_resource.status == es_state) {
+               result = OC_STACK_DUPLICATE_UUID;
+       } else {
+               g_prov_resource.status = es_state;
+               result = OC_STACK_OK;
+       }
+
+       THINGS_LOG_V(THINGS_INFO, ES_RH_TAG, "Enrollee Status : %s (%d)", get_prov_status(g_prov_resource.status), g_prov_resource.status);
+
+GOTO_OUT:
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_enrollee_state OUT");
+       pthread_mutex_unlock(&g_status_mutex);
+       return result;
+}
+
+OCStackResult set_cloud_err_code(ci_error_code_e es_err_code)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_cloud_err_code IN");
+
+       g_prov_resource.vd_err_code = es_err_code;
+       THINGS_LOG_V(THINGS_INFO, ES_RH_TAG, "Cloud ErrorCode : %d", g_prov_resource.vd_err_code);
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_cloud_err_code OUT");
+       return OC_STACK_OK;
+}
+
+OCStackResult set_enrollee_err_code(es_error_code_e es_err_code)
+{
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_enrollee_err_code IN");
+
+       if (g_prov_resource.last_err_code == ER_ERRCODE_SYSTEM_ERROR) {
+               es_set_state(ES_STATE_INIT);
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Please Check your System.(Status=%s , ErrCode=%s)", get_prov_status(get_enrollee_state()), get_prov_errcode(g_prov_resource.last_err_code));
+               return OC_STACK_ERROR;
+       }
+
+       g_prov_resource.last_err_code = es_err_code;
+       THINGS_LOG_V(THINGS_INFO, ES_RH_TAG, "Enrollee ErrorCode : %s(%d)", get_prov_errcode(g_prov_resource.last_err_code), g_prov_resource.last_err_code);
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "set_enrollee_err_code OUT");
+       return OC_STACK_OK;
+}
+
+const char *get_result(OCStackResult result)
+{
+       switch (result) {
+       case OC_STACK_OK:
+               return "OC_STACK_OK";
+       case OC_STACK_INVALID_URI:
+               return "OC_STACK_INVALID_URI";
+       case OC_STACK_INVALID_QUERY:
+               return "OC_STACK_INVALID_QUERY";
+       case OC_STACK_INVALID_IP:
+               return "OC_STACK_INVALID_IP";
+       case OC_STACK_RESOURCE_CHANGED:
+               return "OC_STACK_RESOURCE_CHANGED";
+       case OC_STACK_INVALID_PORT:
+               return "OC_STACK_INVALID_PORT";
+       case OC_STACK_INVALID_CALLBACK:
+               return "OC_STACK_INVALID_CALLBACK";
+       case OC_STACK_INVALID_METHOD:
+               return "OC_STACK_INVALID_METHOD";
+       case OC_STACK_NO_MEMORY:
+               return "OC_STACK_NO_MEMORY";
+       case OC_STACK_COMM_ERROR:
+               return "OC_STACK_COMM_ERROR";
+       case OC_STACK_INVALID_PARAM:
+               return "OC_STACK_INVALID_PARAM";
+       case OC_STACK_NOTIMPL:
+               return "OC_STACK_NOTIMPL";
+       case OC_STACK_NO_RESOURCE:
+               return "OC_STACK_NO_RESOURCE";
+       case OC_STACK_RESOURCE_ERROR:
+               return "OC_STACK_RESOURCE_ERROR";
+       case OC_STACK_SLOW_RESOURCE:
+               return "OC_STACK_SLOW_RESOURCE";
+       case OC_STACK_NO_OBSERVERS:
+               return "OC_STACK_NO_OBSERVERS";
+       case OC_STACK_ERROR:
+               return "OC_STACK_ERROR";
+       case OC_STACK_UNAUTHORIZED_REQ:
+               return "OC_STACK_UNAUTHORIZED_REQ";
+       default:
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Not Supported result value.(%d)", result);
+               return "Not defined OCResult.";
+       }
+}
+
+const char *get_prov_status(things_es_enrollee_state_e status)
+{
+       switch (status) {
+       case ES_STATE_INIT:
+               return "ES_STATE_INIT";
+       case ES_STATE_CONNECTING_TO_ENROLLER:
+               return "ES_STATE_CONNECTING_TO_ENROLLER";
+       case ES_STATE_CONNECTED_TO_ENROLLER:
+               return "ES_STATE_CONNECTED_TO_ENROLLER";
+       case ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER:
+               return "ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER";
+       case ES_STATE_REGISTERING_TO_CLOUD:
+               return "ES_STATE_REGISTERING_TO_CLOUD";
+       case ES_STATE_REGISTERED_TO_CLOUD:
+               return "ES_STATE_REGISTERED_TO_CLOUD";
+       case ES_STATE_FAILED_TO_REGISTER_TO_CLOUD:
+               return "ES_STATE_FAILED_TO_REGISTER_TO_CLOUD";
+       case ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD:
+               return "ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD";
+       case ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD:
+               return "ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD";
+       case ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD:
+               return "ES_STATE_FAILED_TO_PUBLISH_RESOURCES_TO_CLOUD";
+       case ES_STATE_LOGOUT_FROM_CLOUD:
+               return "ES_STATE_LOGOUT_FROM_CLOUD";
+       default:
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Not Supported State value.(%d)", status);
+               return "Not defined State";
+       }
+}
+
+const char *get_prov_errcode(es_error_code_e lastErrcode)
+{
+       switch (lastErrcode) {
+       case ES_ERRCODE_NO_ERROR:
+               return "ES_ERRCODE_NO_ERROR";
+       case ES_ERRCODE_SSID_NOT_FOUND:
+               return "ES_ERRCODE_SSID_NOT_FOUND";
+       case ES_ERRCODE_PW_WRONG:
+               return "ES_ERRCODE_PW_WRONG";
+       case ES_ERRCODE_IP_NOT_ALLOCATED:
+               return "ES_ERRCODE_IP_NOT_ALLOCATED";
+       case ES_ERRCODE_NO_INTERNETCONNECTION:
+               return "ES_ERRCODE_NO_INTERNETCONNECTION";
+       case ES_ERRCODE_TIMEOUT:
+               return "ES_ERRCODE_TIMEOUT";
+       case ES_ERRCODE_FAILED_TO_ACCESS_CLOUD_SERVER:
+               return "ES_ERRCODE_FAILED_TO_ACCESS_CLOUD_SERVER";
+       case ES_ERRCODE_NO_RESPONSE_FROM_CLOUD_SERVER:
+               return "ES_ERRCODE_NO_RESPONSE_FROM_CLOUD_SERVER";
+       case ES_ERRCODE_INVALID_AUTHCODE:
+               return "ES_ERRCODE_INVALID_AUTHCODE";
+       case ES_ERRCODE_INVALID_ACCESSTOKEN:
+               return "ES_ERRCODE_INVALID_ACCESSTOKEN";
+       case ES_ERRCODE_FAILED_TO_REFRESH_ACCESSTOKEN:
+               return "ES_ERRCODE_FAILED_TO_REFRESH_ACCESSTOKEN";
+       case ES_ERRCODE_FAILED_TO_FIND_REGISTERED_DEVICE_IN_CLOUD:
+               return "ES_ERRCODE_FAILED_TO_FIND_REGISTERED_DEVICE_IN_CLOUD";
+       case ES_ERRCODE_FAILED_TO_FIND_REGISTERED_USER_IN_CLOUD:
+               return "ES_ERRCODE_FAILED_TO_FIND_REGISTERED_USER_IN_CLOUD";
+       case ER_ERRCODE_INVALID_PROV_PAYLOAD:
+               return "ER_ERRCODE_INVALID_PROV_PAYLOAD";
+       case ER_ERRCODE_SYSTEM_ERROR:
+               return "ER_ERRCODE_SYSTEM_ERROR";
+       case ES_ERRCODE_UNKNOWN:
+               return "ES_ERRCODE_VENDOR_ERROR";
+       default:
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Not Supported Error value.(%d)", lastErrcode);
+               return "Not Defined last_err_code";
+       }
+}
+
+/*********************************************************************
+ *
+ * Support CI server format.
+ *
+ * - IP:Port
+ * - coaps+tcp://IP
+ * - coaps+tcp://IP:Port
+ * - coaps+tcp://HostName
+ * - coaps+tcp://HostName:Port
+ *
+ *********************************************************************/
+static int check_ci_server_ipv4(char *ci_server, es_cloud_prov_data_s *cloudData)
+{
+       int length = 0;
+       char *pContext = NULL;
+       char *originCIServer = ci_server;
+       char *port = NULL;
+       struct in_addr ip;
+       ip.s_addr = 0;
+
+       if (ci_server == NULL || cloudData == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "ci_server(0x%X)/cloudData(0x%X) is NULL", ci_server, cloudData);
+               return 0;
+       }
+
+       if (strlen(ci_server) == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "ci_server's length is 0");
+               return 0;
+       }
+
+       if (strstr(ci_server, UNSUPPORT_COAP_TCP_HOST) != NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "%s is not support Type", UNSUPPORT_COAP_TCP_HOST);
+               return -1;
+       }
+       // Port Number analysis.
+       if ((pContext = strstr(ci_server, DEFAULT_COAP_TCP_HOST)) != NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "%s type format", DEFAULT_COAP_TCP_HOST);
+
+               ci_server = pContext + strlen(DEFAULT_COAP_TCP_HOST);
+               port = DEFAULT_COAP_PORT;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "[Port] ci_server = %s, port=%s", ci_server, port);
+
+       if ((pContext = strchr(ci_server, ':')) != NULL) {
+               if (*(pContext + 1) == 0 || strlen(pContext + 1) > 5) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Port Num is out of range.(%s)", pContext + 1);
+                       return -1;
+               }
+
+               if (atoi(pContext + 1) == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Invalid Port Num.(Port is not number : %s)", pContext + 1);
+                       return -1;
+               }
+
+               port = pContext + 1;
+               *pContext = 0;
+       }
+
+       if (port == NULL || (length = strlen(ci_server)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Unsupported CI-server format.(port-num is NULL)", originCIServer);
+               return -1;
+       }
+       // ci_server analysis (IP/HostName)
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "[IP] ci_server = %s", ci_server);
+
+       if (inet_aton(ci_server, &ip) == 0 || ip.s_addr == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "ci_server is Host Name.(%s)", ci_server);
+               things_strncpy(cloudData->host_name, ci_server, sizeof(cloudData->host_name));
+               memset(cloudData->ip, 0, IP_PORT);
+               things_strncpy(cloudData->port, port, sizeof(cloudData->port));
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "ci_server is ip address.(%s)", ci_server);
+               things_strncpy(cloudData->ip, ci_server, sizeof(cloudData->ip));
+               memset(cloudData->host_name, 0, THINGS_STRING_MAX_VALUE);
+               things_strncpy(cloudData->port, port, sizeof(cloudData->port));
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Host=%s, IP=%s, Port=%s", cloudData->host_name, cloudData->ip, cloudData->port);
+
+       things_strncpy(cloudData->ci_server, ci_server, sizeof(cloudData->ci_server));
+       cloudData->ci_server[length] = ':';
+       cloudData->ci_server[length + 1] = 0;
+       if (things_strcat(cloudData->ci_server, THINGS_STRING_MAX_VALUE, (const char *)cloudData->port) == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "things_strcat is failed.");
+               return -1;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "cloudData->ci_server = %s", cloudData->ci_server);
+
+       return 1;
+}
+
+bool start_cloud_provisioning(void *cloud_info)
+{
+       bool res = false;
+       int length = 0;
+       char *host = NULL;
+       char *CIServer = NULL;
+       things_cloud_info_s *CIinfo = (things_cloud_info_s *) cloud_info;
+       OCRepPayload *payload = NULL;
+
+       if (CIinfo == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Invalid arguments.");
+               return false;
+       }
+
+       if ((payload = OCRepPayloadCreate()) == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, ES_RH_TAG, "Failed to allocate Payload");
+               return false;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Domain = %s, IP = %s", CIinfo->domain, CIinfo->ip);
+
+       if (CIinfo->domain) {
+               length = strlen(DEFAULT_COAP_TCP_HOST) + strlen(CIinfo->domain) + 2;
+               if (CIinfo->port != NULL) {
+                       length += strlen(CIinfo->port);
+               }
+               host = CIinfo->domain;
+               if ((CIServer = (char *)things_malloc(sizeof(char) * length)) == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Memory allocation is failed.");
+                       goto GOTO_OUT;
+               }
+               memset(CIServer, 0, sizeof(char) * length);
+               things_strcat(CIServer, length, DEFAULT_COAP_TCP_HOST);
+       } else if (CIinfo->ip) {
+               length = strlen(CIinfo->ip) + 2;
+               if (CIinfo->port != NULL) {
+                       length += strlen(CIinfo->port);
+               }
+               host = CIinfo->ip;
+               if ((CIServer = (char *)things_malloc(sizeof(char) * length)) == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Memory allocation is failed.");
+                       goto GOTO_OUT;
+               }
+               memset(CIServer, 0, sizeof(char) * length);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, ES_RH_TAG, "Invalid arguments.(domain = 0x%X, ip = 0x%X)", CIinfo->domain, CIinfo->ip);
+               goto GOTO_OUT;
+       }
+
+       things_strcat(CIServer, length, host);
+       if (CIinfo->port != NULL && strlen(CIinfo->port) > 0) {
+               int LCIserver = strlen(CIServer);
+               CIServer[LCIserver] = ':';
+               CIServer[LCIserver + 1] = NULL;
+               things_strcat(CIServer, length, CIinfo->port);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "CIServer = %s", CIServer);
+
+       if (OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_ACCESS_TOKEN, CIinfo->access_token) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", OC_RSRVD_ES_VENDOR_ACCESS_TOKEN, CIinfo->access_token);
+               goto GOTO_OUT;
+       }
+
+       if (CIinfo->access_token_type != NULL) {
+               if (OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_ACCESS_TOKEN_TYPE, CIinfo->access_token_type) == false) {
+                       THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", OC_RSRVD_ES_VENDOR_ACCESS_TOKEN_TYPE, CIinfo->access_token_type);
+                       goto GOTO_OUT;
+               }
+       }
+
+       if (OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, CIinfo->refresh_token) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, CIinfo->refresh_token);
+               goto GOTO_OUT;
+       }
+
+       if (OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_USER_ID, CIinfo->user_id) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", OC_RSRVD_ES_VENDOR_USER_ID, CIinfo->user_id);
+               goto GOTO_OUT;
+       }
+
+       if (OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHPROVIDER, CIinfo->auth_provider) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", OC_RSRVD_ES_AUTHPROVIDER, CIinfo->auth_provider);
+               goto GOTO_OUT;
+       }
+
+       if (OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CISERVER, CIServer) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", OC_RSRVD_ES_CISERVER, CIServer);
+               goto GOTO_OUT;
+       }
+
+       if (OCRepPayloadSetPropString(payload, OC_RSRVD_ES_VENDOR_CLIENTID, CIinfo->client_id) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, ES_RH_TAG, "Inserting \"%s\" property is failed.(value=\"%s\")", OC_RSRVD_ES_VENDOR_CLIENTID, CIinfo->client_id);
+               goto GOTO_OUT;
+       }
+
+       res = update_cloud_resource(payload);
+
+GOTO_OUT:
+       if (CIServer) {
+               things_free(CIServer);
+               CIServer = NULL;
+       }
+
+       if (payload) {
+               OCRepPayloadDestroy(payload);
+               payload = NULL;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, ES_RH_TAG, "Exit.");
+       return res;
+}
diff --git a/framework/src/st_things/things_stack/src/common/framework/Make.defs b/framework/src/st_things/things_stack/src/common/framework/Make.defs
new file mode 100644 (file)
index 0000000..c02cbd8
--- /dev/null
@@ -0,0 +1,23 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += things_data_manager.c things_req_handler.c things_resource.c things_security_manager.c things_server_builder.c
+
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/framework
+VPATH += :src/st_things/things_stack/src/common/framework
\ No newline at end of file
diff --git a/framework/src/st_things/things_stack/src/common/framework/inc/things_common.h b/framework/src/st_things/things_stack/src/common/framework/inc/things_common.h
new file mode 100644 (file)
index 0000000..c4b7147
--- /dev/null
@@ -0,0 +1,46 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _THINGS_COMMON_H_
+#define _THINGS_COMMON_H_
+
+#include "ocstack.h"
+
+typedef OCEntityHandlerResult(*request_handler_cb)(OCEntityHandlerFlag flag, OCEntityHandlerRequest *entity_handler_request, void *cb);
+
+typedef enum {
+       RST_COMPLETE = 0,
+       RST_EASY_SETUP_DISABLE = 1,
+       RST_CLOUD_MODULE_DISABLE = (1 << 1),
+       RST_CONTROL_MODULE_DISABLE = (1 << 2),
+       RST_CONTROL_QUEUE_EMPTY = (1 << 3),
+       RST_NOTI_MODULE_DISABLE = (1 << 4),
+       RST_DELETE_CLOUD_DEVICE_SUCCESS = (1 << 5),
+       RST_DELETE_CLOUD_DEVICE_FAILURE = (1 << 6),
+       RST_USER_CONFIRM_COMPLETED = (1 << 7),
+       RST_ALL_FLAG = 0xFFFFFFFF
+} rst_state_e;
+
+//-----------------------------------------------------------------------------
+// Function prototype
+//-----------------------------------------------------------------------------
+bool things_get_reset_mask(rst_state_e value);
+
+void things_control_queue_empty(void);
+
+#endif                                                 // _THINGS_COMMON_H_
diff --git a/framework/src/st_things/things_stack/src/common/framework/inc/things_data_manager.h b/framework/src/st_things/things_stack/src/common/framework/inc/things_data_manager.h
new file mode 100644 (file)
index 0000000..4f93daa
--- /dev/null
@@ -0,0 +1,136 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _THINGS_DATA_MANAGER_H_
+#define _THINGS_DATA_MANAGER_H_
+
+#include "things_server_builder.h"
+#include "cloud_manager.h"
+#include "things_api.h"
+
+#include <wifi_manager/wifi_manager.h>
+
+#define MAX_DEVICE_TYPE_LENGTH         (25)
+#define MAX_DEVICE_NAME_LENGTH         (32)
+#define MAX_DEVICE_VER_P               (32)
+#define MAX_DEVICE_VER_OS              (32)
+#define MAX_DEVICE_VER_HW              (32)
+#define MAX_DEVICE_VER_FW              (32)
+#define MAX_DEVICE_ID_LENGTH           (37)
+#define MAX_DEVICE_VENDER_ID           (255)
+#define MAX_DEVICE_DESCRIPTION_LENGTH  (255)
+#define MAX_DEVICE_CAPABILTY_CNT       (50)
+#define MAX_DEVICE_MODEL_ID_LENGTH     (64)
+#define MAX_FILE_ACCESS_CNT             (10)
+#define MAX_URI_LENGTH_OCF              (128)
+#define MAX_PROPERTY_CNT                (20)
+#define MAX_FILE_PATH_LENGTH            (250)
+#define MAX_PROPERTY_LENGTH_OCF         (64)
+
+struct st_resource_type_s {
+       char rt[MAX_PROPERTY_LENGTH_OCF];
+       int prop_cnt;
+       struct things_attribute_info_s *prop[MAX_PROPERTY_CNT];
+} st_resource_type_s;
+
+struct col_resource_s {
+       char uri[MAX_URI_LENGTH_OCF];
+       char *interface_types[MAX_IT_CNT];
+       struct things_resource_info_s *links[MAX_DEVICE_CAPABILTY_CNT];
+       char *resource_types[MAX_RT_CNT];
+
+       int if_cnt;
+       int rt_cnt;
+       int link_cnt;
+       int policy;
+} col_resource_s;
+
+typedef struct st_device_s {
+       int no;
+       char type[MAX_DEVICE_TYPE_LENGTH];
+       char name[MAX_DEVICE_NAME_LENGTH];
+       char model_num[MAX_DEVICE_MODEL_ID_LENGTH];
+       char ver_p[MAX_DEVICE_VER_P];   // mnpv
+       char ver_os[MAX_DEVICE_VER_OS]; // mnhw
+       char ver_hw[MAX_DEVICE_VER_HW]; // mnhw
+       char ver_fw[MAX_DEVICE_VER_FW]; // mnfv
+       char device_id[MAX_DEVICE_ID_LENGTH];   // mnfv
+       char vender_id[MAX_DEVICE_VENDER_ID];   // mnfv
+       char description[MAX_DEVICE_DESCRIPTION_LENGTH];
+       struct col_resource_s collection[MAX_DEVICE_CAPABILTY_CNT];
+       struct things_resource_info_s single[MAX_DEVICE_CAPABILTY_CNT];
+
+       int capa_cnt;
+       int col_cnt;
+       int sig_cnt;
+       int is_physical;
+
+       struct things_resource_s *pchild_resources[MAX_DEVICE_CAPABILTY_CNT];
+} st_device_s;
+
+int dm_init_module(const char *info_Path);
+
+int dm_termiate_module(void);
+
+const char *dm_get_svrdb_file_path(void);
+const char *dm_get_certificate_file_path(void);
+const char *dm_get_privatekey_file_path(void);
+const char *dm_get_filename(int filenum);
+const char *dm_get_things_device_type(int device_id);
+const char *dm_get_resource_uri(int device_num, int index);
+const char *dm_get_things_cloud_address(char *customized_ci_server);
+
+const int dm_get_file_id(int filenum);
+const int dm_get_num_of_files(void);
+const int dm_get_num_of_children(int device_num);
+const int dm_get_wifi_property_interface();
+const int dm_get_ownership_transfer_method();
+const wifi_freq_e dm_get_wifi_property_freq();
+
+struct things_resource_s *dm_get_resource_instance(const char *uri, const int id);
+
+int dm_get_device_information(int *cnt, st_device_s ***list);
+
+long dm_get_num_of_dev_cnt(void);
+st_device_s *dm_get_info_of_dev(unsigned long number);
+bool dm_register_user_define_device_id(const int seq_thing_info, const char *dev_id);
+bool dm_register_device_id(void);
+int dm_register_resource(things_server_builder_s *builder);
+
+int save_acces_point_info(wifi_manager_ap_config_s *connect_config);
+int dm_update_things_cloud(es_cloud_signup_s *cl_data);
+int dm_load_legacy_cloud_data(es_cloud_signup_s **cl_data);
+
+bool dm_is_rsc_published(void);
+
+int dm_del_things_cloud_data(void);
+bool dm_is_there_things_cloud(void);
+
+int dm_validate_attribute_in_request(char *res_type, const void *payload);
+
+typedef enum {
+       es_conn_type_none = 0,
+       es_conn_type_softap = 1,
+       es_conn_type_ble = 2,
+} easysetup_connectivity_type_e;
+
+easysetup_connectivity_type_e dm_get_easysetup_connectivity_type(void);
+wifi_manager_softap_config_s *dm_get_softap_wifi_config(void);
+wifi_manager_ap_config_s *dm_get_homeap_wifi_config();
+
+#endif                                                 // _THINGS_DATA_MANAGER_H_
diff --git a/framework/src/st_things/things_stack/src/common/framework/inc/things_req_handler.h b/framework/src/st_things/things_stack/src/common/framework/inc/things_req_handler.h
new file mode 100644 (file)
index 0000000..2878403
--- /dev/null
@@ -0,0 +1,48 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _THINGS_REQ_HANDLER_H_
+#define _THINGS_REQ_HANDLER_H_
+
+#include "ocstack.h"
+#include "things_common.h"
+#include "things_resource.h"
+#include "things_api.h"
+#include "octypes.h"
+
+typedef struct things_request_handler_s {
+       request_handler_cb entity_handler;
+
+       void (*init_module)(void);
+       void (*deinit_module)(void);
+       int (*notify_things_observers)(const char *uri);
+} things_request_handler_s;
+
+things_request_handler_s *get_handler_instance();
+
+typedef int (*stop_softap_func_type)(int value);
+typedef int (*handle_request_func_type)(struct things_resource_s *res);
+typedef char *(*get_notify_obs_uri_cb)(const char *Uri, const char *query);
+typedef OCEntityHandlerResult(*handle_request_interface_cb)(things_resource_s **ppst_target_resource);
+
+void release_handler_instance(things_request_handler_s *);
+int register_stop_softap_cb(stop_softap_func_type func);
+void notify_result_of_reset(things_resource_s *target_resource, bool result);
+int register_handle_request_func(handle_request_func_type get_func, handle_request_func_type set_func);
+
+#endif                                                 // _THINGS_REQ_HANDLER_H_
diff --git a/framework/src/st_things/things_stack/src/common/framework/inc/things_security_manager.h b/framework/src/st_things/things_stack/src/common/framework/inc/things_security_manager.h
new file mode 100644 (file)
index 0000000..17a6009
--- /dev/null
@@ -0,0 +1,142 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _THINGS_SECURITY_MANAGER_H_
+#define _THINGS_SECURITY_MANAGER_H_
+
+#include "srmutility.h"
+
+#ifdef __SECURED__
+/**
+ * @brief   Authentication type for ownership transfer
+ *              b00000001  (1):  Just works authentication
+ *              b00000010  (2):  Random PIN based authentication
+ *              b00000100  (4):  Certificate based authentication
+ *              b00001000  (8):  Decentralized public key based authentication
+ *              b00010000 (16):  Preconfigured PIN based authentication
+ *              b00100000 (32):  Mutual Verification Just works authentication
+ */
+typedef enum things_auth_type_e {
+       AUTH_UNKNOW = (0x0),
+       AUTH_JUST_WORKS = (0x1 << 0),
+       AUTH_RANDOM_PIN = (0x1 << 1),
+       AUTH_CERTIFICATE = (0x1 << 2),
+       AUTH_DECENTRALIZED_PUB_KEY = (0x1 << 3),
+       AUTH_PRECONF_PIN = (0x1 << 4),
+       AUTH_JUST_WORKS_MUTUAL_VERIFIED = (0x1 << 5),
+       AUTH_CERTIFICATE_CONFIRM = (0x1 << 6),
+} things_auth_type_e;
+
+/**
+ * Access policy in least significant bits (from Spec):
+ *              b00000001  (1):  CREATE
+ *              b00000010  (2):  READ
+ *              b00000100  (4):  WRITE
+ *              b00001000  (8):  DELETE
+ *              b00010000 (16):  NOTIFY
+ *              b00011111 (31) Full permission
+ */
+#define ACL_PERMISSION_CREATE       (0x1 << 0)
+#define ACL_PERMISSION_READ         (0x1 << 1)
+#define ACL_PERMISSION_WRITE        (0x1 << 2)
+#define ACL_PERMISSION_DELETE       (0x1 << 3)
+#define ACL_PERMISSION_NOTIFY       (0x1 << 4)
+#define ACL_PERMISSION_FULL (ACL_PERMISSION_CREATE | \
+                                                               ACL_PERMISSION_READ | \
+                                                               ACL_PERMISSION_WRITE | \
+                                                               ACL_PERMISSION_DELETE | \
+                                                               ACL_PERMISSION_NOTIFY)
+
+/**
+ * Function to reset the SVR DB(security provisioning data)
+ *
+ * @param authTypes authentication type for ownership transfer
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_init_things_security(int auth_type, const char *db_path);
+
+/**
+ * Function to init SVR DB(security provisioning data)
+ * If SVR DB not exist, SVR DB will be generated.
+ *
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_init_svrdb();
+
+/**
+ * Function to reset SVR DB
+ *
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_reset_svrdb();
+
+/**
+ * Function to generate MAC based UUID.
+ * NOTE : device uuid will be changed to the MD5 hash value of MAC address
+ *
+ * @param is_forced if true, Device UUID will be created forcibly.
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_generate_mac_based_device_id(bool is_forced);
+
+/**
+ * Function to save the Cloud ACL
+ *
+ * @param cloud_uuid UUID for cloud
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_save_cloud_acl(const char *cloud_uuid);
+
+/**
+ * Function to save the ACL
+ *
+ * @param uuid                 UUID of controller or wildcard("*")
+ * @param resourceUri          resource URI to be added into access control list.
+ * @param resourceType         Type name of resource
+ * @param interfaceName        Interface name of resource
+ * @param permission           Access permission value
+ *               Access policy in least significant bits (from Spec):
+ *                   b00000001  (1):  CREATE
+ *                   b00000010  (2):  READ
+ *                   b00000100  (4):  WRITE
+ *                   b00001000  (8):  DELETE
+ *                   b00010000 (16):  NOTIFY
+ *                   b00011111 (31) Full permission
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_save_acl(const char *uuid, const char *resource_uri, const char *resource_type, const char *interface_name, uint16_t permission);
+
+/**
+ * API to register OTM event handler
+ *
+ * @param otmEventHandler implementation of OTM event handler (@ref OicSecOtmEventHandler_t)
+ */
+extern void sm_set_otm_event_handler(OicSecOtmEventHandler_t otm_event_handler);
+
+/**
+ * Function to set a MOT status
+ *
+ * @param enable whether the MOT is enabled. (true=enable, false=disable)
+ *
+ * @ret 0 is success, otherwise fail.
+ */
+extern int sm_set_mot_status(bool enable);
+
+#endif                                                 //__SECURED__
+
+#endif                                                 //_THINGS_SECURITY_MANAGER_H_
diff --git a/framework/src/st_things/things_stack/src/common/framework/inc/things_server_builder.h b/framework/src/st_things/things_stack/src/common/framework/inc/things_server_builder.h
new file mode 100644 (file)
index 0000000..04c3186
--- /dev/null
@@ -0,0 +1,55 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _THINGS_SERVER_BUILDER_H_
+#define _THINGS_SERVER_BUILDER_H_
+
+#include "things_resource.h"
+#include "things_common.h"
+#include "things_list.h"
+
+#define MAX_DEVICE_NUM    50
+#define MAX_RESOURCE_NUM  (50 * MAX_DEVICE_NUM)
+
+typedef struct things_server_builder_s {
+       size_t res_num;
+       request_handler_cb handler;
+       struct things_resource_s *gres_arr[MAX_RESOURCE_NUM];   // this need to be linked list based stack..
+
+       void (*init_module)(struct things_server_builder_s *, request_handler_cb);
+       void (*deinit_module)(struct things_server_builder_s *);
+       void (*set_device_info)(struct things_server_builder_s *, char *, char *);
+       void (*set_platform_info)(struct things_server_builder_s *, char *, char *, char *, char *, char *, char *);
+       struct things_resource_s *(*create_resource)(struct things_server_builder_s *, char *, char *, char *, int, int, int);
+       struct things_resource_s *(*create_collection_resource)(struct things_server_builder_s *, char *, char *, char *);
+       struct things_resource_s *(*get_resource)(struct things_server_builder_s *, const char *);
+       void (*delete_resource)(struct things_server_builder_s *);
+
+       int (*add_interface_type)(struct things_resource_s *, char *);
+       int (*add_resource_type)(struct things_resource_s *, char *);
+
+       void (*bind)(struct things_resource_s *, struct things_resource_s *);
+       void (*bind_all)(struct things_resource_s *, struct things_resource_s *[], size_t);
+
+       int (*broadcast_presence)(struct things_server_builder_s *, int);
+} things_server_builder_s;
+
+extern struct things_server_builder_s *get_builder_instance();
+extern void release_builder_instance(struct things_server_builder_s *builder);
+
+#endif                                                 // _THINGS_SERVER_BUILDER_H_
diff --git a/framework/src/st_things/things_stack/src/common/framework/things_data_manager.c b/framework/src/st_things/things_stack/src/common/framework/things_data_manager.c
new file mode 100644 (file)
index 0000000..3b753fd
--- /dev/null
@@ -0,0 +1,2271 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+
+#include <string.h>
+#include <stdlib.h>
+#include <json/cJSON.h>
+
+#include "octypes.h"
+#include "ocpayload.h"
+#include "easysetup.h"
+#include "ocstackconfig.h"
+#include "ocrandom.h"
+#include "things_def.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_string_util.h"
+#include "things_hashmap.h"
+#include "things_resource.h"
+#include "things_data_manager.h"
+#include "things_server_builder.h"
+#include "cloud_manager.h"
+#include "cloud_connector.h"
+#include "things_types.h"
+
+#define TAG "[things_datamgr]"
+
+#define KEY_CLOUD       "cloud"
+#define KEY_WIFI       "wifi"
+
+#define KEY_WIFI_SSID       "ssid"
+#define KEY_WIFI_PASSPHARASE       "passphrase"
+#define KEY_WIFI_AUTH_TYPE       "auth_type"
+#define KEY_WIFI_CRYPTO_TYPE       "crypto_type"
+
+#define KEY_CLOUD_DOMAIN   "domain"
+#define KEY_CLOUD_ADDRESS  "address"
+#define KEY_CLOUD_PORT     "port"
+#define KEY_FILE_PATH    "fileRWpath"
+#define KEY_ATTR_PATH2   "path"
+
+#define KEY_DEVICE         "device"
+#define KEY_DEVICE_SPECIFICATION    "specification"
+#define KEY_DEVICE_SPECIFICATION_DEVICE     "device"
+#define KEY_DEVICE_SPECIFICATION_DEVICE_DEVICETYPE      "deviceType"
+#define KEY_DEVICE_SPECIFICATION_DEVICE_DEVICENAME      "deviceName"
+#define KEY_DEVICE_SPECIFICATION_DEVICE_SPECVERSION     "specVersion"
+#define KEY_DEVICE_SPECIFICATION_DEVICE_DATAMODELVERSION    "dataModelVersion"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM   "platform"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_MANUFACTURERNAME  "manufacturerName"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_MANUFACTURERURI   "manufacturerUrl"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_MANUFACTURINGDATE "manufacturingDate"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_MODELNUMBER   "modelNumber"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_PLATFORMVERSION   "platformVersion"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_OSVERSION     "osVersion"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_HARDWAREVERSION   "hardwareVersion"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_FIRMWAREVERSION   "v"
+#define KEY_DEVICE_SPECIFICATION_PLATFORM_VENDORID  "vendorId"
+
+#define KEY_RESOURCES       "resources"
+#define KEY_RESOURCES_TYPE  "resourceTypes"
+
+#define KEY_RESOURCES_COL   "collection"
+#define KEY_RESOURCES_SIG   "single"
+
+#define KEY_CONFIGURATION    "configuration"
+#define KEY_CONFIGURATION_EASYSETUP    "easySetup"
+#define KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY    "connectivity"
+#define KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_TYPE    "type"
+
+#define KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP    "softAP"
+#define KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP_MANUFACTUREID    "manufacturerId"
+#define KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP_SETUPID    "setupId"
+#define KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP_ARTIK    "artik"
+#define KEY_CONFIGURATION_EASYSETUP_OWNERSHIP       "ownershipTransferMethod"
+
+#define KEY_CONFIGURATION_WIFI    "wifi"
+#define KEY_CONFIGURATION_WIFI_INTERFACES    "interfaces"
+#define KEY_CONFIGURATION_WIFI_FREQUENCY    "frequency"
+
+#define KEY_CONFIGURATION_FILEPATH      "filePath"
+#define KEY_CONFIGURATION_FILEPATH_SVRDB    "svrdb"
+#define KEY_CONFIGURATION_FILEPATH_PROVISIONING     "provisioning"
+#define KEY_CONFIGURATION_FILEPATH_CERTIFICATE     "certificate"
+#define KEY_CONFIGURATION_FILEPATH_PRIVATEKEY       "privateKey"
+
+#define KEY_DEVICE_RESOURCE_URI "uri"
+#define KEY_DEVICE_RESOURCE_TYPES "types"
+#define KEY_DEVICE_RESOURCE_INTERFACES "interfaces"
+#define KEY_DEVICE_RESOURCE_POLICY "policy"
+#define KEY_DEVICE_RESOURCE_COLLECTION_LINKS    "links"
+
+#define KEY_DEVICE_RESOURCETYPE_TYPE   "type"
+#define KEY_DEVICE_RESOURCETYPE_PROPERTIES    "properties"
+#define KEY_DEVICE_RESOURCETYPE_PROPERTIES_KEY    "key"
+#define KEY_DEVICE_RESOURCETYPE_PROPERTIES_TYPE    "type"
+#define KEY_DEVICE_RESOURCETYPE_PROPERTIES_MANDATORY    "mandatory"
+#define KEY_DEVICE_RESOURCETYPE_PROPERTIES_RW    "rw"
+
+#define KEY_ATTR_DEVICE_DEVICEID     "devid"
+
+#define CHECK_BIT(var, pos)  (((var)>>(pos)) & 1)
+
+#define CHECK_READABLE(var) CHECK_BIT(var, 0)
+#define CHECK_WRITABLE(var) CHECK_BIT(var, 1)
+
+#define CHECK_DISCOVERABLE(var) CHECK_BIT(var, 0)
+#define CHECK_OBSERVABLE(var)   CHECK_BIT(var, 1)
+#define CHECK_SECURE(var)       CHECK_BIT(var, 2)
+
+#define MAX_FILE_ACCESS_CNT          (10)
+#define MAX_KEY_LENGTH               (50)
+
+#define MAX_URI_LENGTH          (128)
+#define MAX_IT_CNT                    (5)
+#define MAX_RT_CNT                   (10)
+
+#define MAX_ATTRIBUTE_LENGTH     (64)
+
+#define MAX_CLOUD_ADDRESS           (256)      //   Need to match with the Cloud Spec.
+#define MAX_CLOUD_SESSIONKEY        (128)      //   Need to match with the Cloud Spec.
+
+#define MAX_FILE_PATH_LENGTH        (250)
+
+#define MAX_SUBDEVICE_EA            (100)
+
+static bool is_support_user_def_dev_list = true;       // It's allow to apply user-defined device-ID only when start Stack.
+static char *user_def_dev_list[MAX_SUBDEVICE_EA + 1] = { 0, };
+
+static volatile int resource_type_cnt = 0;
+
+static char g_things_cloud_file_path[MAX_FILE_PATH_LENGTH] = { 0 };
+static char g_things_info_file_path[MAX_FILE_PATH_LENGTH] = { 0 };
+static char g_svrdb_file_path[MAX_FILE_PATH_LENGTH] = { 0 };
+static char g_certificate_file_path[MAX_FILE_PATH_LENGTH] = { 0 };
+static char g_private_key_file_path[MAX_FILE_PATH_LENGTH] = { 0 };
+
+static char g_cloud_address[MAX_CLOUD_ADDRESS] = { 0 };
+
+static char *g_manufacturer_name;
+static char *g_setup_id;
+static bool is_artik;
+
+static int g_wifi_interface;
+static wifi_freq_e g_wifi_freq;
+
+static int g_ownership_transfer_method = 0;
+
+static struct hashmap_s *g_resource_type_hmap = NULL;  // map for resource types
+static struct hashmap_s *g_device_hmap = NULL;
+
+static bool is_there_cloud_data = false;
+static const char *origin_cloud_json_str = "{\n\
+               \"cloud\":    {\n\
+                       \"address\":    \"52.40.216.160:5683\"\n\
+               },\n\
+               \"wifi\": {\n\
+                       \"ssid\": \"unknown\"\n\
+               }\n\
+}";
+
+static wifi_manager_softap_config_s ap_config;
+static easysetup_connectivity_type_e es_conn_type = es_conn_type_none;
+static wifi_manager_ap_config_s g_homeap_info;
+
+typedef int8_t INT8;
+
+#define STD_CI_CLOUD_ADDRESS "52.40.216.160:5683"
+#define MAX_CI_CLOUD_ADDRESS 256
+static es_cloud_signup_s *gpst_cloud_data = NULL;
+static char g_ci_cloud_address[MAX_CI_CLOUD_ADDRESS] = { 0 };
+
+struct things_attribute_info_s const gstAttr_x_com_samsung_provisioninginfo[] = {
+       {
+               .key = "x.com.samsung.provisioning.targets",
+               .type = 9,
+               .mandatory = false,
+               .rw = 1
+       },
+       {
+               .key = "x.com.samsung.provisioning.owned",
+               .type = 0,
+               .mandatory = false,
+               .rw = 1
+       },
+       {
+               .key = "x.com.samsung.provisioning.easysetupdi",
+               .type = 3,
+               .mandatory = false,
+               .rw = 1
+       },
+       {
+               .key = "x.com.samsung.provisioning.reset",
+               .type = 0,
+               .mandatory = false,
+               .rw = 3
+       },
+       {
+               .key = "x.com.samsung.provisioning.stopAP",
+               .type = 0,
+               .mandatory = false,
+               .rw = 3
+       }
+};
+
+const struct things_attribute_info_s const gstAttr_x_com_samsung_accesspointlist[] = {
+       {
+               .key = "x.com.samsung.accesspoint.items",
+               .type = 9,
+               .mandatory = true,
+               .rw = 1
+       }
+};
+
+static const struct st_resource_type_s const gst_resource_types[] = {
+       {
+               .rt = "x.com.samsung.provisioninginfo",
+               .prop_cnt = 5,
+               .prop[0] = &gstAttr_x_com_samsung_provisioninginfo[0],
+               .prop[1] = &gstAttr_x_com_samsung_provisioninginfo[1],
+               .prop[2] = &gstAttr_x_com_samsung_provisioninginfo[2],
+               .prop[3] = &gstAttr_x_com_samsung_provisioninginfo[3],
+               .prop[4] = &gstAttr_x_com_samsung_provisioninginfo[4]
+       },
+       {
+               .rt = "x.com.samsung.accesspointlist",
+               .prop_cnt = 1,
+               .prop[0] = &gstAttr_x_com_samsung_accesspointlist[0]
+       }
+};
+
+static const struct things_resource_info_s const gstResources[] = {
+       {
+               .uri = "/sec/provisioninginfo",
+               .interface_types = {"oic.if.a"},
+               .resource_types = {"x.com.samsung.provisioninginfo"},
+               .if_cnt = 1,
+               .rt_cnt = 1,
+               .policy = 3
+       },
+       {
+               .uri = "/sec/accesspointlist",
+               .interface_types = {"oic.if.s"},
+               .resource_types = {"x.com.samsung.accesspointlist"},
+               .if_cnt = 1,
+               .rt_cnt = 1,
+               .policy = 3
+       }
+};
+
+bool update_and_save_device_info(st_device_s **dev_list, int dev_cnt)
+{
+       assert(1);
+       return false;
+}
+
+/**
+ *     @fn get_cloud_server_address
+ *     @brief Function to get cloud server address
+ *  @param pch_current_server
+ *  @return
+ */
+char *get_cloud_server_address(char *pch_current_server)
+{
+       if (gpst_cloud_data != NULL) {
+               memset(g_ci_cloud_address, 0, MAX_CI_CLOUD_ADDRESS);
+               memcpy(g_ci_cloud_address, gpst_cloud_data->address, strlen(gpst_cloud_data->address) + 1);
+       } else {
+               memcpy(g_ci_cloud_address, STD_CI_CLOUD_ADDRESS, strlen(STD_CI_CLOUD_ADDRESS));
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "CLOUD CI Address : %s", g_ci_cloud_address);
+
+       return g_ci_cloud_address;
+}
+
+static struct things_attribute_info_s *create_property()
+{
+       struct things_attribute_info_s *property = things_malloc(sizeof(things_attribute_info_s));
+
+       memset(property->key, 0, (size_t) MAX_KEY_LENGTH);
+       property->type = 0;
+       property->mandatory = false;
+       property->rw = 0;
+
+       return property;
+}
+
+static struct st_resource_type_s *create_resource_type()
+{
+       struct st_resource_type_s *type = things_malloc(sizeof(st_resource_type_s));
+
+       memset(type->rt, 0, (size_t) MAX_ATTRIBUTE_LENGTH);
+       memset(type->prop, 0, (size_t) MAX_PROPERTY_CNT);
+       type->prop_cnt = 0;
+
+       return type;
+}
+
+static struct things_resource_info_s *create_resource()
+{
+       struct things_resource_info_s *resource = things_malloc(sizeof(things_resource_info_s));
+
+       memset(resource->uri, 0, sizeof(resource->uri));
+       memset(resource->interface_types, 0, sizeof(resource->interface_types));
+       memset(resource->resource_types, 0, sizeof(resource->resource_types));
+       resource->policy = 0;
+       resource->if_cnt = 0;
+       resource->rt_cnt = 0;
+
+       return resource;
+}
+
+static st_device_s *create_device()
+{
+       st_device_s *device = things_malloc(sizeof(st_device_s));
+
+       memset(device->type, 0, (size_t) MAX_DEVICE_TYPE_LENGTH);
+       memset(device->name, 0, (size_t) MAX_DEVICE_NAME_LENGTH);
+       memset(device->model_num, 0, (size_t) MAX_DEVICE_MODEL_ID_LENGTH);
+       memset(device->ver_p, 0, (size_t) MAX_DEVICE_VER_P);
+       memset(device->ver_os, 0, (size_t) MAX_DEVICE_VER_OS);
+       memset(device->ver_hw, 0, (size_t) MAX_DEVICE_VER_HW);
+       memset(device->ver_fw, 0, (size_t) MAX_DEVICE_VER_FW);
+       memset(device->device_id, 0, (size_t) MAX_DEVICE_ID_LENGTH);
+       memset(device->vender_id, 0, (size_t) MAX_DEVICE_VENDER_ID);
+       memset(device->description, 0, (size_t) MAX_DEVICE_DESCRIPTION_LENGTH);
+
+       device->no = -1;
+       device->capa_cnt = 0;
+       device->col_cnt = 0;
+       device->sig_cnt = 0;
+       device->is_physical = 0;
+
+       for (int index = 0; index < MAX_DEVICE_CAPABILTY_CNT; index++) {
+               device->pchild_resources[index] = NULL;
+       }
+
+       return device;
+}
+
+static size_t get_json_file_size(const char *filename)
+{
+       size_t size = 0;
+       FILE *fp = fopen(filename, "r");
+
+       if (fp) {
+               if (0 == fseek(fp, 0L, SEEK_END)) {
+                       size = ftell(fp);
+                       rewind(fp);
+               }
+               fclose(fp);
+       }
+       return size;
+}
+
+static char *get_json_string_from_file(const char *filename)
+{
+       FILE *fp = NULL;
+       char *json_str = NULL;
+       size_t size = get_json_file_size(filename);
+       size_t readed = 0;
+       int fp_acess_cnt = 0;
+
+       if (size <= 0) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "Failed converting to JSON");
+               return NULL;
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "File size: %d ", size);
+       }
+
+       json_str = (char *)things_malloc(size + 1);
+
+       // 1. File Read
+       fp = fopen(filename, "r");
+       if (NULL == fp) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Failed to open %s", filename);
+               things_free(json_str);
+               return NULL;
+       }
+       // 2. Json String read from the given file.
+       size_t bytes_read = 0;
+       while (readed < size && fp_acess_cnt < MAX_FILE_ACCESS_CNT) {
+               bytes_read = fread(&(json_str[readed]), 1, size - readed, fp);
+               readed += bytes_read;
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Read Size: %d, total Size =%d", readed, size);
+               fp_acess_cnt++;
+       }
+
+       if (fp_acess_cnt >= MAX_FILE_ACCESS_CNT) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Access-Times is Over for File Read. (Readed Size: %d, total Size =%d)", readed, size);
+               things_free(json_str);
+               fclose(fp);
+               return NULL;
+       }
+
+       json_str[readed] = '\0';
+
+       fclose(fp);
+       fp = NULL;
+
+       return json_str;
+}
+
+static int set_json_string_into_file(const char *filename, const char *json_str)
+{
+       FILE *fp = NULL;
+       // 1. File Read
+       fp = fopen(filename, "w");
+       if (NULL == fp) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Failed to open \"%s\" with Write permission.", filename);
+               return 0;
+       }
+       // 2. Json String read from the given file.
+       fwrite(json_str, 1, strlen(json_str), fp);
+
+       fclose(fp);
+       fp = NULL;
+       return 1;
+}
+
+static int init_things_info_file(cJSON *cjson, char *origin_json_str)
+{
+       int res = 1;
+
+       if (g_things_info_file_path[0] == 0) {
+               int length = 0;
+               cJSON *file_rw_path = cJSON_GetObjectItem(cjson, KEY_FILE_PATH);
+               if (NULL == file_rw_path || (length = strlen(file_rw_path->valuestring)) <= 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "\"%s\" key is not exist in info file. or value is empty.", KEY_FILE_PATH);
+                       return 0;
+               }
+
+               memset(g_things_info_file_path, 0, MAX_FILE_PATH_LENGTH);
+               memcpy(g_things_info_file_path, file_rw_path->valuestring, length + 1);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Info file path : %s", g_things_info_file_path);
+       }
+
+       int is_valid = 1;
+
+       char *json_str = get_json_string_from_file(g_things_info_file_path);
+       if (json_str != NULL) {
+               cJSON *root = cJSON_Parse((const char *)json_str);
+               if (root == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "%s fail to parsed.", g_things_info_file_path);
+                       is_valid = 0;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "%s is empty.", g_things_info_file_path);
+               is_valid = 0;
+       }
+       
+       if (is_valid == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Try to reset the info file.");
+               if (set_json_string_into_file(g_things_info_file_path, origin_json_str) == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "original info file copy failed.");
+                       res = 0;
+               }
+       }
+
+       return res;
+}
+
+static int get_json_int(cJSON *json, int64_t *variable)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter");
+
+       int res = 1;
+
+       if (json == NULL || variable == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "json = %d, variable = %d", json, variable);
+               return 0;
+       }
+
+       if (json->type != cJSON_Number) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "json-value Type is Not String value.");
+               return 0;
+       }
+
+       *variable = json->valueint;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit");
+
+       return res;
+}
+
+static int get_json_string(cJSON *json, char **variable)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter");
+
+       int res = 1;
+       int length = 0;
+
+       if (json == NULL || variable == NULL || *variable != NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "There is NULL value.(json = %d, variable = %d)", json, variable);
+               if (variable != NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "variable value is not NULL.(*variable = %d)", *variable);
+               }
+               return 0;
+       }
+
+       if (json->type != json->type) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "json-value Type is Not String value.");
+               return 0;
+       }
+
+       if ((length = strlen(json->valuestring)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "length is NULL");
+               return 0;
+       }
+
+       *variable = (char *)things_malloc(sizeof(char) * (length + 1));
+       if (*variable == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.");
+               return 0;
+       }
+
+       memset(*variable, 0, length + 1);
+       memcpy(*variable, json->valuestring, length + 1);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit");
+
+       return res;
+}
+
+static int load_cloud_signup_data(cJSON *json, es_cloud_signup_s **cl_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter");
+
+       int res = 1;
+
+       if (json == NULL || cl_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "json = %d, cl_data = %d", json, cl_data);
+               return -1;
+       }
+
+       cJSON *domain = cJSON_GetObjectItem(json, KEY_CLOUD_DOMAIN);
+       cJSON *address = cJSON_GetObjectItem(json, KEY_CLOUD_ADDRESS);
+       cJSON *port = cJSON_GetObjectItem(json, KEY_CLOUD_PORT);
+       cJSON *accesstoken = cJSON_GetObjectItem(json, KEY_TOKEN_ACCESS);
+       cJSON *refresh_accesstoken = cJSON_GetObjectItem(json, KEY_TOKEN_ACCESS_REFRESH);
+       cJSON *token_type = cJSON_GetObjectItem(json, KEY_TOKEN_TYPE);
+       cJSON *expire_time = cJSON_GetObjectItem(json, KEY_EXPIRE_TIME);
+       cJSON *user_id = cJSON_GetObjectItem(json, KEY_ID_USER);
+       cJSON *redirect_uri = cJSON_GetObjectItem(json, KEY_SERVER_REDIRECT_URI);
+       cJSON *certificate = cJSON_GetObjectItem(json, KEY_CERTIFICATE_FILE);
+       cJSON *server_id = cJSON_GetObjectItem(json, KEY_SERVER_ID);
+
+       if (address == NULL || accesstoken == NULL || refresh_accesstoken == NULL || user_id == NULL || expire_time == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "address = %d, accesstoken = %d, refresh_accesstoken = %d, user_id = %d, expire_time = %d", address, accesstoken, refresh_accesstoken, user_id, expire_time);
+               return -2;
+       }
+
+       if (es_cloud_signup_init(cl_data) == false) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ESCloud data initialization is failed.");
+               return -1;
+       }
+
+       if (get_json_string(address, &((*cl_data)->address)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Load JSON String address is failed");
+               res = -1;
+       }
+
+       if (get_json_string(accesstoken, &((*cl_data)->access_token)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Load JSON String accesstoken is failed");
+               res = -1;
+       }
+
+       if (get_json_string(refresh_accesstoken, &((*cl_data)->refresh_token)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Load JSON String refresh_accesstoken is failed");
+               res = -1;
+       }
+
+       if (get_json_string(user_id, &((*cl_data)->uid)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Load JSON String user_id is failed");
+               res = -1;
+       }
+
+       if (get_json_int(expire_time, &((*cl_data)->expire_time)) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Load JSON String expire_time is failed");
+               res = -1;
+       }
+
+       get_json_string(token_type, &((*cl_data)->token_type));
+       get_json_string(redirect_uri, &((*cl_data)->redirect_uri));
+       get_json_string(certificate, &((*cl_data)->certificate));
+       get_json_string(server_id, &((*cl_data)->sid));
+       get_json_string(domain, &((*cl_data)->domain));
+       get_json_string(port, &((*cl_data)->port));
+
+       if (res == -1) {
+               es_cloud_signup_clear(*cl_data);
+               *cl_data = NULL;
+       } else {
+               memcpy(g_cloud_address, (*cl_data)->address, strlen((*cl_data)->address) + 1);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CLOUD CI Address : %s", g_cloud_address);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit");
+
+       return res;
+}
+
+static int if_need_init_things_cloud_file(const char *filename)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int res = 0;
+
+       FILE *fp = fopen(filename, "r");
+       if (fp) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Already Exist : provisioning file.");
+               fclose(fp);
+       } else {
+               if (set_json_string_into_file(filename, origin_cloud_json_str) == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Creating privisioning file is failed.");
+                       res = -1;
+               } else {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Creating privisioning file is Success.");
+                       res = 1;
+               }
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return res;
+}
+
+easysetup_connectivity_type_e dm_get_easysetup_connectivity_type(void)
+{
+       return es_conn_type;
+}
+
+wifi_manager_softap_config_s *dm_get_softap_wifi_config(void)
+{
+       // TO DO : need to make softap SSID by security
+       char *temp_ssid = "samsung_E1";
+       char *temp_passphrase = "1111122222";
+       int temp_channel = 1;
+
+       strncpy(ap_config.ssid, temp_ssid, strlen(temp_ssid) + 1);
+       strncpy(ap_config.passphrase, temp_passphrase, strlen(temp_passphrase) + 1);
+       ap_config.channel = temp_channel;
+
+       return &ap_config;
+}
+
+wifi_manager_ap_config_s *dm_get_homeap_wifi_config(void)
+{
+       return &g_homeap_info;
+}
+
+int parse_things_cloud_json(const char *filename)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ret = 0;
+       char *json_str = NULL;
+
+       if (if_need_init_things_cloud_file(filename) == -1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "RW CloudFile-loading is failed. please check your \"%s\"", filename);
+               return 0;
+       }
+
+RETRY_JSON:
+       json_str = get_json_string_from_file(filename);
+
+       if (json_str == NULL) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "cloud file initialization.");
+               if (set_json_string_into_file(filename, origin_cloud_json_str) == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] Creating cloud file is failed.");
+                       return 0;
+               }
+               goto RETRY_JSON;
+       }
+
+       if (strlen(json_str) > 0) {
+               // 3. Parse the Json string
+               cJSON *root = cJSON_Parse((const char *)json_str);
+
+               if (root == NULL) {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "cloud file context has a error about json-format.");
+                       things_free(json_str);
+                       json_str = NULL;
+
+                       THINGS_LOG_V(THINGS_INFO, TAG, "cloud file initialization.");
+                       if (set_json_string_into_file(filename, origin_cloud_json_str) == 0) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] Creating colud file is failed.");
+                               return 0;
+                       }
+                       goto RETRY_JSON;
+               }
+
+               cJSON *cloud = cJSON_GetObjectItem(root, KEY_CLOUD);
+               cJSON *wifi = cJSON_GetObjectItem(root, KEY_WIFI);
+
+               if (NULL != wifi && NULL != cloud) {
+                       /***** Cloud *****/
+                       cJSON *address = cJSON_GetObjectItem(cloud, KEY_CLOUD_ADDRESS);
+                       if (NULL != address) {
+                               memset(g_cloud_address, 0, (size_t) MAX_CLOUD_ADDRESS);
+                               memcpy(g_cloud_address, address->valuestring, strlen(address->valuestring) + 1);
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[CLOUD] CI Address : %s", g_cloud_address);
+                               ret = 1;
+                       }
+
+                       cJSON *accesstoken = cJSON_GetObjectItem(cloud, KEY_TOKEN_ACCESS);
+                       cJSON *refresh_accesstoken = cJSON_GetObjectItem(cloud, KEY_TOKEN_ACCESS_REFRESH);
+                       cJSON *user_id = cJSON_GetObjectItem(cloud, KEY_ID_USER);
+                       cJSON *expire_time = cJSON_GetObjectItem(cloud, KEY_EXPIRE_TIME);
+
+                       /***** Wifi *****/
+                       cJSON *ssid = cJSON_GetObjectItem(wifi, KEY_WIFI_SSID);
+                       if (NULL != ssid) {
+                               memcpy(g_homeap_info.ssid, ssid->valuestring, strlen(ssid->valuestring) + 1);
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[WIFI] SSID Address : %s", g_homeap_info.ssid);
+                               ret = 1;
+                               g_homeap_info.ssid_length = strlen(g_homeap_info.ssid);
+                       }
+
+                       cJSON *passphrase = cJSON_GetObjectItem(wifi, KEY_WIFI_PASSPHARASE);
+                       if (NULL != passphrase) {
+                               memcpy(g_homeap_info.passphrase, passphrase->valuestring, strlen(passphrase->valuestring) + 1);
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[WIFI] PASSPHRASE Address : %s", g_homeap_info.passphrase);
+                               ret = 1;
+                               g_homeap_info.passphrase_length = strlen(g_homeap_info.passphrase);
+                       }
+
+                       cJSON *auth_type = cJSON_GetObjectItem(wifi, KEY_WIFI_AUTH_TYPE);
+
+                       if (NULL != auth_type) {
+                               g_homeap_info.ap_auth_type = auth_type->valueint;
+                       }
+
+                       cJSON *crypto_type = cJSON_GetObjectItem(wifi, KEY_WIFI_CRYPTO_TYPE);
+                       if (NULL != crypto_type) {
+                               g_homeap_info.ap_crypto_type = crypto_type->valueint;
+                       }
+
+                       if (address == NULL || accesstoken == NULL || refresh_accesstoken == NULL || user_id == NULL || expire_time == NULL || ssid == NULL || passphrase == NULL || auth_type == NULL || crypto_type == NULL) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ProvisionInfo] address = %d, accesstoken = %d, refresh_accesstoken = %d, user_id = %d, expire_time = %d", address, accesstoken, refresh_accesstoken, user_id, expire_time);
+                               is_there_cloud_data = false;
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "[ProvisionInfo] There is mandatory elements in cloud file.");
+                               is_there_cloud_data = true;
+                       }
+               }
+
+               if (NULL != root) {
+                       cJSON_Delete(root);
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Can not Read \"%s\" file.", filename);
+       }
+
+       if (json_str != NULL) {
+               things_free(json_str);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return ret;
+}
+
+static int parse_things_info_json(const char *filename)
+{
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ret = 1;
+       char *json_str = get_json_string_from_file(filename);
+
+       if (json_str != NULL && strlen(json_str) > 0) {
+               // 3. Parse the Json string
+               cJSON *root = cJSON_Parse((const char *)json_str);
+               assert(root != NULL);
+
+               st_device_s *node = NULL;
+
+               // Device Items
+               cJSON *device = cJSON_GetObjectItem(root, KEY_DEVICE);
+               int device_cnt = cJSON_GetArraySize(device);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "device_cnt = %d", device_cnt);
+               if (g_device_hmap == NULL) {
+                       g_device_hmap = hashmap_create(device_cnt);
+               }
+
+               if (g_device_hmap == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "g_device_hmap is NULL");
+                       cJSON_Delete(root);
+
+                       if (json_str != NULL) {
+                               things_free(json_str);
+                       }
+                       return 0;
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "device_cnt of hashmap = %d", hashmap_count(g_device_hmap));
+
+               for (int device_num = 0; device_num < device_cnt; device_num++) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] ============================================");
+
+                       node = create_device();
+                       node->no = device_num;
+                       node->is_physical = 1;
+
+                       cJSON *device_item = cJSON_GetArrayItem(device, device_num);
+                       cJSON *specification = cJSON_GetObjectItem(device_item, KEY_DEVICE_SPECIFICATION);
+                       if (NULL != specification) {
+                               cJSON *spec_device = cJSON_GetObjectItem(specification, KEY_DEVICE_SPECIFICATION_DEVICE);
+                               if (NULL != spec_device) {
+                                       cJSON *device_type = cJSON_GetObjectItem(spec_device, KEY_DEVICE_SPECIFICATION_DEVICE_DEVICETYPE);
+                                       cJSON *device_name = cJSON_GetObjectItem(spec_device, KEY_DEVICE_SPECIFICATION_DEVICE_DEVICENAME);
+                                       cJSON *spec_version = cJSON_GetObjectItem(spec_device, KEY_DEVICE_SPECIFICATION_DEVICE_SPECVERSION);
+                                       cJSON *data_model_version = cJSON_GetObjectItem(spec_device, KEY_DEVICE_SPECIFICATION_DEVICE_DATAMODELVERSION);
+
+                                       if (NULL != device_type) {
+                                               memcpy(node->type, device_type->valuestring, strlen(device_type->valuestring) + 1);
+                                       }
+
+                                       if (NULL != device_name) {
+                                               memcpy(node->name, device_name->valuestring, strlen(device_name->valuestring) + 1);
+                                       }
+                               }
+
+                               cJSON *spec_platform = cJSON_GetObjectItem(specification, KEY_DEVICE_SPECIFICATION_PLATFORM);
+                               if (NULL != spec_platform) {
+                                       cJSON *manufacturer_name = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_MANUFACTURERNAME);
+                                       cJSON *manufacturer_uri = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_MANUFACTURERURI);
+                                       cJSON *manufacturing_date = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_MANUFACTURINGDATE);
+                                       cJSON *model_number = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_MODELNUMBER);
+                                       cJSON *platform_version = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_PLATFORMVERSION);
+                                       cJSON *os_version = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_OSVERSION);
+                                       cJSON *hardware_version = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_HARDWAREVERSION);
+                                       cJSON *firmware_version = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_FIRMWAREVERSION);
+                                       cJSON *vendor_id = cJSON_GetObjectItem(spec_platform, KEY_DEVICE_SPECIFICATION_PLATFORM_VENDORID);
+
+                                       if (NULL != model_number) {
+                                               memcpy(node->model_num, model_number->valuestring, strlen(model_number->valuestring) + 1);
+                                       }
+                                       if (NULL != platform_version) {
+                                               memcpy(node->ver_p, platform_version->valuestring, strlen(platform_version->valuestring) + 1);
+                                       }
+                                       if (NULL != os_version) {
+                                               memcpy(node->ver_os, os_version->valuestring, strlen(os_version->valuestring) + 1);
+                                       }
+                                       if (NULL != hardware_version) {
+                                               memcpy(node->ver_hw, hardware_version->valuestring, strlen(hardware_version->valuestring) + 1);
+                                       }
+                                       if (NULL != firmware_version) {
+                                               memcpy(node->ver_fw, firmware_version->valuestring, strlen(firmware_version->valuestring) + 1);
+                                       }
+                                       if (NULL != vendor_id) {
+                                               memcpy(node->vender_id, vendor_id->valuestring, strlen(vendor_id->valuestring) + 1);
+                                       }
+                               }
+                       }
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] type : %s", (node->type));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] name : %s", (node->name));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] model num : %s", (node->model_num));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] plat. ver : %s", (node->ver_p));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] os version : %s", (node->ver_os));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] hw version : %s", (node->ver_hw));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] fw version : %s", (node->ver_fw));
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] vender id : %s", (node->vender_id));
+
+                       cJSON *resources = cJSON_GetObjectItem(device_item, KEY_RESOURCES);
+                       if (resources != NULL) {
+                               // 1. Read thsoe resource(s) which will be binded into the Collection resource(/device/#)
+                               cJSON *collection = cJSON_GetObjectItem(resources, KEY_RESOURCES_COL);
+
+                               if (collection) {
+                                       node->col_cnt = cJSON_GetArraySize(collection);
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] Resources for Collection Cnt : %d", node->col_cnt);
+
+                                       for (int iter = 0; iter < node->col_cnt; iter++) {
+                                               cJSON *res = cJSON_GetArrayItem(collection, iter);
+                                               if (res->type != NULL) {
+                                                       cJSON *uri = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_URI);
+                                                       memcpy(node->collection[iter].uri, uri->valuestring, strlen(uri->valuestring) + 1);
+                                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] collection[0].uri : %s", (node->collection[iter].uri));
+
+                                                       cJSON *types = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_TYPES);
+                                                       if (types) {
+                                                               int type_cnt = cJSON_GetArraySize(types);
+                                                               node->collection[iter].rt_cnt = type_cnt;
+                                                               for (int typeiter = 0; typeiter < type_cnt; typeiter++) {
+                                                                       cJSON *type = cJSON_GetArrayItem(types, typeiter);
+                                                                       node->collection[iter].resource_types[typeiter] = things_malloc(sizeof(char *) *strlen(type->valuestring) + 1);
+                                                                       memcpy(node->collection[iter].resource_types[typeiter], type->valuestring, strlen(type->valuestring) + 1);
+                                                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] collection[iter].resource_types[typeiter] : %s", (node->collection[iter].resource_types[typeiter]));
+                                                               }
+                                                       } else {
+                                                               return 0;
+                                                       }
+
+                                                       cJSON *interfaces = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_INTERFACES);
+                                                       if (interfaces) {
+                                                               int if_cnt = cJSON_GetArraySize(interfaces);
+                                                               node->collection[iter].if_cnt = if_cnt;
+                                                               for (int ifiter = 0; ifiter < if_cnt; ifiter++) {
+                                                                       cJSON *interface = cJSON_GetArrayItem(interfaces, ifiter);
+                                                                       node->collection[iter].interface_types[ifiter] = things_malloc(sizeof(char *) *strlen(interface->valuestring) + 1);
+                                                                       memcpy(node->collection[iter].interface_types[ifiter], interface->valuestring, strlen(interface->valuestring) + 1);
+                                                               }
+                                                       } else {
+                                                               return 0;
+                                                       }
+
+                                                       cJSON *policy = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_POLICY);
+                                                       node->collection[iter].policy = policy->valueint;
+                                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] collection[iter].policy : %d", (node->collection[iter].policy));
+
+                                                       cJSON *links = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_COLLECTION_LINKS);
+                                                       if (links) {
+                                                               int linkCnt = cJSON_GetArraySize(links);
+                                                               node->collection[iter].link_cnt = linkCnt;
+                                                               THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] collection[iter].link_cnt : %d", (node->collection[iter].link_cnt));
+                                                               for (int linkiter = 0; linkiter < linkCnt; linkiter++) {
+                                                                       cJSON *link = cJSON_GetArrayItem(links, linkiter);
+
+                                                                       struct things_resource_info_s *link_resource = create_resource();
+
+                                                                       cJSON *uri = cJSON_GetObjectItem(link, KEY_DEVICE_RESOURCE_URI);
+                                                                       memcpy(link_resource->uri, uri->valuestring, strlen(uri->valuestring) + 1);
+                                                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] link_resource->uri : %s", (link_resource->uri));
+
+                                                                       cJSON *types = cJSON_GetObjectItem(link, KEY_DEVICE_RESOURCE_TYPES);
+                                                                       if (types) {
+                                                                               int type_cnt = cJSON_GetArraySize(types);
+                                                                               link_resource->rt_cnt = type_cnt;
+                                                                               for (int typeiter = 0; typeiter < type_cnt; typeiter++) {
+                                                                                       cJSON *type = cJSON_GetArrayItem(types, typeiter);
+                                                                                       link_resource->resource_types[typeiter] = things_malloc(sizeof(char *) *strlen(type->valuestring) + 1);
+                                                                                       memcpy(link_resource->resource_types[typeiter], type->valuestring, strlen(type->valuestring) + 1);
+                                                                               }
+                                                                       } else {
+                                                                               return 0;
+                                                                       }
+                                                                       cJSON *interfaces = cJSON_GetObjectItem(link, KEY_DEVICE_RESOURCE_INTERFACES);
+                                                                       if (interfaces) {
+                                                                               int if_cnt = cJSON_GetArraySize(interfaces);
+                                                                               link_resource->if_cnt = if_cnt;
+                                                                               for (int ifiter = 0; ifiter < if_cnt; ifiter++) {
+                                                                                       cJSON *interface = cJSON_GetArrayItem(interfaces, ifiter);
+                                                                                       link_resource->interface_types[ifiter] = things_malloc(sizeof(char *) *strlen(interface->valuestring) + 1);
+                                                                                       memcpy(link_resource->interface_types[ifiter], interface->valuestring, strlen(interface->valuestring) + 1);
+                                                                               }
+                                                                       } else {
+                                                                               return 0;
+                                                                       }
+                                                                       cJSON *policy = cJSON_GetObjectItem(link, KEY_DEVICE_RESOURCE_POLICY);
+                                                                       link_resource->policy = policy->valueint;
+                                                                       node->collection[iter].links[linkiter] = link_resource;
+                                                               }
+                                                       } else {
+                                                               return 0;
+                                                       }
+                                               }
+
+                                       }
+                                       ret = 1;
+
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] URI. : %s", node->collection[0].uri);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] interface_type. : %s", node->collection[0].interface_types[0]);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] resource_types. : %s", node->collection[0].resource_types[0]);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] if_cnt. : %d", node->collection[0].if_cnt);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] rt_cnt. : %d", node->collection[0].rt_cnt);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] link_cnt. : %d", node->collection[0].link_cnt);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[COLLECTION] policy. : %d", node->collection[0].policy);
+                               } else {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "Children Reosurces Not Exist");
+                                       //ret = 0;
+                               }
+
+                               // 2. Read thsoe resource(s) which will not be binded into the Collection resource
+                               cJSON *single = cJSON_GetObjectItem(resources, KEY_RESOURCES_SIG);
+
+                               if (single) {
+                                       node->sig_cnt = cJSON_GetArraySize(single);
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] Resources for Single Usage Cnt : %d", node->sig_cnt);
+
+                                       for (int iter = 0; iter < node->sig_cnt; iter++) {
+                                               cJSON *res = cJSON_GetArrayItem(single, iter);
+                                               if (res->type != NULL) {
+                                                       cJSON *uri = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_URI);
+                                                       memcpy(node->single[iter].uri, uri->valuestring, strlen(uri->valuestring) + 1);
+
+                                                       cJSON *types = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_TYPES);
+                                                       if (types) {
+                                                               int type_cnt = cJSON_GetArraySize(types);
+                                                               node->single[iter].rt_cnt = type_cnt;
+                                                               for (int typeiter = 0; typeiter < type_cnt; typeiter++) {
+                                                                       cJSON *type = cJSON_GetArrayItem(types, typeiter);
+                                                                       node->single[iter].resource_types[typeiter] = things_malloc(sizeof(char *) *strlen(type->valuestring) + 1);
+                                                                       memcpy(node->single[iter].resource_types[typeiter], type->valuestring, strlen(type->valuestring) + 1);
+                                                               }
+                                                       } else {
+                                                               return 0;
+                                                       }
+                                                       cJSON *interfaces = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_INTERFACES);
+                                                       if (interfaces) {
+                                                               int if_cnt = cJSON_GetArraySize(interfaces);
+                                                               node->single[iter].if_cnt = if_cnt;
+                                                               for (int ifiter = 0; ifiter < if_cnt; ifiter++) {
+                                                                       cJSON *interface = cJSON_GetArrayItem(interfaces, ifiter);
+                                                                       node->single[iter].interface_types[ifiter] = things_malloc(sizeof(char *) *strlen(interface->valuestring) + 1);
+                                                                       memcpy(node->single[iter].interface_types[ifiter], interface->valuestring, strlen(interface->valuestring) + 1);
+                                                               }
+                                                       } else {
+                                                               return 0;
+                                                       }
+                                                       cJSON *policy = cJSON_GetObjectItem(res, KEY_DEVICE_RESOURCE_POLICY);
+                                                       if (policy) {
+                                                               node->single[iter].policy = policy->valueint;
+                                                       } else {
+                                                               return 0;
+                                                       }
+
+                                               }
+                                       }
+
+                                       /***** register additional resource(provisininginfo / accesspointlist) *****/
+                                       int resCnt = sizeof(gstResources) / sizeof(things_resource_info_s);
+                                       for (int itr = 0; itr < resCnt; itr++) {
+                                               memcpy(node->single[node->sig_cnt].uri, gstResources[itr].uri, strlen(gstResources[itr].uri) + 1);
+                                               int type_cnt = gstResources[itr].rt_cnt;
+                                               node->single[node->sig_cnt].rt_cnt = type_cnt;
+                                               for (int typeiter = 0; typeiter < type_cnt; typeiter++) {
+                                                       node->single[node->sig_cnt].resource_types[typeiter] = gstResources[itr].resource_types[typeiter];
+                                               }
+
+                                               int if_cnt = gstResources[itr].if_cnt;
+                                               node->single[node->sig_cnt].if_cnt = if_cnt;
+                                               for (int ifiter = 0; ifiter < if_cnt; ifiter++) {
+                                                       node->single[node->sig_cnt].interface_types[ifiter] = gstResources[itr].interface_types[ifiter];
+                                               }
+                                               node->single[node->sig_cnt].policy = gstResources[itr].policy;
+                                               node->sig_cnt++;
+                                       }
+
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "Resources for Single Usage Cnt : %d", node->sig_cnt);
+                               } else {
+                                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Single Reosurces Not Exist");
+                               }
+                       } else {
+                               THINGS_LOG_D(THINGS_INFO, TAG, "Reosurces Not Exist");
+                               ret = 0;
+                       }
+                       hashmap_insert(g_device_hmap, node, (unsigned long)device_num);
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] ============================================");
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] Total Device Num : %d", (int)hashmap_count(g_device_hmap));
+
+               // for resourceType
+               struct st_resource_type_s *restype = NULL;
+               cJSON *resource_types = cJSON_GetObjectItem(root, KEY_RESOURCES_TYPE);
+               resource_type_cnt = cJSON_GetArraySize(resource_types);
+               g_resource_type_hmap = hashmap_create(resource_type_cnt);
+
+               THINGS_LOG_D(THINGS_INFO, TAG, "Resource Types Cnt : %d", resource_type_cnt);
+               for (int i = 0; i < resource_type_cnt; i++) {
+                       int index = 0;
+
+                       restype = create_resource_type();
+
+                       cJSON *cj_rt = cJSON_GetArrayItem(resource_types, i);
+                       cJSON *rtype = cJSON_GetObjectItem(cj_rt, KEY_DEVICE_RESOURCETYPE_TYPE);
+                       cJSON *properties = cJSON_GetObjectItem(cj_rt, KEY_DEVICE_RESOURCETYPE_PROPERTIES);
+
+                       if (NULL != rtype) {
+                               index = hashmap_get_hashval((unsigned char *)rtype->valuestring);
+                               memcpy(restype->rt, rtype->valuestring, strlen(rtype->valuestring) + 1);
+
+                               if (NULL != properties) {
+                                       restype->prop_cnt = cJSON_GetArraySize(properties);
+
+                                       for (int iter2 = 0; iter2 < (restype->prop_cnt); iter2++) {
+                                               cJSON *attr = cJSON_GetArrayItem(properties, iter2);
+                                               cJSON *key = cJSON_GetObjectItem(attr, KEY_DEVICE_RESOURCETYPE_PROPERTIES_KEY);
+                                               cJSON *type = cJSON_GetObjectItem(attr, KEY_DEVICE_RESOURCETYPE_PROPERTIES_TYPE);
+                                               cJSON *mandatory = cJSON_GetObjectItem(attr, KEY_DEVICE_RESOURCETYPE_PROPERTIES_MANDATORY);
+                                               cJSON *rw = cJSON_GetObjectItem(attr, KEY_DEVICE_RESOURCETYPE_PROPERTIES_RW);
+                                               restype->prop[iter2] = create_property();
+                                               if (key->valuestring != NULL) {
+                                                       memcpy(restype->prop[iter2]->key, key->valuestring, strlen(key->valuestring) + 1);
+                                               }
+                                               if (type->valueint != NULL) {
+                                                       restype->prop[iter2]->type = type->valueint;
+                                               }
+
+                                               if (mandatory->type == cJSON_True) {
+                                                       restype->prop[iter2]->mandatory = true;
+                                               } else {
+                                                       restype->prop[iter2]->mandatory = false;
+                                               }
+
+                                               restype->prop[iter2]->rw = rw->valueint;
+                                       }
+                               } else {
+                                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Not Attribute Exist~!!!! ");
+                               }
+                               hashmap_insert(g_resource_type_hmap, restype, index);
+                       }
+               }
+
+               /***** register additional resourcetype(provisininginfo / accesspointlist) *****/
+               int res_type_cnt = sizeof(gst_resource_types) / sizeof(st_resource_type_s);
+               for (int rtItr = 0; rtItr < res_type_cnt; rtItr++) {
+                       int idx = hashmap_get_hashval((unsigned char *)gst_resource_types[rtItr].rt);
+                       hashmap_insert(g_resource_type_hmap, &gst_resource_types[rtItr], idx);
+                       resource_type_cnt++;
+               }
+
+               //for configuration
+               cJSON *configuration = cJSON_GetObjectItem(root, KEY_CONFIGURATION);
+               if (NULL != configuration) {
+                       int connectivity_type = 0;
+
+                       cJSON *easysetup = cJSON_GetObjectItem(configuration, KEY_CONFIGURATION_EASYSETUP);
+                       if (NULL != easysetup) {
+                               cJSON *connectivity = cJSON_GetObjectItem(easysetup, KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY);
+                               if (NULL != connectivity) {
+                                       cJSON *type = cJSON_GetObjectItem(connectivity, KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_TYPE);
+                                       connectivity_type = type->valueint;
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[configuration] type       : %d", connectivity_type);
+                                       if (connectivity_type == 1) {
+                                               es_conn_type = es_conn_type_softap;
+                                               cJSON *softap = cJSON_GetObjectItem(connectivity, KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP);
+                                               if (NULL != softap) {
+                                                       cJSON *manufature_id = cJSON_GetObjectItem(softap, KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP_MANUFACTUREID);
+                                                       cJSON *setup_id = cJSON_GetObjectItem(softap, KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP_SETUPID);
+                                                       cJSON *artik = cJSON_GetObjectItem(softap, KEY_CONFIGURATION_EASYSETUP_CONNECTIVITY_SOFTAP_ARTIK);
+
+                                                       if (NULL != manufature_id && NULL != setup_id) {
+                                                               bool is_artik = false;
+                                                               if (artik->type == cJSON_True) {
+                                                                       is_artik = true;
+                                                               } else {
+                                                                       is_artik = false;
+                                                               }
+
+                                                               THINGS_LOG_D(THINGS_INFO, TAG, "[configuration] manufature_id : %s / setup_id : %s / artik : %d", manufature_id->valuestring, setup_id->valuestring, is_artik);
+
+                                                               g_manufacturer_name = things_malloc(sizeof(char *) *strlen(manufature_id->valuestring) + 1);
+                                                               strncpy(g_manufacturer_name, manufature_id->valuestring, strlen(manufature_id->valuestring) + 1);
+
+                                                               g_setup_id = things_malloc(sizeof(char *) *strlen(setup_id->valuestring) + 1);
+                                                               strncpy(g_setup_id, setup_id->valuestring, strlen(setup_id->valuestring) + 1);
+                                                       } else {
+                                                               return 0;
+                                                       }
+                                               }
+                                       } else if (connectivity_type == 2) {
+                                               //TO DO
+                                               es_conn_type = es_conn_type_ble;
+                                       } else {
+                                               return 0;
+                                       }
+                               } else {
+                                       return 0;
+                               }
+
+                               cJSON *ownership_transfer_method = cJSON_GetObjectItem(easysetup, KEY_CONFIGURATION_EASYSETUP_OWNERSHIP);
+                               if (NULL != ownership_transfer_method) {
+                                       g_ownership_transfer_method = ownership_transfer_method->valueint;
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[configuration] ownership_transfer_method : %d", g_ownership_transfer_method);
+                               } else {
+                                       return 0;
+                               }
+
+                       }
+                       cJSON *wifi = cJSON_GetObjectItem(configuration, KEY_CONFIGURATION_WIFI);
+                       if (NULL != wifi) {
+                               cJSON *wifi_interfaces = cJSON_GetObjectItem(wifi, KEY_CONFIGURATION_WIFI_INTERFACES);
+                               cJSON *wifi_frequency = cJSON_GetObjectItem(wifi, KEY_CONFIGURATION_WIFI_FREQUENCY);
+                               if (NULL != wifi_interfaces && NULL != wifi_frequency) {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[configuration] wifi_interfaces : %d / wifi_frequency : %d", wifi_interfaces->valueint, wifi_frequency->valueint);
+                                       g_wifi_interface = wifi_interfaces->valueint;
+
+                                       if (wifi_frequency->valueint == 1) {
+                                               g_wifi_freq = WiFi_24G;
+                                       } else if (wifi_frequency->valueint == 2) {
+                                               g_wifi_freq = WiFi_5G;
+                                       } else if (wifi_frequency->valueint == 3) {
+                                               g_wifi_freq = WiFi_BOTH;
+                                       } else {
+                                               THINGS_LOG_D(THINGS_INFO, TAG, "unknown wifi freq value");
+                                       }
+                               } else {
+                                       return 0;
+                               }
+                       } else {
+                               return 0;
+                       }
+
+                       cJSON *file_path = cJSON_GetObjectItem(configuration, KEY_CONFIGURATION_FILEPATH);
+                       if (NULL != file_path) {
+                               cJSON *svrdb = cJSON_GetObjectItem(file_path, KEY_CONFIGURATION_FILEPATH_SVRDB);
+                               cJSON *provisioning = cJSON_GetObjectItem(file_path, KEY_CONFIGURATION_FILEPATH_PROVISIONING);
+                               cJSON *certificate = cJSON_GetObjectItem(file_path, KEY_CONFIGURATION_FILEPATH_CERTIFICATE);
+                               cJSON *privateKey = cJSON_GetObjectItem(file_path, KEY_CONFIGURATION_FILEPATH_PRIVATEKEY);
+
+                               if (NULL != svrdb && NULL != provisioning && NULL != certificate && NULL != privateKey) {
+                                       memset(g_svrdb_file_path, 0, (size_t) MAX_FILE_PATH_LENGTH);
+                                       memset(g_certificate_file_path, 0, (size_t) MAX_FILE_PATH_LENGTH);
+                                       memset(g_private_key_file_path, 0, (size_t) MAX_FILE_PATH_LENGTH);
+                                       memcpy(g_svrdb_file_path, svrdb->valuestring, strlen(svrdb->valuestring) + 1);
+                                       memcpy(g_certificate_file_path, certificate->valuestring, strlen(certificate->valuestring) + 1);
+                                       memcpy(g_private_key_file_path, privateKey->valuestring, strlen(privateKey->valuestring) + 1);
+                                       memcpy(g_things_cloud_file_path, provisioning->valuestring, strlen(provisioning->valuestring) + 1);
+
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "Security SVR DB file path : %s", g_svrdb_file_path);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[configuration] svrdb : %s / provisioning : %s", svrdb->valuestring, provisioning->valuestring);
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "[configuration] certificate : %s / privateKey : %s", certificate->valuestring, privateKey->valuestring);
+
+                                       ret = 1;
+                               } else {
+                                       return 0;
+                               }
+                       } else {
+                               return 0;
+                       }
+               }
+               if (NULL != root) {
+                       cJSON_Delete(root);
+               }
+
+       }
+
+       if (json_str != NULL) {
+               things_free(json_str);
+       }
+
+       parse_things_cloud_json(g_things_cloud_file_path);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return ret;
+}
+
+static int get_signup_data_from_json(const char *filename, es_cloud_signup_s **cl_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ret = 1;
+       char *json_str = get_json_string_from_file(filename);
+
+       if (json_str != NULL && strlen(json_str) > 0) {
+               // 3. Parse the Json string
+               cJSON *root = cJSON_Parse((const char *)json_str);
+               cJSON *cloud = cJSON_GetObjectItem(root, KEY_CLOUD);
+               if (cloud == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud cJSON is NULL.");
+                       ret = 0;
+               } else if ((ret = load_cloud_signup_data(cloud, cl_data)) != 1) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Load Cloud SignUp Data Failed.");
+               }
+
+               cJSON_Delete(root);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud file Reading is failed.");
+               ret = 0;
+       }
+
+       if (json_str != NULL) {
+               things_free(json_str);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return ret;
+}
+
+int save_acces_point_info(wifi_manager_ap_config_s *connect_config)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, THINGS_FUNC_ENTRY);
+
+       char *filename = g_things_cloud_file_path;
+
+       int ret = 0;
+       cJSON *root = NULL;
+       char *json_update = NULL;
+       char *json_str = get_json_string_from_file(filename);
+
+       if (json_str != NULL && strlen(json_str) > 0) {
+               root = cJSON_Parse((const char *)json_str);
+
+               cJSON *wifi = cJSON_GetObjectItem(root, KEY_WIFI);
+               if (wifi == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud cJSON is NULL.");
+                       goto GOTO_OUT;
+               }
+
+               cJSON_DeleteItemFromObject(wifi, KEY_WIFI_SSID);
+               cJSON_DeleteItemFromObject(wifi, KEY_WIFI_PASSPHARASE);
+               cJSON_DeleteItemFromObject(wifi, KEY_WIFI_AUTH_TYPE);
+               cJSON_DeleteItemFromObject(wifi, KEY_WIFI_CRYPTO_TYPE);
+
+               if (strlen(connect_config->ssid) > 0) {
+                       cJSON_AddStringToObject(wifi, KEY_WIFI_SSID, connect_config->ssid);
+               }
+               if (strlen(connect_config->passphrase) > 0) {
+                       cJSON_AddStringToObject(wifi, KEY_WIFI_PASSPHARASE, connect_config->passphrase);
+               }
+               cJSON_AddNumberToObject(wifi, KEY_WIFI_AUTH_TYPE, connect_config->ap_auth_type);
+               cJSON_AddNumberToObject(wifi, KEY_WIFI_CRYPTO_TYPE, connect_config->ap_crypto_type);
+
+               json_update = cJSON_Print(root);
+
+               if (set_json_string_into_file(filename, json_update) == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Fail : Store data to info file.");
+                       goto GOTO_OUT;
+               }
+
+               ret = 1;
+       }                                                       // End of if
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "Update Success in \"%s\" file.", filename);
+
+GOTO_OUT:
+       if (root) {
+               cJSON_Delete(root);
+               root = NULL;
+       }
+
+       if (json_str != NULL) {
+               things_free(json_str);
+       }
+
+       if (json_update != NULL) {
+               things_free(json_update);
+       }
+
+       THINGS_LOG_D(THINGS_INFO, TAG, THINGS_FUNC_EXIT);
+       return ret;
+}
+
+static int update_things_cloud_json_by_cloud_signup(const char *filename, es_cloud_signup_s *cl_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ret = 0;
+       cJSON *root = NULL;
+       char *json_update = NULL;
+       char *json_str = get_json_string_from_file(filename);
+
+       if (json_str != NULL && strlen(json_str) > 0) {
+               // 3. Parse the Json string
+               root = cJSON_Parse((const char *)json_str);
+
+               // Cloud Items
+               cJSON *cloud = cJSON_GetObjectItem(root, KEY_CLOUD);
+               if (cloud == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud cJSON is NULL.");
+                       goto GOTO_OUT;
+               }
+
+               if (cl_data != NULL) {
+                       cJSON_DeleteItemFromObject(cloud, KEY_CLOUD_ADDRESS);
+               }
+               cJSON_DeleteItemFromObject(cloud, KEY_CLOUD_DOMAIN);
+               cJSON_DeleteItemFromObject(cloud, KEY_CLOUD_PORT);
+               cJSON_DeleteItemFromObject(cloud, KEY_TOKEN_ACCESS);
+               cJSON_DeleteItemFromObject(cloud, KEY_TOKEN_ACCESS_REFRESH);
+               cJSON_DeleteItemFromObject(cloud, KEY_TOKEN_TYPE);
+               cJSON_DeleteItemFromObject(cloud, KEY_EXPIRE_TIME);
+               cJSON_DeleteItemFromObject(cloud, KEY_ID_USER);
+               cJSON_DeleteItemFromObject(cloud, KEY_SERVER_REDIRECT_URI);
+               cJSON_DeleteItemFromObject(cloud, KEY_CERTIFICATE_FILE);
+               cJSON_DeleteItemFromObject(cloud, KEY_SERVER_ID);
+
+               memset(g_cloud_address, 0, MAX_CLOUD_ADDRESS);
+               if (cl_data != NULL) {
+                       if (things_strcat(g_cloud_address, MAX_CLOUD_ADDRESS, cl_data->address) == NULL) {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Fail : Copy to g_cloud_address.");
+                               goto GOTO_OUT;
+                       }
+                       if (cl_data->domain != NULL && strlen(cl_data->domain) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_CLOUD_DOMAIN, cl_data->domain);
+                       }
+                       if (cl_data->address != NULL && strlen(cl_data->address) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_CLOUD_ADDRESS, cl_data->address);
+                       }
+                       if (cl_data->port != NULL && strlen(cl_data->port) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_CLOUD_PORT, cl_data->port);
+                       }
+                       if (cl_data->access_token != NULL && strlen(cl_data->access_token) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_TOKEN_ACCESS, cl_data->access_token);
+                       }
+                       if (cl_data->refresh_token != NULL && strlen(cl_data->refresh_token) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_TOKEN_ACCESS_REFRESH, cl_data->refresh_token);
+                       }
+                       if (cl_data->token_type != NULL && strlen(cl_data->token_type) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_TOKEN_TYPE, cl_data->token_type);
+                       }
+                       if (cl_data->expire_time != CLOUD_EXPIRESIN_INVALID) {
+                               cJSON_AddNumberToObject(cloud, KEY_EXPIRE_TIME, cl_data->expire_time);
+                       }
+                       if (cl_data->uid != NULL && strlen(cl_data->uid) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_ID_USER, cl_data->uid);
+                       }
+                       if (cl_data->redirect_uri != NULL && strlen(cl_data->redirect_uri) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_SERVER_REDIRECT_URI, cl_data->redirect_uri);
+                       }
+                       if (cl_data->certificate != NULL && strlen(cl_data->certificate) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_CERTIFICATE_FILE, cl_data->certificate);
+                       }
+                       if (cl_data->sid != NULL && strlen(cl_data->sid) > 0) {
+                               cJSON_AddStringToObject(cloud, KEY_SERVER_ID, cl_data->sid);
+                       }
+               }
+
+               json_update = cJSON_Print(root);
+
+               if (set_json_string_into_file(filename, json_update) == 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Fail : Store data to info file.");
+                       goto GOTO_OUT;
+               }
+
+               ret = 1;
+       }                                                       // End of if
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Update Success in \"%s\" file.", filename);
+
+GOTO_OUT:
+       if (root) {
+               cJSON_Delete(root);
+               root = NULL;
+       }
+
+       if (json_str != NULL) {
+               things_free(json_str);
+       }
+
+       if (json_update != NULL) {
+               things_free(json_update);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return ret;
+}
+
+static int Parse_things_files(const char *info_Path)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       int res = 1;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "orginal info file path = %s", info_Path);
+       if (!parse_things_info_json(info_Path)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Info file parsing Failed");
+               res = 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return res;
+}
+
+int dm_load_legacy_cloud_data(es_cloud_signup_s **cl_data)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int ret = 1;
+
+       if (g_things_cloud_file_path[0] == 0 || cl_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Provisioning file path is NULL.(%s) or Invalid argument.(0x%X)", g_things_cloud_file_path, cl_data);
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "g_things_cloud_file_path = %s", g_things_cloud_file_path);
+
+       if ((ret = get_signup_data_from_json(g_things_cloud_file_path, cl_data)) != 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not Get sign-up data failed from Provisioning file.");
+       }
+
+       usleep(500000);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return ret;
+}
+
+const char *dm_get_things_device_type(int device_id)
+{
+       //THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       st_device_s *device = NULL;
+
+       device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)device_id);
+       if (device == NULL) {
+
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Device Not Exist");
+               return NULL;
+       }
+
+       return device->type;
+}
+
+const char *dm_get_svrdb_file_path(void)
+{
+       return g_svrdb_file_path;
+}
+
+const char *dm_get_certificate_file_path(void)
+{
+       return g_certificate_file_path;
+}
+
+const char *dm_get_privatekey_file_path(void)
+{
+       return g_private_key_file_path;
+}
+
+const char *dm_get_things_cloud_address(char *customized_ci_server)
+{
+       if (customized_ci_server && customized_ci_server[0] != 0) {
+               return customized_ci_server;
+       }
+       return get_cloud_server_address(customized_ci_server);
+}
+
+bool dm_is_rsc_published(void)
+{
+       return (es_get_state() == ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD ? true : false);
+}
+
+static things_resource_s *register_resource(things_server_builder_s *p_builder, struct things_resource_info_s *resource, const char *id)
+{
+       things_resource_s *ret = NULL;
+       char res_uri[MAX_URI_LENGTH] = { 0 };
+
+       if (NULL != resource) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "RESOURCE TO REGISTER : %s", resource->uri);
+
+               memset(res_uri, 0, (size_t) MAX_URI_LENGTH);
+               /*SVACE warning fix */
+               strncat(res_uri, resource->uri, MAX_URI_LENGTH);
+
+               ret = p_builder->create_resource(p_builder, res_uri, resource->resource_types[0], resource->interface_types[0], CHECK_DISCOVERABLE(resource->policy), CHECK_OBSERVABLE(resource->policy), CHECK_SECURE(resource->policy));
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "add_resource_type : %s", resource->resource_types[0]);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "add_interface_type : %s", resource->interface_types[0]);
+               for (int rt_num = 1; rt_num < resource->rt_cnt; rt_num++) {
+                       p_builder->add_resource_type(ret, resource->resource_types[rt_num]);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "add_resource_type : %s", resource->resource_types[rt_num]);
+               }
+
+               for (int it_num = 1; it_num < resource->if_cnt; it_num++) {
+                       p_builder->add_interface_type(ret, resource->interface_types[it_num]);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "add_interface_type : %s", resource->interface_types[it_num]);
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Input Param ");
+       }
+
+       return ret;
+}
+
+static things_resource_s *register_device_resource(things_server_builder_s *p_builder, st_device_s *device, const char *id)
+{
+       things_resource_s *ret = NULL;
+       char res_uri[MAX_URI_LENGTH] = { 0 };
+
+       if (NULL != device) {
+               memset(res_uri, 0, (size_t) MAX_URI_LENGTH);
+               strncat(res_uri, OC_RSRVD_DEVICE_URI, MAX_URI_LENGTH);
+
+               ret = p_builder->create_resource(p_builder, res_uri, OC_RSRVD_RESOURCE_TYPE_DEVICE, OC_RSRVD_INTERFACE_READ, 0, 0, 1);
+
+               p_builder->add_resource_type(ret, device->type);
+
+               ret->rep = things_create_representation_inst(NULL);
+               if (ret->rep) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/d] name :%s", device->name);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/d] type :%s", device->type);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_DEVICE_NAME, device->name);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_DEVICE_ID, device->device_id);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_SPEC_VERSION, OC_SPEC_VERSION);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_DATA_MODEL_VERSION, OC_DATA_MODEL_VERSION);
+               } else {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not able to create representation");
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Input Param ");
+       }
+
+       return ret;
+}
+
+static things_resource_s *register_platform_resource(things_server_builder_s *p_builder, st_device_s *device, const char *id)
+{
+       things_resource_s *ret = NULL;
+       char res_uri[MAX_URI_LENGTH] = { 0 };
+
+       if (NULL != device) {
+               memset(res_uri, 0, (size_t) MAX_URI_LENGTH);
+               strncat(res_uri, OC_RSRVD_PLATFORM_URI, MAX_URI_LENGTH);
+
+               ret = p_builder->create_resource(p_builder, res_uri, OC_RSRVD_RESOURCE_TYPE_PLATFORM, OC_RSRVD_INTERFACE_READ, 0, 0, 1);
+
+               ret->rep = things_create_representation_inst(NULL);
+               if (ret->rep) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Manufacturer :%s", MANUFACTURER_NAME);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Model Name :%s", device->model_num);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. Plaform :%s", device->ver_p);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. OS :%s", device->ver_os);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. HW :%s", device->ver_hw);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. FW :%s", device->ver_fw);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. vid :%s", device->vender_id);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_PLATFORM_ID, device->device_id);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_MFG_NAME, MANUFACTURER_NAME);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_MODEL_NUM, device->model_num);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_PLATFORM_VERSION, device->ver_p);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_OS_VERSION, device->ver_os);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_HARDWARE_VERSION, device->ver_hw);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_FIRMWARE_VERSION, device->ver_fw);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_MFG_URL, MANUFACTURER_URL);
+
+                       ret->rep->things_set_value(ret->rep, OC_RSRVD_VID, device->vender_id);
+               } else {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not able to create representation");
+               }
+
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Input Param ");
+       }
+
+       return ret;
+}
+
+long dm_get_num_of_dev_cnt(void)
+{
+       return hashmap_count(g_device_hmap);
+}
+
+st_device_s *dm_get_info_of_dev(unsigned long number)
+{
+       return (st_device_s *) hashmap_get(g_device_hmap, number);
+}
+
+bool dm_register_user_define_device_id(const int seq_thing_info, const char *dev_id)
+{
+       if (is_support_user_def_dev_list == false) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "No More Support User define Device ID.");
+               return false;
+       }
+
+       if (seq_thing_info < 1 || seq_thing_info > MAX_SUBDEVICE_EA || dev_id == NULL || strlen(dev_id) == 0) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "It Support Max %d EA for device ID", MAX_SUBDEVICE_EA);
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(seq_thing_info=%d, dev_id=0x%X)", seq_thing_info, dev_id);
+               return false;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "seq_thing_info=%d, dev_id=%s", seq_thing_info, dev_id);
+
+       if (strlen(dev_id) >= MAX_DEVICE_ID_LENGTH) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Overflow device ID length.(It Support Max length: %d)", MAX_DEVICE_ID_LENGTH);
+               return false;
+       }
+       user_def_dev_list[seq_thing_info] = strdup(dev_id);
+
+       return true;
+}
+
+static void dm_delete_user_define_device_id(void)
+{
+       int i = 0;
+
+       for (i = 0; i < MAX_SUBDEVICE_EA; i++) {
+               things_free(user_def_dev_list[i]);
+               user_def_dev_list[i] = NULL;
+       }
+}
+
+bool dm_register_device_id(void)
+{
+       int i = 0;
+       char *id = NULL;
+       st_device_s **dev_list = NULL;
+       int device_cnt = (int)hashmap_count(g_device_hmap);
+       if (device_cnt < 1) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "No Device Information to Register");
+               return false;
+       }
+
+       if ((dev_list = (st_device_s **) things_malloc(sizeof(st_device_s *) *device_cnt)) == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "st_device_s mem allocation is failed.");
+               return false;
+       }
+       // Set Main-Device ID
+       id = OCGetServerInstanceIDString();
+       dev_list[0] = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)0);
+
+       if (id == NULL || dev_list[0] == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Error : id = %s, Main-device =0x%X", id, dev_list[0]);
+               goto GOTO_ERROR;
+       }
+       memcpy(dev_list[0]->device_id, id, strlen(id) + 1);
+
+       // Set Sub-Device ID
+       for (i = 1; i < device_cnt; i++) {
+               dev_list[i] = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)i);
+               if (dev_list[i] == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Error : device[%d] =0x%X", i, dev_list[i]);
+                       goto GOTO_ERROR;
+               }
+
+               if (user_def_dev_list[i] != NULL || strlen(dev_list[i]->device_id) == 0) {
+                       // a. If logical device is in a hosting(physical) device.
+                       if (dev_list[i]->is_physical == 1) {
+                               OCRandomUuidResult idGenRet = RAND_UUID_CONVERT_ERROR;
+
+                               if (user_def_dev_list[i]) {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Set Sub-device ID with user-defined device ID.");
+                                       memcpy(dev_list[i]->device_id, user_def_dev_list[i], strlen(user_def_dev_list[i]) + 1);
+                                       idGenRet = RAND_UUID_OK;
+                               } else {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Set Sub-device ID with Auto-Generated device ID.");
+                                       idGenRet = OCGenerateUuidString(dev_list[i]->device_id);
+                               }
+
+                               if (idGenRet != RAND_UUID_OK) {
+                                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "[DEVICE] Device ID Creation Failed : %d", idGenRet);
+                               } else {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[DEVICE] ID Created : %s", (dev_list[i]->device_id));
+                               }
+                       }
+                       // b. If logical device is in the other physical device
+                       else {
+                               THINGS_LOG_D(THINGS_INFO, TAG, "[DEVICE] Not Physically Separated Device ");
+                       }
+               }
+       }
+
+       is_support_user_def_dev_list = false;   //  It's allow permission to apply user defined device-ID only when start THINGS_STACK.
+
+       dm_delete_user_define_device_id();
+       things_free(dev_list);
+       dev_list = NULL;
+       return true;
+
+GOTO_ERROR:
+       things_free(dev_list);
+       dev_list = NULL;
+       return false;
+}
+
+int dm_register_resource(things_server_builder_s *p_builder)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (p_builder == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Builder instance is NULL");
+
+               return 0;
+       }
+
+       int device_cnt = (int)hashmap_count(g_device_hmap);
+       if (device_cnt < 1) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "No Device Information to Register");
+
+               return 0;
+       }
+
+       for (int device_num = 0; device_num < device_cnt; device_num++) {
+               char id[11] = { 0 };
+               char res_uri[MAX_URI_LENGTH] = { 0 };
+               int key = 0;
+               int n_count_of_children = 0;
+
+               st_device_s *device = NULL;
+               struct things_resource_info_s *resource = NULL;
+               struct col_resource_s *col_resource_s = NULL;
+               struct things_resource_s *p_collection_resource = NULL;
+
+               // 2. Device Capability Resources Registration
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "BEFORE SEARCHING THE DEVICE  ITEM FROM HASH TABLE");
+
+               device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)device_num);
+
+               if (NULL != device) {
+                       /*SVACE warning fix */
+                       snprintf(id, sizeof(id), "%d", device->no);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "==================== Device (%s) ====================", id);
+
+                       if (device->col_cnt < 1) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "NO COLLECTION & ITS CHILDREN RESOURCE(S)");
+                       } else {
+                               THINGS_LOG_D(THINGS_INFO, TAG, "COLLECTION CHILDREN RESOURCE(S) CNT : %d", device->col_cnt);
+
+                               memset(res_uri, 0, (size_t) MAX_URI_LENGTH);
+                               strncat(res_uri, device->collection[0].uri, MAX_URI_LENGTH);
+
+                               p_collection_resource = p_builder->create_collection_resource(p_builder, res_uri, device->collection[0].resource_types[0], device->collection[0].interface_types[0]);
+
+                               for (int rt_num = 1; rt_num < device->collection[0].rt_cnt; rt_num++) {
+                                       OCBindResourceTypeToResource(p_builder, device->collection[0].resource_types[rt_num]);
+                               }
+
+                               // THINGS_LOG_D(THINGS_DEBUG, TAG, "IT TO BIND : %d", resource->if_cnt);
+                               for (int it_num = 1; it_num < device->collection[0].if_cnt; it_num++) {
+                                       OCBindResourceInterfaceToResource(p_builder, device->collection[0].interface_types[it_num]);
+                               }
+
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "AFTER REGISTERGING DEVICE RESOURCE");
+
+                               if (p_collection_resource != NULL) {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "DEVICE RESOURCE(S) CNT : %d", device->col_cnt);
+                                       for (int capa_num = 0; capa_num < device->collection[0].link_cnt; capa_num++) {
+                                               resource = device->collection[0].links[capa_num];
+                                               device->pchild_resources[n_count_of_children++] = register_resource(p_builder, resource, id);
+                                       }                       // End of for children resource(s) registration loop
+                               }                               // End of single device
+
+                               p_builder->bind_all(p_collection_resource, device->pchild_resources, n_count_of_children);
+
+                               device->pchild_resources[n_count_of_children++] = p_collection_resource;
+                       }
+
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "SINGLE RESOURCE(S) CNT : %d", device->sig_cnt);
+
+                       for (int capa_num = 0; capa_num < device->sig_cnt; capa_num++) {
+                               resource = &device->single[capa_num];
+                               device->pchild_resources[n_count_of_children++] = register_resource(p_builder, resource, id);
+                       }                                       // End of for single resource registration loop
+
+                       // Create the Device(/oic/d) and Platform (/oic/p)
+                       // ex) Aircon Multi-Model
+                       if (device_num < 1) {
+                               // for hosting device
+                               p_builder->set_device_info(p_builder, device->name, device->type);
+                               p_builder->set_platform_info(p_builder, device->model_num,      // gDeviceModel,
+                                                                                        device->ver_p, // gPlatformVersion,
+                                                                                        device->ver_os,        // gOSVersion,
+                                                                                        device->ver_hw,        // gHWVersions,
+                                                                                        device->ver_fw,        // gFWVersions,
+                                                                                        device->vender_id);    // gVenderId);
+                       } else {
+                               if (device->is_physical == 1) {
+                                       THINGS_LOG_V(THINGS_INFO, TAG, "It's Physically Separated Device : %s", device->device_id);
+                                       // for those physically separated devices
+                                       // a. /oic/d/# resource
+                                       device->pchild_resources[n_count_of_children++] = register_device_resource(p_builder, device, id);
+                                       // b. /oic/p/# resource
+                                       device->pchild_resources[n_count_of_children++] = register_platform_resource(p_builder, device, id);
+                               } else {
+                                       THINGS_LOG_V(THINGS_INFO, TAG, "It's Logical Device in One Physical Device : [%d]", device_num);
+                               }
+                       }
+
+                       // Total Size of the device->pChildresources : col_cnt + sig_cnt + 1(/device) + a(/oic/d & /oic/p)
+                       device->capa_cnt = n_count_of_children;
+               }                                               // End of device NULL Check
+       }                                                       // End of for device loop
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====================================================");
+
+       if (p_builder->broadcast_presence(p_builder, 20) == 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Broadcast Presence Failed.");
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return 1;
+}
+
+struct things_resource_s *dm_get_resource_instance(const char *uri, const int id)
+{
+       things_resource_s *ret = NULL;
+
+       int device_cnt = (int)hashmap_count(g_device_hmap);
+       if (device_cnt > 0 && device_cnt > id) {
+               st_device_s *device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)(id));
+
+               if (device) {
+                       for (int index = 0; index < MAX_DEVICE_CAPABILTY_CNT; index++) {
+                               if (device->pchild_resources[index] == NULL) {
+                                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Resource with URI : %s not exist !!!!", uri);
+                                       break;
+                               } else if (strncmp(device->pchild_resources[index]->uri, uri, strlen(uri)) == 0) {
+                                       THINGS_LOG_V(THINGS_DEBUG, TAG, "Found %s from device[%d] : %s!!!!", uri, id, device->device_id);
+
+                                       char *sValue = NULL;
+
+                                       device->pchild_resources[index]->rep->things_get_value(device->pchild_resources[index]->rep, OC_RSRVD_DEVICE_ID, &sValue);
+                                       ret = device->pchild_resources[index];
+                                       break;
+                               } else {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "[%d] Resource URI : %s", index, device->pchild_resources[index]->uri);
+                               }
+                       }
+               }
+       }
+       return ret;
+}
+
+int dm_get_device_information(int *cnt, st_device_s ***list)
+{
+       int ret = 0;
+
+       int device_cnt = (int)hashmap_count(g_device_hmap);
+       if (device_cnt > 0) {
+               st_device_s **devices = NULL;
+               if ((devices = (st_device_s **) things_malloc(sizeof(st_device_s *) *device_cnt)) == NULL) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "st_device_s memory allocation is failed.");
+                       return ret;
+               }
+
+               for (int index = 0; index < device_cnt; index++) {
+                       devices[index] = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)index);
+               }
+
+               (*list) = devices;
+               (*cnt) = device_cnt;
+               ret = 1;
+       }
+
+       return ret;
+}
+
+const int dm_get_num_of_children(int device_num)
+{
+       int ret = 0;
+
+       st_device_s *device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)device_num);
+       if (NULL != device) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "DEVICE CHILDREN RESOURCE(S) : %d", device->col_cnt);
+               ret = device->col_cnt;
+       }
+
+       return ret;
+}
+
+const char *dm_get_resource_uri(int device_num, int index)
+{
+       st_device_s *device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)device_num);
+       if (NULL != device) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "DEVICE CHILDREN RESOURCE(S) : %d", device->col_cnt);
+               if ((index) >= device->col_cnt) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Index : %d", index);
+               } else {
+
+                       return device->collection[0].links[index]->uri;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Device Num to Search : %d", device_num);
+       }
+
+       return NULL;
+}
+
+int dm_update_device_iInfo_list(st_device_s **dev_list, int devCnt)
+{
+       int ret = 1;
+       update_and_save_device_info(dev_list, devCnt);
+       return ret;
+}
+
+int dm_update_things_cloud(es_cloud_signup_s *cl_data)
+{
+       int ret = 1;
+
+       THINGS_LOG_V(THINGS_INFO, TAG, "RTOS Recived Signup Data domain[%s], address[%s], port [%s],  access_token[%s],  refresh_token[%s], token_type[%s],  " "uid[%s]", cl_data->domain, cl_data->address, cl_data->port, cl_data->access_token, cl_data->refresh_token, cl_data->token_type, cl_data->uid);
+       THINGS_LOG_V(THINGS_INFO, TAG, "RTOS Recived Signup Data redirect_uri[%s],  certificate[%s], sid[%s]", cl_data->redirect_uri, cl_data->certificate, cl_data->sid);
+
+       if (g_things_cloud_file_path[0] == 0 || cl_data == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud file path is NULL(%s). or Invalid argument.(0x%X)", g_things_cloud_file_path, cl_data);
+               ret = 0;
+               return ret;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "g_things_cloud_file_path = %s", g_things_cloud_file_path);
+
+       if (update_things_cloud_json_by_cloud_signup(g_things_cloud_file_path, cl_data) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Provisioning file update failed.");
+               ret = 0;
+       }
+
+       if (ret == 1) {
+               int res = 0;
+               es_cloud_signup_s *confirmData = NULL;
+
+               if ((res = dm_load_legacy_cloud_data(&confirmData)) == 1) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Update Success.");
+                       is_there_cloud_data = true;
+                       es_cloud_signup_clear(confirmData);
+                       confirmData = NULL;
+               } else {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Update Failed.(%d)", res);     // 1 : Success , 0/-1 : system error. , -2 : saved invalid Cloud-Data.
+                       is_there_cloud_data = false;
+               }
+       }
+
+       return ret;
+}
+
+int dm_del_things_cloud_data(void)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int ret = 1;
+       if (g_things_cloud_file_path[0] == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "cloud file path is NULL.");
+               ret = 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "g_things_cloud_file_path = %s", g_things_cloud_file_path);
+
+       if (update_things_cloud_json_by_cloud_signup(g_things_cloud_file_path, NULL) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "It's failed to delete Cloud-Data in cloud file.");
+               ret = 0;
+       }
+
+       if (ret == 1) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Delete Success.");
+               is_there_cloud_data = false;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return ret;
+}
+
+bool dm_is_there_things_cloud(void)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "is_there_cloud_data = %d", is_there_cloud_data);
+       return is_there_cloud_data;
+}
+
+int dm_validate_attribute_in_request(char *rt, const void *payload)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       int ret = 0;
+
+       if (rt != NULL && payload != NULL) {
+               // 1. Get index with resource type
+               unsigned long index = hashmap_get_hashval((unsigned char *)rt);
+               OCRepPayload *r_payload = (OCRepPayload *) payload;
+
+               // 2. Get resource type instance
+               THINGS_LOG_D(THINGS_INFO, TAG, "Index : %u  rt : %s", index, rt);
+               struct st_resource_type_s *res_type = (struct st_resource_type_s *)hashmap_get(g_resource_type_hmap, index);
+
+               if (NULL != res_type) {
+                       int iter = 0;
+                       // 3. Get attributes & check
+                       //    POLICY
+                       //    a. Check exsitence of read-only attributes in the payload which should not be..
+                       for (iter = 0; iter < res_type->prop_cnt; iter++) {
+                               if (NULL != res_type->prop[iter]
+                                       && (1 == CHECK_READABLE(res_type->prop[iter]->rw)
+                                               && 1 != CHECK_WRITABLE(res_type->prop[iter]->rw))
+                                  ) {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "\tCHECKING READ-ONLY ATTR : %s", res_type->prop[iter]->key);
+                                       if (!OCRepPayloadIsNull(r_payload, res_type->prop[iter]->key)) {
+                                               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> EXIST");
+                                               goto VALIDATION_EXIT;
+                                       } else {
+                                               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> NOT EXIST");
+                                       }
+                               }
+                       }
+                       //    b. Check existence of rw attribute in the payload which should exist at least 1
+                       for (iter = 0; iter < res_type->prop_cnt; iter++) {
+                               if (NULL != res_type->prop[iter]
+                                       && 1 == CHECK_WRITABLE(res_type->prop[iter]->rw)) {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "\tCHECKING WRITE-ABLE ATTR : %s", res_type->prop[iter]->key);
+                                       if (!OCRepPayloadIsNull(r_payload, res_type->prop[iter]->key)) {
+                                               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> EXIST");
+
+                                               ret = 1;
+                                               break;
+                                       } else {
+                                               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> NOT EXIST");
+                                       }
+                               }
+                       }
+                       //    c. Make it pass if it's collection resource
+                       if (0 == strncmp(rt, OC_RSRVD_RESOURCE_TYPE_COLLECTION, strlen(OC_RSRVD_RESOURCE_TYPE_COLLECTION))
+                               || 0 == strncmp(rt, SEC_RTYPE_THINGS_DEVICE, strlen(SEC_RTYPE_THINGS_DEVICE))) {
+                               // TODO : Need to check whether there an array delivered or not..
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> Child %s", (r_payload->next != NULL ? "EXIST" : "NOT EXIST"));
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> Request On Collection Resource. Making it PASS");
+                               ret = 1;
+                       }
+               } else {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Not Supporting rt : %s", rt);
+               }
+       } else {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid Input - rt : %s, payload %d", rt, payload);
+       }
+
+VALIDATION_EXIT:
+
+       if (ret == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t==> INVALID REQUEST~!!!");
+       }
+       return ret;
+}
+
+int things_get_resource_type(const char *resource_uri, int *count, char ***resource_types)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "things_get_resource_type : %s", resource_uri);
+       int device_cnt = (int)hashmap_count(g_device_hmap);
+       if (device_cnt > 0) {
+               st_device_s *device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)0);
+
+               if (device != NULL) {
+                       if (device->sig_cnt > 0) {
+                               for (int index = 0; index < device->sig_cnt; index++) {
+                                       if (strncmp(device->single[index].uri, resource_uri, strlen(resource_uri)) == 0) {
+                                               (*count) = device->single[index].rt_cnt;
+                                               (*resource_types) = device->single[index].resource_types;
+                                               return 1;
+                                       }
+                               }
+                       }
+                       if (device->col_cnt > 0) {
+                               for (int index = 0; index < device->col_cnt; index++) {
+                                       if (strncmp(device->collection[index].uri, resource_uri, strlen(resource_uri)) == 0) {
+                                               (*count) = device->collection[index].rt_cnt;
+                                               (*resource_types) = device->collection[index].resource_types;
+                                               return 1;
+                                       } else {
+                                               for (int index_links = 0; index_links < device->collection[index].link_cnt; index_links++) {
+                                                       if (strncmp(device->collection[index].links[index_links]->uri, resource_uri, strlen(resource_uri)) == 0) {
+                                                               (*count) = device->collection[index].links[index_links]->rt_cnt;
+                                                               (*resource_types) = device->collection[index].links[index_links]->resource_types;
+                                                               return 1;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+const int dm_get_wifi_property_interface()
+{
+       return g_wifi_interface;
+}
+
+const wifi_freq_e dm_get_wifi_property_freq()
+{
+       return g_wifi_freq;
+}
+
+const int dm_get_ownership_transfer_method()
+{
+       THINGS_LOG_V(THINGS_INFO, TAG, "ownership_transfer_method : %d", g_ownership_transfer_method);
+       return g_ownership_transfer_method;
+}
+
+int things_get_attributes_by_resource_type(const char *res_type, int *count, things_attribute_info_s ***attributes)
+{
+       int resource_type_cnt = (int)hashmap_count(g_resource_type_hmap);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "things_get_attributes_by_resource_type : %s, resource_type_cnt : %d", res_type, resource_type_cnt);
+
+       if (resource_type_cnt > 0) {
+
+               int index = hashmap_get_hashval(res_type);
+               struct st_resource_type_s *res_type = (struct st_resource_type_s *)hashmap_get(g_resource_type_hmap, index);
+               if (res_type == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "res_type Not Exist");
+                       return 0;
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "res_type : %s, res_type : %s", res_type->rt, res_type);
+               if (strncmp(res_type->rt, res_type, strlen(res_type)) == 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "res_type->prop_cnt : %d", res_type->prop_cnt);
+                       (*count) = res_type->prop_cnt;
+                       (*attributes) = res_type->prop;
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+bool things_is_collection_resource(const char *res_uri)
+{
+       int device_cnt = (int)hashmap_count(g_device_hmap);
+       if (device_cnt > 0) {
+               st_device_s *device = NULL;
+
+               device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)0);
+               if (device == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Device Not Exist");
+                       return NULL;
+               }
+
+               if (device->col_cnt > 0) {
+                       for (int index = 0; index < device->col_cnt; index++) {
+                               if (strncmp(device->collection[index].uri, res_uri, strlen(res_uri)) == 0) {
+                                       return true;
+                               }
+                       }
+               }
+       }
+       return false;
+}
+
+int things_get_child_resources(const char *col_res_uri, int *count, things_resource_info_s ***child_resources)
+{
+       st_device_s *device = NULL;
+
+       device = (st_device_s *) hashmap_get(g_device_hmap, (unsigned long)0);
+       if (device == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Device Not Exist");
+               return NULL;
+       }
+
+       if (device->col_cnt > 0) {
+               for (int index = 0; index < device->col_cnt; index++) {
+                       if (strncmp(device->collection[index].uri, col_res_uri, strlen(col_res_uri)) == 0) {
+                               (*count) = device->collection[index].link_cnt;
+                               (*child_resources) = device->collection[index].links;
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+int dm_init_module(const char *devJsonPath)
+{
+       if (devJsonPath == NULL) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "devJsonPath is NULL");
+               return 0;
+       }
+
+       memset(g_svrdb_file_path, 0, (size_t) MAX_FILE_PATH_LENGTH);
+       memset(g_things_cloud_file_path, 0, (size_t) MAX_FILE_PATH_LENGTH);
+       memset(g_cloud_address, 0, (size_t) MAX_CLOUD_ADDRESS);
+
+       return Parse_things_files(devJsonPath);
+}
+
+//
+
+int dm_termiate_module()
+{
+       //  Need to backup all the keys in order to delete from the map.
+       hashmap_delete(g_device_hmap);
+       hashmap_delete(g_resource_type_hmap);
+       return 1;
+}
diff --git a/framework/src/st_things/things_stack/src/common/framework/things_req_handler.c b/framework/src/st_things/things_stack/src/common/framework/things_req_handler.c
new file mode 100644 (file)
index 0000000..b12583f
--- /dev/null
@@ -0,0 +1,1189 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#define _BSD_SOURCE                            // for the usleep
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include "ocpayload.h"
+
+#include "things_def.h"
+#include "things_common.h"
+#include "things_queue.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "cacommon.h"
+#include "things_string_util.h"
+#include "things_resource.h"
+#include "../utils/inc/things_network.h"
+#include "things_api.h"
+#include "things_types.h"
+#include "things_server_builder.h"
+#include "things_data_manager.h"
+
+#include "things_req_handler.h"
+#include "things_hashmap.h"
+
+#include "things_thread.h"
+#ifdef __ST_THINGS_RTOS__
+#include "ctype.h"
+#include "things_rtos_util.h"
+#endif
+
+#define TAG "[things_reqhdlr]"
+
+static handle_request_func_type g_handle_request_get_cb = NULL;
+static handle_request_func_type g_handle_request_set_cb = NULL;
+
+extern things_server_builder_s *g_builder;
+
+static queue_s *gp_oic_req_queue;
+static int g_handle_res_cnt = 0;
+static char **g_handle_res_list = NULL;
+static handle_request_func_type g_handle_req_cb = NULL;
+static get_notify_obs_uri_cb g_get_notify_obs_uri = NULL;
+
+static handle_request_interface_cb g_handle_request_interface_cb = NULL;
+
+static stop_softap_func_type g_stop_soft_ap_cb = NULL;
+
+static pthread_t g_req_handle;
+
+static int g_quit_flag = 0;
+
+OCEntityHandlerResult things_abort(pthread_t *h_thread_abort, things_es_enrollee_abort_e level);
+
+/**
+ * Return : 0 (Invalid Request), 1 (Resource Supporting Interface)
+ * Need refactoring later...
+ */
+static int verify_request(OCEntityHandlerRequest *eh_request, const char *uri, int req_type)
+{
+       int result = 0;
+
+       if (g_builder == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Server Builder is not registered..");
+               goto EXIT_VALIDATION;
+       }
+
+       things_resource_s *resource = things_create_resource_inst(eh_request->requestHandle,
+                                                                 eh_request->resource,
+                                                                 eh_request->query,
+                                                                 eh_request->payload); //g_builder->get_resource(g_builder, uri);
+       things_resource_s *child = NULL;
+       /*! Added by st_things for memory Leak fix
+        */
+       things_resource_s *pst_temp_resource = resource;
+       if (resource == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Resource Not found : %s ", uri);
+               goto EXIT_VALIDATION;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Query in the Request : %s", eh_request->query);
+
+       //  Verify received request in valid or not..
+       // 1. If there's no interface type in the request ..
+       if ((strstr(eh_request->query, "if=") == NULL)
+               || (strstr(eh_request->query, OIC_INTERFACE_BASELINE) != NULL)
+               || (true == resource->things_is_supporting_interface_type(resource, eh_request->query))) {
+               result = 1;
+       }
+       // 2. If request type == POST(OC_REST_POST == 4),
+       //    then validate the attributes kyes in the request
+       if (result == 1 && req_type == OC_REST_POST) {
+               //  Reseting the result value to apply
+               // the result of additional verification
+               result = 0;
+
+               // if(gValidator == NULL )
+               // {s
+               //     THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Validator not registered");
+               //     goto EXIT_VALIDATION;
+               // }
+
+               //  If the given resource does not have sensor nor read interface type..
+               if (!(resource->things_is_supporting_interface_type(resource, OIC_INTERFACE_SENSOR))
+                       && !(resource->things_is_supporting_interface_type(resource, OC_RSRVD_INTERFACE_READ))) {
+                       //  If no query or..
+                       //       query with "supporting interface types"  then...
+                       if ((strstr(eh_request->query, "if=") == NULL)
+                               || ((strstr(eh_request->query, "if=") != NULL)
+                                       && (resource->things_is_supporting_interface_type(resource, eh_request->query))
+                                  )
+                          ) {
+                               //  Verify request(Attributes.) with Validator func implemented
+                               const int num = resource->things_get_num_of_res_types(resource);
+
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "# of RT :%d", num);
+
+                               if (resource->size > 1) {
+                                       // Remove "rep" wrapper
+                                       things_resource_s *res = resource;
+                                       things_representation_s *tRep = NULL;
+                                       things_representation_s *tchild_rep = NULL;
+
+                                       for (int iter = 0; iter < resource->size; ++iter) {
+                                               tchild_rep = things_create_representation_inst(NULL);
+                                               res->things_get_representation(res, &tRep);
+                                               tRep->things_get_object_value(tRep, OC_RSRVD_REPRESENTATION, tchild_rep);
+                                               res->things_set_representation(res, tchild_rep);
+
+                                               res = res->things_get_next(res);
+                                       }
+
+                                       for (int iter = 0; iter < resource->size; ++iter) {
+                                               child = NULL;
+
+                                               if (resource->uri == NULL) {
+                                                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Resource URI is NULL.");
+                                                       result = OC_EH_ERROR;
+                                                       goto EXIT_VALIDATION;
+                                               }
+
+                                               child = g_builder->get_resource(g_builder, resource->uri);
+
+                                               if (NULL == child) {
+                                                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Not Existing Child Resource.");
+                                                       result = OC_EH_ERROR;
+                                                       goto EXIT_VALIDATION;
+                                               }
+                                               if (NULL == resource->rep) {
+                                                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "things_representation_s is NULL.");
+                                                       result = OC_EH_ERROR;
+                                                       goto EXIT_VALIDATION;
+
+                                               }
+
+                                               if (num > 0) {
+                                                       for (int i = 0; i < num; i++) {
+
+                                                               result |= dm_validate_attribute_in_request(resource->things_get_res_type(child, i), (const void *) /*eh_request->payload */resource->rep->payload);
+                                                               if (!result) {
+                                                                       goto EXIT_VALIDATION;
+                                                               }
+                                                       }
+                                               }
+
+                                               resource = resource->things_get_next(resource);
+
+                                               // if(targetUri != NULL)   things_free(targetUri);
+                                       }
+                               } else {
+                                       if (num > 0) {
+                                               for (int iter = 0; iter < num; iter++) {
+                                                       // if it's okey in any case then....it's valid..
+                                                       result |= dm_validate_attribute_in_request(resource->things_get_res_type(resource, iter), (const void *)eh_request->payload);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+EXIT_VALIDATION:
+
+       /*! Added by st_things for memory Leak fix
+        */
+       things_release_resource_inst(pst_temp_resource);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Validation Result.(%d)", result);
+
+       return result;
+}
+
+OCEntityHandlerResult send_response(OCRequestHandle request_handle, OCResourceHandle resource, OCEntityHandlerResult result, const char *uri, void *payload)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       OCEntityHandlerResult eh_result = OC_EH_OK;
+       OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, {}, {0}, false };
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Creating Response with Request Handle : %x,Resource Handle : %x", request_handle, resource);
+
+       response.numSendVendorSpecificHeaderOptions = 0;
+       memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+       memset(response.resourceUri, 0, sizeof(response.resourceUri));
+
+       if (NULL != request_handle && NULL != resource) {
+               response.requestHandle = request_handle;        //eh_request->request_handle;
+               response.resourceHandle = resource;     //eh_request->resource;
+               response.persistentBufferFlag = 0;
+               response.ehResult = result;
+               if (payload != NULL) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Payload is Not NULL");
+                       response.payload = (OCPayload *) payload;
+               } else {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "No Payload");
+                       response.payload = NULL;
+               }
+
+               THINGS_LOG_V(THINGS_INFO, TAG, "\t\t\tRes. : %s ( %d )", (response.ehResult == OC_EH_OK ? "NORMAL" : "ERROR"), response.ehResult);
+
+               OCStackResult ret = OCDoResponse(&response);
+               THINGS_LOG_V(THINGS_INFO, TAG, "\t\t\tMsg. Out? : (%s)", (ret == OC_STACK_OK) ? "SUCCESS" : "FAIL");
+               if (ret != OC_STACK_OK) {
+                       eh_result = OC_EH_ERROR;
+               }
+       } else {
+               eh_result = OC_EH_ERROR;
+       }
+
+       // THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return eh_result;
+}
+
+static bool is_number(char *str)
+{
+       int len = strlen(str);
+       for (int index = 0; index < len; index++) {
+               if (!isdigit(str[index])) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "It's NOT NUMBER : %s", str);
+                       return false;
+               }
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "It is NUMBER : %s", str);
+       return true;
+}
+
+/**
+ * This functions will replace thie ConverAPInfo(~~ )
+ */
+static OCEntityHandlerResult convert_ap_infor(things_resource_s *target_resource, access_point_info_s **p_list, int list_cnt)
+{
+
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       things_representation_s *rep = NULL;
+
+       if (!(list_cnt == 0 || p_list == NULL)) {
+
+               if (target_resource->rep == NULL) {
+                       rep = things_create_representation_inst(NULL);
+                       target_resource->things_set_representation(target_resource, rep);
+               } else {
+                       rep = target_resource->rep;
+               }
+
+               things_representation_s **child_rep = (things_representation_s **) things_malloc(list_cnt * sizeof(things_representation_s *));
+
+               for (int iter = 0; iter < list_cnt; iter++) {
+
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "e_ssid : %s", p_list[iter]->e_ssid);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "security_key : %s", p_list[iter]->security_key);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "auth_type : %s", p_list[iter]->auth_type);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "enc_type : %s", p_list[iter]->enc_type);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "channel : %s", p_list[iter]->channel);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "signal_level : %s", p_list[iter]->signal_level);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "bss_id : %s", p_list[iter]->bss_id);
+
+                       child_rep[iter] = things_create_representation_inst(NULL);
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_CHANNAL, p_list[iter]->channel);
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_ENCTYPE, p_list[iter]->enc_type);
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_MACADDR, p_list[iter]->bss_id);
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_MAXRATE, "MAX_RATE");
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_RSSI, p_list[iter]->signal_level);
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_SECTYPE, p_list[iter]->auth_type);
+                       child_rep[iter]->things_set_value(child_rep[iter], SEC_ATTRIBUTE_AP_SSID, p_list[iter]->e_ssid);
+               }
+
+               rep->things_set_arrayvalue(rep, SEC_ATTRIBUTE_AP_ITEMS, list_cnt, child_rep);
+
+               for (int iter = 0; iter < list_cnt; iter++) {
+                       /*! Changed by st_things for memory Leak fix
+                        */
+                       things_release_representation_inst(child_rep[iter]);
+                       child_rep[iter] = NULL;
+               }
+               things_free(child_rep);
+               child_rep = NULL;
+
+               eh_result = OC_EH_OK;
+       }
+
+       return eh_result;
+}
+
+/**
+ * This functions will be deprecated~!!!
+ */
+static OCEntityHandlerResult get_ap_scan_result(things_resource_s *target_resource)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       access_point_info_s **p_list = NULL;
+       int list_cnt = 0;
+       int result = 0;
+
+       // p_list = (access_point_info_s**)things_malloc(sizeof(access_point_info_s*) *MAX_NUM_AP);
+
+       result = things_get_ap_list(&p_list, &list_cnt);
+       if (result) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Get Access points list!!! %d ", list_cnt);
+               if (list_cnt > 0) {
+                       //eh_result = ConvertAPInfo(target_resource, p_list, list_cnt);
+                       eh_result = convert_ap_infor(target_resource, p_list, list_cnt);
+               } else if (list_cnt == 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "0 Access points!!!! %d ", list_cnt);
+                       eh_result = OC_EH_OK;
+               } else {
+                       eh_result = OC_EH_ERROR;
+               }
+       } else {
+               THINGS_LOG_V(THINGS_ERROR, TAG, "GET AP Searching List FUNC Failed!!!!");
+       }
+
+       if (p_list != NULL) {
+               for (int i = 0; i < list_cnt; i++) {
+                       things_free(p_list[i]);
+               }
+               things_free(p_list);
+       }
+
+       return eh_result;
+}
+
+/**
+ * This functions will replace the get_ap_scan_result(~~)
+ */
+static OCEntityHandlerResult get_provisioning_info(things_resource_s *target_resource)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       // if(eh_result == OC_EH_OK)
+       {
+
+               const char *deviceID = OCGetServerInstanceIDString();
+               const char *deviceRT = dm_get_things_device_type(0);
+               bool isOwned = false;
+               bool isReset = things_get_reset_mask(RST_ALL_FLAG);
+               /* if(!isReset) { */
+               /*  isReset = 1; */
+               /* } */
+
+               if (OC_STACK_OK != OCGetDeviceOwnedState(&isOwned)) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Failed to get device owned state, Informing as UNOWNED~!!!!");
+                       isOwned = false;
+               }
+               if (target_resource->rep == NULL) {
+                       /*! Added by st_things for memory Leak fix
+                        */
+                       things_representation_s *pstRep = NULL;
+                       pstRep = things_create_representation_inst(NULL);
+                       target_resource->things_set_representation(target_resource, pstRep);
+               }
+
+               things_representation_s *child_rep[1] = { NULL };
+
+               child_rep[0] = things_create_representation_inst(NULL);
+               child_rep[0]->things_set_value(child_rep[0], SEC_ATTRIBUTE_PROV_TARGET_ID, deviceID);
+               child_rep[0]->things_set_value(child_rep[0], SEC_ATTRIBUTE_PROV_TARGET_RT, deviceRT);
+
+               // child_rep[0]->things_set_bool_value(child_rep[0], SEC_ATTRIBUTE_PROV_TARGET_OWNED, isOwned);
+               child_rep[0]->things_set_bool_value(child_rep[0], SEC_ATTRIBUTE_PROV_TARGET_PUBED, dm_is_rsc_published());
+
+               target_resource->rep->things_set_arrayvalue(target_resource->rep, SEC_ATTRIBUTE_PROV_TARGETS, 1, child_rep);
+
+               target_resource->rep->things_set_bool_value(target_resource->rep, SEC_ATTRIBUTE_PROV_TARGET_OWNED, isOwned);
+
+               target_resource->rep->things_set_value(target_resource->rep, SEC_ATTRIBUTE_PROV_EZSETDI, deviceID);
+
+               target_resource->rep->things_set_bool_value(target_resource->rep, SEC_ATTRIBUTE_PROV_RESET, isReset);
+
+               target_resource->rep->things_set_int_value(target_resource->rep, SEC_ATTRIBUTE_PROV_ABORT, 0);
+               /*! Added by st_things for memory Leak fix
+                */
+               if (NULL != child_rep[0]) {
+                       things_release_representation_inst(child_rep[0]);
+               }
+
+               eh_result = OC_EH_OK;
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult trigger_reset_request(things_resource_s *target_resource, bool reset)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+       things_resource_s *clone_resource = NULL;
+       bool isOwned;
+
+       OCGetDeviceOwnedState(&isOwned);
+       if (isOwned == false) {
+               return OC_EH_NOT_ACCEPTABLE;
+       }
+
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "==> RESET : %s", (reset == true ? "YES" : "NO"));
+
+       if (reset == true) {
+               int res = -1;
+
+               clone_resource = clone_resource_inst(target_resource);
+               res = things_reset((void *)clone_resource, RST_NEED_CONFIRM);
+
+               switch (res) {
+               case 1:
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Reset Thread create is success.");
+                       eh_result = OC_EH_SLOW;
+                       break;
+               case 0:
+                       THINGS_LOG(THINGS_INFO, TAG, "Already Run Reset-Process.");
+                       eh_result = OC_EH_NOT_ACCEPTABLE;
+               default:
+                       things_release_resource_inst(clone_resource);
+                       clone_resource = NULL;
+                       break;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "reset = %d, So, can not reset start.", reset);
+               eh_result = OC_EH_OK;
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult trigger_stop_ap_request(things_resource_s *target_resource, bool stop_ap)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "==> STOP SOFT AP : %s", (stop_ap == true ? "YES" : "NO"));
+
+       if (stop_ap == true) {
+               if (NULL != g_stop_soft_ap_cb) {
+                       if (1 == g_stop_soft_ap_cb(stop_ap)) {
+                               THINGS_LOG_V(THINGS_DEBUG, TAG, "Stop Soft AP notified Successfully");
+                               eh_result = OC_EH_OK;
+                       } else {
+                               THINGS_LOG_V(THINGS_DEBUG, TAG, "Stop Soft AP notified, BUT DENIED");
+                               eh_result = OC_EH_ERROR;
+                       }
+               }
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "stop_ap = %d, So, can not stop AP.", stop_ap);
+               eh_result = OC_EH_OK;
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult trigger_abort_request(things_resource_s *target_resource, things_es_enrollee_abort_e abort_es)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+       static pthread_t h_thread_abort = NULL;
+//    static pthread_t h_thread_abort[4] = {NULL, };
+
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "==> ABORT Easy Setup : %d", abort_es);
+
+       switch (abort_es) {
+       case ABORT_BEFORE_RESET_CONFIRM:        // before Reset Confirm.
+       case ABORT_BEFORE_SEC_CONFIRM:  // After Reset Confirm & before Security Confirm.
+       case ABORT_BEFORE_DATA_PROVISIONING:    // After Security Confirm
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Forwarding abort-level to st_things App.(Level: %d)", abort_es);
+               eh_result = things_abort(&h_thread_abort, abort_es);
+//        eh_result = things_abort(&h_thread_abort[abort_es], abort_es);
+               break;
+       default:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "abort_es = %d, So, Don't need any-process", abort_es);
+               eh_result = OC_EH_OK;
+               break;
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult set_provisioning_info(things_resource_s *target_resource)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       bool reset = false;
+       bool stop_ap = false;
+       int64_t abort_es = 0;
+
+       if (target_resource->rep->things_get_bool_value(target_resource->rep, SEC_ATTRIBUTE_PROV_RESET, &reset) == true) {
+               eh_result = trigger_reset_request(target_resource, reset);
+       } else if (target_resource->rep->things_get_bool_value(target_resource->rep, SEC_ATTRIBUTE_PROV_TERMINATE_AP, &stop_ap) == true) {
+               eh_result = trigger_stop_ap_request(target_resource, stop_ap);
+       } else if (target_resource->rep->things_get_int_value(target_resource->rep, SEC_ATTRIBUTE_PROV_ABORT, &abort_es) == true) {
+               eh_result = trigger_abort_request(target_resource, (things_es_enrollee_abort_e) abort_es);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Get Value is failed.(RESET NOR TERMINATE NOR ABORT)");
+               return eh_result;
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult get_device_or_platform_info_result(things_resource_s *target_resource, char *device_id)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       if (strlen(device_id) > 0 && is_number(device_id)) {
+               int num = atoi(device_id);
+
+               // 1. Get the resource with uri
+               things_resource_s *resource = dm_get_resource_instance(target_resource->uri, num);
+               if (resource) {
+                       // 2. Clone the Payload of the resource
+                       OCPayloadDestroy((OCPayload *) target_resource->rep->payload);
+                       target_resource->rep->payload = NULL;
+                       target_resource->rep->payload = OCRepPayloadClone(resource->rep->payload);
+
+                       eh_result = OC_EH_OK;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Device ID : %s", device_id);
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult process_post_request(things_resource_s **target_res)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       things_resource_s *target_resource = *target_res;
+
+       if (strstr(target_resource->uri, URI_SEC) != NULL && strstr(target_resource->uri, URI_PROVINFO) != NULL) {
+               // 1. Post request for the Easy-Setup reset
+               eh_result = set_provisioning_info(target_resource);
+       }
+#ifndef __ST_THINGS_RTOS__
+       else if (strstr(target_resource->uri, URI_INFORMATION) != NULL) {
+               // X. Get request for the Access point list(Will be deprecated!!!!)
+               eh_result = SetDeviceInfoResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_ACTIONS) != NULL) {
+               // 2. Post request on the schedule resource
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "#####00 IN process_post_request pQuery : %s", target_resource->query);
+               eh_result = SetActionResource(target_resource);
+       } else if (strstr(target_resource->uri, URI_FILE) != NULL && strstr(target_resource->uri, URI_TRANSFER) != NULL) {
+               // 3. Post request on the sharable file(s) to update the blob data
+               eh_result = SetFileTransferResource(target_resource);
+       } else if (strstr(target_resource->uri, URI_CONTENTS) != NULL && strstr(target_resource->uri, URI_RENDERER) != NULL) {
+               // 4. Post request for the storing Blob data of files
+               eh_result = SetContentsRendererMetadataResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_OIC) != NULL && strstr(target_resource->uri, URI_WK_MAINTENANCE) != NULL) {
+               // 5. Post request for the trigger device maintenance functions
+               eh_result = SetDeviceMaintenanceResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_BIXBY) != NULL) {
+               // 6. Post request for handling bixby request
+               eh_result = SetBixbyRequestResult(target_resource);
+       }
+#endif
+       else {
+#ifndef __ST_THINGS_RTOS__
+               // 7. Post request on the other reosurce(s)
+               int handled = 0;
+               if (NULL != g_handle_res_list) {
+                       int iter = 0;
+                       for (iter = 0; iter < g_handle_res_cnt; iter++) {
+                               if (strstr(target_resource->uri, g_handle_res_list[iter])) {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "Handling %s with things_resource_s Based CB", target_resource->uri);
+
+                                       int ret = g_handle_req_cb(target_resource->req_type, target_resource);
+                                       if (1 == ret) {
+                                               eh_result = OC_EH_OK;
+                                               handled = 1;
+                                       } else {
+                                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Handled as ERROR from App.");
+                                       }
+
+                                       break;
+                               }
+                       }
+               }
+               if (handled == 0) {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Handling %s with things_info_s Converting Based CB", target_resource->uri);
+
+                       eh_result = PostResourceData(target_res);
+               }
+#else
+
+               // Post request for application resources
+               if (g_handle_request_set_cb != NULL) {
+                       int ret = g_handle_request_set_cb(target_resource);
+                       if (1 == ret) {
+                               eh_result = OC_EH_OK;
+                       } else {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Handled as ERROR from App.");
+                       }
+               } else {
+                       THINGS_LOG_V(THINGS_ERROR, TAG, "g_handle_request_set_cb is not registered");
+               }
+#endif
+       }
+
+       return eh_result;
+}
+
+static OCEntityHandlerResult process_get_request(things_resource_s *target_resource)
+{
+
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       char *device_id = NULL;
+
+       device_id = strrchr(target_resource->uri, '/') + 1;
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Get Device ID in Resources URI = %s", device_id);
+
+       things_representation_s *rep = things_create_representation_inst(NULL);
+       target_resource->things_set_representation(target_resource, rep);
+
+       if (strstr(target_resource->uri, URI_SEC) != NULL && strstr(target_resource->uri, URI_PROVINFO) != NULL) {
+               // 1. Get request for the Access point list
+               eh_result = get_provisioning_info(target_resource);
+       }
+#ifndef __ST_THINGS_RTOS__
+       else if (strstr(target_resource->uri, URI_INFORMATION) != NULL) {
+               // X. Get request for the Access point list(Will be deprecated!!!!)
+               eh_result = GetDeviceInfoResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_SEC) != NULL && strstr(target_resource->uri, URI_ACCESSPOINTLIST) != NULL) {
+               // X. Get request for the Access point list(Will be deprecated!!!!)
+               eh_result = get_ap_scan_result(target_resource);
+       } else if (strstr(target_resource->uri, URI_FILE) != NULL && strstr(target_resource->uri, URI_LIST) != NULL) {
+               // 3. Get request for the list of files which can be transfered to the Client
+               eh_result = GetFileListResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_FILE) != NULL && strstr(target_resource->uri, URI_TRANSFER) != NULL) {
+               // 4. Get request for the Blob data of files
+               eh_result = GetFileBlobValueResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_ACTIONS) != NULL) {
+               // 5. Get request for the list of schedules
+               eh_result = GetActionResource(target_resource);
+       } else if ((strstr(target_resource->uri, URI_CONTENTS) != NULL && strstr(target_resource->uri, URI_PROVIDER) != NULL)
+                          || (strstr(target_resource->uri, URI_CONTENTS) != NULL && strstr(target_resource->uri, URI_RENDERER) != NULL)
+                         ) {
+               // 7. Get request for the Blob data of files
+               eh_result = GetContentsMetadataResult(target_resource);
+       } else if (strstr(target_resource->uri, URI_OIC) != NULL && strstr(target_resource->uri, URI_WK_MAINTENANCE) != NULL) {
+               // 8. Get request for the device maintenance information
+               eh_result = GetDeviceMaintenanceResult(target_resource);
+       }
+#endif
+       else if (strstr(target_resource->uri, URI_SEC) != NULL && strstr(target_resource->uri, URI_ACCESSPOINTLIST) != NULL) {
+               // X. Get request for the Access point list(Will be deprecated!!!!)
+               eh_result = get_ap_scan_result(target_resource);
+       } else if (strstr(target_resource->uri, OC_RSRVD_DEVICE_URI) != NULL || strstr(target_resource->uri, OC_RSRVD_PLATFORM_URI) != NULL) {
+               // 9. Get request for the device maintenance information
+               eh_result = get_device_or_platform_info_result(target_resource, device_id);
+       } else {
+#ifndef __ST_THINGS_RTOS__
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "HELLO WORLD");
+               // 10. Get request on the other resources
+               int handled = 0;
+               if (NULL != g_handle_res_list) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "HELLO WORLD");
+                       int iter = 0;
+                       for (iter = 0; iter < g_handle_res_cnt; iter++) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "%s  : %s ", target_resource->uri, g_handle_res_list[iter]);
+                               if (strstr(target_resource->uri, g_handle_res_list[iter])) {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "Handling %s with things_resource_s Based CB", target_resource->uri);
+                                       int ret = g_handle_req_cb(target_resource->req_type, target_resource);
+                                       if (1 == ret) {
+                                               eh_result = OC_EH_OK;
+                                               handled = 1;
+                                       } else {
+                                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Handled as ERROR from App.");
+                                       }
+
+                                       break;
+                               }
+                       }
+               }
+               if (handled == 0) {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Handling %s with things_info_s Converting Based CB", target_resource->uri);
+
+                       eh_result = GetResourceData(target_resource);
+               }
+#else
+               // Post request for application resources
+               if (g_handle_request_get_cb != NULL) {
+                       int ret = g_handle_request_get_cb(target_resource);
+                       if (1 == ret) {
+                               eh_result = OC_EH_OK;
+                       } else {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Handled as ERROR from App.");
+                       }
+               } else {
+                       THINGS_LOG_V(THINGS_ERROR, TAG, "g_handle_request_get_cb is not registered");
+               }
+#endif
+       }
+
+       return eh_result;
+}
+
+static bool is_can_not_response_case(things_resource_s *target_resource, OCMethod req_type, OCEntityHandlerResult eh_result)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       bool res = false;
+
+       if (target_resource == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Invalid argument.(target_resource=NULL)");
+               return true;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "target_resource->uri=%s", target_resource->uri);
+       if (strstr(target_resource->uri, URI_SEC) != NULL && strstr(target_resource->uri, URI_PROVINFO) != NULL) {
+               if (req_type == OC_REST_POST && eh_result == OC_EH_SLOW) {
+                       res = true;
+               }
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "result = %d", res);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return res;
+}
+
+static void *message_handling_loop(void *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int req_type = -1;
+       // char* uri = NULL;
+       things_resource_s *target_resource = NULL;
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       while (!g_quit_flag) {
+               //THINGS_LOG_D(THINGS_INFO, TAG, "[Req.HDLoop] Looping.");
+
+               //while(gOicReqQueue.length(&gOicReqQueue) > 0)
+               while (gp_oic_req_queue->length(gp_oic_req_queue) > 0) {
+                       eh_result = OC_EH_ERROR;
+
+                       //target_resource = gOicReqQueue.pop(&gOicReqQueue, &req_type);
+                       target_resource = gp_oic_req_queue->pop(gp_oic_req_queue, &req_type);
+                       if (NULL == target_resource) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Request Item is NULL.");
+                               continue;
+                       }
+                       // RequestInfo* info = CreateRequestInfo(req_type, 0,
+                       //                             target_resource->request_handle,
+                       //                             target_resource->resource_handle);
+
+                       // duplicate_string (info->frameId, &target_resource->cmd_id);
+
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Request Handle : %x, Resource Handle : %x", target_resource->request_handle, target_resource->resource_handle);
+
+                       // THINGS_LOG_D(THINGS_DEBUG, TAG, "Request on cmd_id. %s",
+                       //                         target_resource->cmd_id);
+                       target_resource->req_type = req_type;
+
+                       if (req_type == OC_REST_GET) {
+                               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tReq. : GET on %s", target_resource->uri);
+                               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tQuery: %s", target_resource->query);
+                               eh_result = process_get_request(target_resource);
+
+                       } else if (req_type == OC_REST_POST) {
+                               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tReq. : POST on  %s", target_resource->uri);
+                               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tQuery: %s", target_resource->query);
+                               eh_result = process_post_request(&target_resource);
+                       } else {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, " Invalid Request Received : %d", req_type);
+                       }
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, " @@@@@ target_resource ->size : %d", target_resource->size);
+                       // THINGS_LOG_D(THINGS_DEBUG, TAG, " @@@@@ target_resource ->cmd_id : %s", target_resource->cmd_id);
+
+                       if (is_can_not_response_case(target_resource, req_type, eh_result) == false) {
+                               if (eh_result != OC_EH_OK && eh_result != OC_EH_SLOW) {
+                                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Handing Request Failed, Sending ERROR Response");
+
+                                       things_resource_s *temp = g_builder->get_resource(g_builder, target_resource->uri);
+                                       const char *rt = temp->things_get_res_type(temp, 0);
+                                       if (0 == strncmp(rt, SEC_RTYPE_TEMPERATURE, strlen(SEC_RTYPE_TEMPERATURE)) || 0 == strncmp(rt, OIC_RTYPE_TEMPERATURE, strlen(OIC_RTYPE_TEMPERATURE))) {
+                                               OCRepPayload *rep_payload = target_resource->things_get_rep_payload(target_resource);
+                                               send_response(target_resource->request_handle, target_resource->resource_handle, OC_EH_ERROR, target_resource->uri, rep_payload);
+                                       } else {
+                                               send_response(target_resource->request_handle, target_resource->resource_handle, eh_result, target_resource->uri, NULL);
+                                       }
+                               } else {
+                                       OCRepPayload *rep_payload = target_resource->things_get_rep_payload(target_resource);
+
+                                       eh_result = send_response(target_resource->request_handle,      // reqInfo->reqHandle,
+                                                                                         target_resource->resource_handle,     // reqInfo->resHandle,
+                                                                                         target_resource->error, target_resource->uri, rep_payload);
+
+                                       /*! Added by st_things for memory Leak fix
+                                        */
+                                       //if(OC_EH_ERROR == eh_result)
+                                       //{
+                                       OCPayloadDestroy((OCPayload *) rep_payload);
+                                       rep_payload = NULL;
+                                       //}
+                               }
+                       }
+                       // Need to design How to release memory allocated for the things_resource_s list.
+                       things_release_resource_inst(target_resource);
+
+                       usleep(100 * 1000);
+               }                                               // End Of While Loop
+
+               things_control_queue_empty();
+
+               usleep(100 * 1000);
+       }                                                       // End Of While Loop
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[Req.HDLoop] Leaving loop...");
+
+       return NULL;
+}
+
+void notify_result_of_reset(things_resource_s *target_resource, bool result)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       if (target_resource == NULL) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Not exist remote-client.");
+               return;
+       }
+
+       if (result == true) {           // reset Success.
+               OCRepPayload *rep_payload = target_resource->things_get_rep_payload(target_resource);
+
+               eh_result = send_response(target_resource->request_handle,      // reqInfo->reqHandle,
+                                                                 target_resource->resource_handle,     // reqInfo->resHandle,
+                                                                 target_resource->error, target_resource->uri, rep_payload);
+
+               /*! Added by st_things for memory Leak fix
+                */
+//        if(OC_EH_ERROR == eh_result)
+//        {
+               OCPayloadDestroy((OCPayload *) rep_payload);
+               rep_payload = NULL;
+//        }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Handing Request Failed, Sending ERROR Response");
+
+               send_response(target_resource->request_handle, target_resource->resource_handle, eh_result, target_resource->uri, NULL);
+       }
+
+       things_release_resource_inst(target_resource);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+int notify_things_observers(const char *uri, const char *query)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       int res = 0;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "uri = %s", uri);
+       if (NULL != uri) {
+               int remainLen = MAX_RESOURCE_LEN - 1;
+               char tempUri[MAX_RESOURCE_LEN] = { 0 };
+
+               if (NULL != g_get_notify_obs_uri) {
+                       char *temp = g_get_notify_obs_uri(uri, query);
+                       if (NULL != temp) {
+                               things_strncpy(tempUri, temp, remainLen);
+                               remainLen -= strnlen(tempUri, MAX_RESOURCE_LEN - 1);
+                               things_free(temp);
+                       }
+               }
+
+               if (strnlen(tempUri, MAX_RESOURCE_LEN - 1) < 1) {
+                       things_strncpy(tempUri, uri, remainLen);
+                       remainLen -= strnlen(tempUri, MAX_RESOURCE_LEN - 1);
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "%s resource notifies to observers.", tempUri);
+
+               for (int iter = 0; iter < g_builder->res_num; iter++) {
+                       if (strstr(g_builder->gres_arr[iter]->uri, tempUri) != NULL) {
+                               OCStackResult ret2 = OCNotifyAllObservers((OCResourceHandle) g_builder->gres_arr[iter]->resource_handle,
+                                                                        OC_MEDIUM_QOS);
+
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "%s resource has notified to observers.", g_builder->gres_arr[iter]->uri);
+
+                               if (OC_STACK_OK == ret2) {
+                                       THINGS_LOG(THINGS_INFO, TAG, "Success: Sent notification to Observers");
+                               } else {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "Failed: No Observers to notify : %d ", ret2);
+                               }
+                               res = 1;
+                               break;
+                       }
+               }
+
+#ifndef __ST_THINGS_RTOS__
+               // if(res)
+               {
+                       // Need to refactor later support the number bigger then 9
+                       char *device_num = strrchr(uri, '/');
+                       char res_uri[128] = { 0 };
+
+                       memset(res_uri, 0, (size_t) 128);
+                       strncat(res_uri, URI_DEVICE_COL, strlen(URI_DEVICE_COL));
+                       strncat(res_uri, device_num, strlen(device_num));
+
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Target Collection URI : %s", res_uri);
+
+                       things_resource_s *temp = g_builder->get_resource(g_builder, res_uri);
+                       if (temp) {
+                               OCStackResult ret3 = OCNotifyAllObservers((OCResourceHandle) temp->resource_handle,
+                                                                        OC_MEDIUM_QOS);
+
+                               if (OC_STACK_OK == ret3) {
+                                       THINGS_LOG(THINGS_INFO, TAG, "Sent notification to Observers");
+                               } else {
+                                       THINGS_LOG_D(THINGS_INFO, TAG, "No Observers to notify : %d ", ret3);
+                               }
+                       }
+               }
+#endif
+
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return res;
+}
+
+OCEntityHandlerResult handle_message(things_resource_s *target_resource)
+{
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       if (NULL == target_resource) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Request Item is NULL.");
+               return OC_EH_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Request Handle : %x, Resource Handle : %x", target_resource->request_handle, target_resource->resource_handle);
+
+       // THINGS_LOG_D(THINGS_DEBUG, TAG, "Request on cmd_id. %s",
+       //                         target_resource->cmd_id);
+
+       if (target_resource->req_type == OC_REST_GET) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tReq. : GET on %s", target_resource->uri);
+               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tQuery: %s", target_resource->query);
+               eh_result = process_get_request(target_resource);
+
+       } else if (target_resource->req_type == OC_REST_POST) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tReq. : POST on  %s", target_resource->uri);
+               THINGS_LOG_V(THINGS_INFO, TAG, "\t\tQuery: %s", target_resource->query);
+               eh_result = process_post_request(&target_resource);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, " Invalid Request Received : %d", target_resource->req_type);
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, " @@@@@ target_resource ->size : %d", target_resource->size);
+       // THINGS_LOG_D(THINGS_DEBUG, TAG, " @@@@@ target_resource ->cmd_id : %s", target_resource->cmd_id);
+
+       if (is_can_not_response_case(target_resource, target_resource->req_type, eh_result) == false) {
+               if (eh_result != OC_EH_OK && eh_result != OC_EH_SLOW) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Handing Request Failed, Sending ERROR Response");
+
+                       things_resource_s *temp = g_builder->get_resource(g_builder, target_resource->uri);
+                       const char *rt = temp->things_get_res_type(temp, 0);
+                       if (0 == strncmp(rt, SEC_RTYPE_TEMPERATURE, strlen(SEC_RTYPE_TEMPERATURE)) || 0 == strncmp(rt, OIC_RTYPE_TEMPERATURE, strlen(OIC_RTYPE_TEMPERATURE))) {
+                               OCRepPayload *rep_payload = target_resource->things_get_rep_payload(target_resource);
+                               send_response(target_resource->request_handle, target_resource->resource_handle, OC_EH_ERROR, target_resource->uri, rep_payload);
+                       } else {
+                               send_response(target_resource->request_handle, target_resource->resource_handle, eh_result, target_resource->uri, NULL);
+                       }
+                       eh_result = OC_EH_OK;
+               } else {
+                       OCRepPayload *rep_payload = target_resource->things_get_rep_payload(target_resource);
+
+                       eh_result = send_response(target_resource->request_handle,      // reqInfo->reqHandle,
+                                                                         target_resource->resource_handle,     // reqInfo->resHandle,
+                                                                         target_resource->error, target_resource->uri, rep_payload);
+
+                       /*! Added by st_things for memory Leak fix
+                        */
+                       //if(OC_EH_ERROR == eh_result)
+                       //{
+                       OCPayloadDestroy((OCPayload *) rep_payload);
+                       rep_payload = NULL;
+                       //}
+               }
+       }
+       //  Need to design How to release memory allocated for the things_resource_s list.
+       things_release_resource_inst(target_resource);
+
+       return eh_result;
+}
+
+OCEntityHandlerResult entity_handler(OCEntityHandlerFlag flag, OCEntityHandlerRequest *entity_handler_request, void *callback)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, THINGS_FUNC_ENTRY);
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       // Validate pointer
+       if (!entity_handler_request) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Invalid request pointer");
+               return eh_result;
+       }
+
+       const char *uri = OCGetResourceUri(entity_handler_request->resource);
+
+       // Observe Request Handling
+       if (flag & OC_OBSERVE_FLAG) {
+               if (OC_OBSERVE_REGISTER == entity_handler_request->obsInfo.action) {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "Observe Requset on : %s ", uri);
+                       // 1. Check whether it's Observe request on the Collection Resource
+                       if (NULL != strstr(uri, URI_DEVICE_COL)) {
+                               //2. Check whether the query carriese the if=oic.if.b
+                               if ((strstr(entity_handler_request->query, OIC_INTERFACE_BATCH) == NULL)) {
+                                       //3. If not batch then error
+                                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Collection Resource Requires BATCH for Observing : %s", entity_handler_request->query);
+                                       eh_result = OC_EH_BAD_REQ;
+                                       goto RESPONSE_ERROR;
+                               } else {
+                                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Receiving Observe Request Collection Resource");
+                               }
+                       }
+               } else if (OC_OBSERVE_DEREGISTER == entity_handler_request->obsInfo.action) {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "CancelObserve Request on : %s", uri);
+               }
+       }
+       // Get/Post Request Handling
+       if (flag & OC_REQUEST_FLAG) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "Req. URI  : %s", uri);
+               THINGS_LOG_D(THINGS_INFO, TAG, "Req. TYPE : %d", entity_handler_request->method);
+
+               if (things_get_reset_mask(RST_CONTROL_MODULE_DISABLE) == true) {
+                       THINGS_LOG(THINGS_INFO, TAG, "Control Module Disable.");
+                       eh_result = OC_EH_NOT_ACCEPTABLE;
+               } else if ((OC_REST_GET == entity_handler_request->method)
+                                  || (OC_REST_POST == entity_handler_request->method)) {
+                       THINGS_LOG_D(THINGS_INFO, TAG, "Request Handle : %x, Resource Handle : %x", entity_handler_request->requestHandle, entity_handler_request->resource);
+                       if (verify_request(entity_handler_request, uri, (int)entity_handler_request->method) > 0) {
+                               //  IoTivity Stack Destroy the payload after receving result from this function
+                               //       Therefore, we need to copy/clone the payload for the later use..
+                               things_resource_s *resource = things_create_resource_inst(entity_handler_request->requestHandle,
+                                                                                         entity_handler_request->resource,
+                                                                                         entity_handler_request->query,
+                                                                                         entity_handler_request->payload);
+                               resource->things_set_dev_addr(resource, &(entity_handler_request->devAddr));
+                               resource->req_type = entity_handler_request->method;
+                               //resource->set_uri(resource, uri);
+
+//                THINGS_LOG_D(THINGS_DEBUG, TAG, "About to Queue a received Request~!!!!");
+//
+//                //gOicReqQueue.push(&gOicReqQueue, resource, entity_handler_request->method);
+//                gp_oic_req_queue->push(gp_oic_req_queue, resource, entity_handler_request->method);
+//                eh_result = OC_EH_SLOW;
+                               eh_result = handle_message(resource);
+                       } else {
+                               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid Query in the Request : %s", entity_handler_request->query);
+                       }
+               } else if (OC_REST_DELETE == entity_handler_request->method || OC_REST_PUT == entity_handler_request->method) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Delete/PUT Req. Handling is not supported Yet");
+               } else {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Received unsupported method from client");
+               }
+
+       }
+
+RESPONSE_ERROR:
+
+       if (eh_result != OC_EH_SLOW && eh_result != OC_EH_OK) {
+               //  If the result is OC_EH_ERROR, the stack will remove the
+               //       received request in the stack.
+               //       If the reusult is OC_EH_SLOW, then the request will be
+               //       stored in the stack till the response goes out
+               eh_result = send_response(entity_handler_request->requestHandle, entity_handler_request->resource, eh_result, uri, NULL);
+               // Currently this code will not do anything...
+               //      Need to refactor later..
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return eh_result;
+}
+
+void init_handler()
+{
+       g_quit_flag = false;
+
+//#ifdef __ST_THINGS_RTOS__
+//    pthread_create_rtos(&g_req_handle, NULL, message_handling_loop, (void *)NULL, THINGS_STACK_MESSAGE_HANDLING_THREAD);
+//#else
+//   things_thread_create (&g_req_handle, NULL, message_handling_loop, (void *)NULL);
+//#endif
+
+}
+
+void deinit_handler()
+{
+       g_quit_flag = true;
+
+       int iter = 0;
+       if (g_handle_res_list != NULL) {
+               for (iter = 0; iter < g_handle_res_cnt; iter++) {
+                       if (g_handle_res_list[iter] != NULL) {
+                               things_free(g_handle_res_list[iter]);
+                               g_handle_res_list[iter] = NULL;
+                       }
+               }
+               things_free(g_handle_res_list);
+               g_handle_res_list = NULL;
+       }
+       g_handle_res_cnt = 0;
+}
+
+struct things_request_handler_s *get_handler_instance()
+{
+       struct things_request_handler_s *handler = (things_request_handler_s *) things_malloc(sizeof(things_request_handler_s));
+
+       if (handler == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Not Enough Memory");
+               return NULL;
+       } else {
+               handler->entity_handler = &entity_handler;
+               handler->init_module = &init_handler;
+               handler->deinit_module = &deinit_handler;
+               handler->notify_things_observers = &notify_things_observers;
+               return handler;
+       }
+}
+
+void release_handler_instance(struct things_request_handler_s *handler)
+{
+       if (handler) {
+               handler->deinit_module();
+               things_free(handler);
+       }
+}
+
+int register_stop_softap_cb(stop_softap_func_type func)
+{
+       if (NULL != func) {
+               g_stop_soft_ap_cb = func;
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int register_handle_request_func(handle_request_func_type get_func, handle_request_func_type set_func)
+{
+       if (NULL != get_func && NULL != set_func) {
+               g_handle_request_get_cb = get_func;
+               g_handle_request_set_cb = set_func;
+       } else {
+               return 0;
+       }
+       return 1;
+}
diff --git a/framework/src/st_things/things_stack/src/common/framework/things_resource.c b/framework/src/st_things/things_stack/src/common/framework/things_resource.c
new file mode 100644 (file)
index 0000000..9cd5445
--- /dev/null
@@ -0,0 +1,945 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#define _BSD_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "things_def.h"
+#include "things_common.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_string_util.h"
+#include "oic_malloc.h"
+#include "ocpayload.h"
+#include "things_resource.h"
+#include "octypes.h"
+
+#define TAG "[things_resource]"
+
+//#*******************************************************************************//
+//#                 Function definitions for the THINGS Resources.
+//#*******************************************************************************//
+
+void set_dev_addr(struct things_resource_s *p_res, void *dev_addr)
+{
+       if (dev_addr == NULL) {
+               p_res->dev_addr = NULL;
+               return;
+       }
+       (p_res->dev_addr) = (OCDevAddr *) things_malloc(sizeof(OCDevAddr));
+       if (NULL != p_res->dev_addr) {
+               memcpy((p_res->dev_addr), dev_addr, sizeof(OCDevAddr));
+       }
+       // p_res->dev_addr = dev_addr;
+}
+
+void *get_dev_addr(struct things_resource_s *p_res)
+{
+       return (p_res->dev_addr);
+}
+
+void set_uri(struct things_resource_s *res, const char *key)
+{
+       //THINGS_LOG_V(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (key == NULL) {
+               return;
+       }
+
+       if (res->uri != NULL) {
+               things_free(res->uri);
+               res->uri = NULL;
+       }
+       res->uri = (char *)things_malloc(sizeof(char) *strlen(key) + 1);
+       memset(res->uri, 0, strlen(key) + 1);
+       things_strncpy(res->uri, key, strlen(key) + 1);
+
+       if (NULL != res->rep) {
+               OCRepPayloadSetUri(res->rep->payload, key);
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Set URI Failed, No Representation Yet");
+       }
+
+       //THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+void set_error(struct things_resource_s *res, double error)
+{
+       res->error = error;
+}
+
+void things_set_value(struct things_representation_s *rep, char *key, char *value)
+{
+#ifdef __ST_THINGS_RTOS__
+       if (value != NULL && key != NULL) {
+               OCRepPayloadSetPropString(rep->payload, key, value);
+       }
+#else
+       OCRepPayloadSetPropString(rep->payload, key, value);
+#endif
+}
+
+void things_set_bool_value(struct things_representation_s *rep, char *key, bool value)
+{
+       OCRepPayloadSetPropBool(rep->payload, key, value);
+}
+
+void things_set_int_value(struct things_representation_s *rep, char *key, int64_t value)
+{
+       OCRepPayloadSetPropInt(rep->payload, key, value);
+}
+
+void things_set_double_value(struct things_representation_s *rep, char *key, double value)
+{
+       OCRepPayloadSetPropDouble(rep->payload, key, value);
+}
+
+void things_set_byte_value(struct things_representation_s *rep, char *key, uint8_t *value, size_t size)
+{
+       OCByteString b_val = { value, size };
+
+       if (b_val.len < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "No byte value to Set");
+       } else {
+               OCRepPayloadSetPropByteString(rep->payload, key, b_val);
+       }
+}
+
+bool things_set_object_value(struct things_representation_s *mother, char *key, struct things_representation_s *child)
+{
+       return OCRepPayloadSetPropObject(mother->payload, key, child->payload);
+}
+
+static OCRepPayloadValue *things_rep_payload_find_values(const OCRepPayload *payload, const char *name)
+{
+       if (!payload || !name) {
+               return NULL;
+       }
+
+       OCRepPayloadValue *val = payload->values;
+       while (val) {
+               if (0 == strncmp(val->name, name, strlen(name))) {
+                       return val;
+               }
+               val = val->next;
+       }
+
+       return NULL;
+}
+
+bool things_set_arrayvalue(struct things_representation_s *mother, char *key, int length, struct things_representation_s **children)
+{
+       bool things_set_value = false;
+       if (length < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA LENGTH IS ZERO!!!!!!");
+               return things_set_value;
+       }
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+
+       OCRepPayload *payloads[length];
+
+       for (int iter = 0; iter < length; iter++) {
+               payloads[iter] = children[iter]->payload;
+       }
+       //  This is codesnippet for creating Array type of value inside the payload..
+       things_set_value = OCRepPayloadSetPropObjectArray(mother->payload, key, (const OCRepPayload **)(payloads), dimensions);
+
+       // THINGS_LOG_V(THINGS_INFO, TAG, " Length : %d", length);
+       // OCRepPayloadSetPropInt(mother->payload, SEC_ATTRIBUTE_LENGTH, length);
+
+       //  Do we need to have those children representation
+       //       with this resource instance????
+       return things_set_value;
+}
+
+bool things_get_arrayvalue(struct things_representation_s *mother, char *key, int *length, struct things_representation_s ***children)
+{
+       //THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "NOt Supported This Function Yet");
+       bool find_value = false;
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "There're (%d) Number of children resources in the Payload : %d", mother->num_children);
+
+       // if( OCRepPayloadGetPropInt((OCRepPayload*)(mother->payload), SEC_ATTRIBUTE_LENGTH, &(mother->num_children) ) )
+       OCRepPayloadValue *payload_value = things_rep_payload_find_values((OCRepPayload *)(mother->payload), key);
+       if (NULL != payload_value) {
+               OCRepPayload **payload_values = NULL;
+               size_t dimension_size = calcDimTotal(payload_value->arr.dimensions);
+               size_t dimensions[3] = { dimension_size, 0, 0 };
+
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Dimension size in the Payload : %d", dimension_size);
+               //    This is testing code only... will be removed...
+               find_value = OCRepPayloadGetPropObjectArray((OCRepPayload *)(mother->payload), key, &payload_values, dimensions);
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Find Value : %d", find_value);
+               if (find_value) {
+                       *children = (things_representation_s **) things_malloc(sizeof(things_representation_s *) *dimension_size);
+
+                       for (int iter = 0; iter < dimension_size; iter++) {
+                               (*children)[iter] = things_create_representation_inst(payload_values[iter]);
+                               /*! Added by st_things for memory Leak fix
+                                */
+                               OCRepPayloadDestroy(payload_values[iter]);
+                       }
+                       /*! Added by st_things for memory Leak fix
+                        */
+                       OICFree(payload_values);
+                       *length = mother->num_children = dimension_size;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA NOT EXIST~!!!!");
+       }
+
+       return find_value;
+}
+
+void things_set_string_arrayvalue(struct things_representation_s *mother, char *key, int length, char **array)
+{
+       if (length < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA LENGTH IS ZERO!!!!!!");
+               return;
+       }
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+
+       //    This is codesnippet for creating Array type of value inside the payload..
+       OCRepPayloadSetStringArray(mother->payload, key, (const char **)array, dimensions);
+}
+
+bool things_get_string_arrayvalue(struct things_representation_s *mother, char *key, int *length, char ***array)
+{
+       THINGS_LOG_V(THINGS_DEBUG, TAG, "There're (%d) Number of children resources in the Payload : %d", mother->num_children);
+
+       bool find_value = false;
+
+       OCRepPayloadValue *payload_value = NULL;
+
+       payload_value = things_rep_payload_find_values((OCRepPayload *)(mother->payload), key);
+
+       if (payload_value != NULL) {
+               size_t dimension_size = calcDimTotal(payload_value->arr.dimensions);
+               size_t dimensions[3] = { dimension_size, 0, 0 };
+
+               find_value = OCRepPayloadGetStringArray((OCRepPayload *)(mother->payload), key, array, dimensions);
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Find Value : %d", find_value);
+               if (find_value) {
+
+                       *length = dimension_size;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA NOT EXIST~!!!!");
+       }
+
+       return find_value;
+}
+
+void things_set_double_arrayvalue(struct things_representation_s *mother, char *key, int length, double *array)
+{
+       if (length < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA LENGTH IS ZERO!!!!!!");
+               return;
+       }
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+
+       OCRepPayloadSetDoubleArray(mother->payload, key, array, dimensions);
+}
+
+bool things_get_double_arrayvalue(struct things_representation_s *mother, char *key, int *length, double **array)
+{
+       bool find_value = false;
+
+       OCRepPayloadValue *payload_value = things_rep_payload_find_values((OCRepPayload *)(mother->payload), key);
+       if (NULL != payload_value) {
+
+               size_t dimension_size = calcDimTotal(payload_value->arr.dimensions);
+               size_t dimensions[3] = { dimension_size, 0, 0 };
+
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Dimension size in the Payload : %d", dimension_size);
+
+               find_value = OCRepPayloadGetDoubleArray((OCRepPayload *)(mother->payload), key, array, dimensions);
+
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Find Value : %d", find_value);
+               if (find_value) {
+                       *length = dimension_size;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA NOT EXIST~!!!!");
+       }
+
+       return find_value;
+}
+
+void things_set_int_arrayvalue(struct things_representation_s *mother, char *key, int length, int64_t *array)
+{
+       if (length < 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA LENGTH IS ZERO!!!!!!");
+               return;
+       }
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { length, 0, 0 };
+
+       OCRepPayloadSetIntArray(mother->payload, key, array, dimensions);
+}
+
+bool things_get_int_arrayvalue(struct things_representation_s *mother, char *key, int *length, int64_t **array)
+{
+       bool find_value = false;
+
+       OCRepPayloadValue *payload_value = things_rep_payload_find_values((OCRepPayload *)(mother->payload), key);
+
+       if (NULL != payload_value) {
+               size_t dimension_size = calcDimTotal(payload_value->arr.dimensions);
+               size_t dimensions[3] = { dimension_size, 0, 0 };
+
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Dimension size in the Payload : %d", dimension_size);
+
+               find_value = OCRepPayloadGetIntArray((OCRepPayload *)(mother->payload), key, array, dimensions);
+
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Find Value : %d", find_value);
+               if (find_value) {
+                       *length = dimension_size;
+               }
+       } else {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "DATA NOT EXIST~!!!!");
+       }
+       return find_value;
+}
+
+void set_representation(struct things_resource_s *res, struct things_representation_s *rep)
+{
+       if (res->rep) {
+               things_release_representation_inst(res->rep);
+               res->rep = NULL;
+       }
+       res->rep = rep;
+}
+
+//   Getter should be refactored to deliver the request value as its return
+//      not through the inserted param.
+void get_uri(struct things_resource_s *res, char **value)
+{
+       if (res->uri != NULL) {
+               *value = (char *)things_malloc(sizeof(char) *strlen(res->uri) + 1);
+               memset(*value, 0, strlen(res->uri) + 1);
+               things_strncpy(*value, res->uri, strlen(res->uri) + 1);
+       }
+}
+
+int get_num_of_res_types(struct things_resource_s *res)
+{
+       uint8_t num = 0;
+       OCGetNumberOfResourceTypes((OCResourceHandle) res->resource_handle, &num);
+       return (int)num;
+}
+
+const char *get_res_type(struct things_resource_s *res, int index)
+{
+       const char *resourcType = OCGetResourceTypeName((OCResourceHandle) res->resource_handle, index);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====>  RH : %x cnt : %d", res->resource_handle, index);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====>  RT : %s ", resourcType);
+
+       return resourcType;
+}
+
+int get_num_of_inf_types(struct things_resource_s *res)
+{
+       uint8_t num = 0;
+       OCGetNumberOfResourceInterfaces((OCResourceHandle) res->resource_handle, &num);
+       return (int)num;
+}
+
+const char *get_inf_type(struct things_resource_s *res, int index)
+{
+       const char *interface_type = OCGetResourceInterfaceName((OCResourceHandle) res->resource_handle, index);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====>  RH : %x cnt : %d", res->resource_handle, index);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====>  IT : %s ", interface_type);
+
+       return interface_type;
+}
+
+bool things_get_value(struct things_representation_s *rep, char *key, char **value)
+{
+       return OCRepPayloadGetPropString((OCRepPayload *) rep->payload, key, (char **)value);
+}
+
+bool things_get_bool_value(struct things_representation_s *rep, char *key, bool *value)
+{
+       return OCRepPayloadGetPropBool((OCRepPayload *) rep->payload, key, value);
+}
+
+bool things_get_int_value(struct things_representation_s *rep, char *key, int64_t *value)
+{
+       return OCRepPayloadGetPropInt((OCRepPayload *) rep->payload, key, value);
+}
+
+bool things_get_double_value(struct things_representation_s *rep, char *key, double *value)
+{
+       return OCRepPayloadGetPropDouble((OCRepPayload *) rep->payload, key, value);
+}
+
+bool things_get_byte_value(struct things_representation_s *rep, char *key, uint8_t **value, size_t *size)
+{
+       OCByteString b_val = { NULL, 0 };
+       bool ret = OCRepPayloadGetPropByteString((OCRepPayload *) rep->payload, key, &b_val);
+
+       if (true == ret) {
+               (*size) = b_val.len;
+               (*value) = (uint8_t *) things_malloc((*size) + 1);
+               memcpy((*value), b_val.bytes, b_val.len);
+
+               if (b_val.bytes != NULL) {
+                       things_free(b_val.bytes);
+                       b_val.bytes = NULL;
+               }
+       }
+
+       return ret;
+}
+
+bool things_get_object_value(struct things_representation_s *mother, char *key, struct things_representation_s *child)
+{
+       OCRepPayload *payload = NULL;
+       bool ret = OCRepPayloadGetPropObject(mother->payload, key, &payload);
+
+       if (true == ret && NULL != payload) {
+               if (child->payload) {
+                       OCRepPayloadDestroy(child->payload);
+                       child->payload = NULL;
+               }
+               child->payload = payload;
+       }
+       return ret;
+}
+
+bool get_query(struct things_resource_s *res, char *key, char **value)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (NULL == key) {
+               return 0;
+       } else if (NULL == res) {
+               return 0;
+       } else if (NULL == res->query) {
+               return 0;
+       } else if (strlen(res->query) < 1) {
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Query is %s.", res->query);
+
+       *value = NULL;
+
+       char *p_buff = NULL, *p_origin = NULL;
+       char *p_ptr = NULL;
+       char *p_ptr2 = NULL;
+
+       p_origin = p_buff = (char *)things_malloc(strlen(res->query) + 1);
+
+       if (NULL == p_buff || NULL == p_origin) {
+               return 0;
+       }
+
+       memset(p_buff, 0, strlen(res->query) + 1);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "p_buff is initialized by 0.");
+       memcpy(p_buff, res->query, strlen(res->query));
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "p_buff is Initialized as", res->query);
+
+       p_ptr = strtok(p_buff, QUERY_DELIMITER);
+       if (p_ptr != NULL) {
+               p_ptr2 = p_ptr;
+       } else {
+               things_free(p_origin);
+               return 0;
+       }
+       //while (p_ptr != NULL)
+       while (p_ptr2 != NULL) {
+               if (strncmp(p_ptr2, key, strlen(key)) == 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "\tFind Query : %s", p_ptr2 + strlen(key) + 1);
+
+                       duplicate_string(p_ptr2 + strlen(key) + 1, value);
+                       if (NULL == *value) {
+                               things_free(p_origin);
+                               return 1;
+                       }
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "\tRESULT : %s", *value);
+                       break;
+               }
+
+               p_ptr2 = strtok(NULL, QUERY_DELIMITER);
+       }
+
+       things_free(p_origin);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return 1;
+}
+
+struct things_resource_s *get_children(struct things_resource_s *pParent)
+{
+       return pParent->next;
+}
+
+bool get_representation(struct things_resource_s *res, struct things_representation_s **rep)
+{
+       if (res->rep != NULL) {
+               *rep = res->rep;
+               return true;
+       }
+
+       return false;
+}
+
+void /*OCRepPayload */ *create_payload(struct things_resource_s *res, char *query)
+{
+       //    To provide identical pattern for handling the result
+       //       allocating new memory for the payload to delete later
+       OCRepPayload *payload = OCRepPayloadClone((OCRepPayload *)(res->rep->payload));
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Query : %s", query);
+
+       if (query == NULL || (query != NULL && strlen(query) < 1)
+               || strstr(query, OIC_INTERFACE_ACTUATOR) != NULL || strstr(query, OIC_INTERFACE_SENSOR) != NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Including properties & its values only");
+               // Do nothing..
+       } else if (strstr(query, OIC_INTERFACE_BASELINE)) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Including all the properties & its values");
+
+               uint8_t index = 0;
+               uint8_t number_of_interfaces = 0;
+               uint8_t number_of_resource_type = 0;
+
+               OCGetNumberOfResourceInterfaces((OCResourceHandle) res->resource_handle, &number_of_interfaces);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "@@  IF # : %d ", number_of_interfaces);
+               //2.a Find interface type(s) & insert it/them into payload
+               for (index = 0; index < number_of_interfaces; index++) {
+                       const char *interface = OCGetResourceInterfaceName((OCResourceHandle) res->resource_handle, index);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====>  IF : %s ", interface);
+                       OCRepPayloadAddInterface(payload, interface);
+               }
+
+               //3.a Find resource type & insert it into payload
+               OCGetNumberOfResourceTypes((OCResourceHandle) res->resource_handle, &number_of_resource_type);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "@@  RT # : %d ", number_of_resource_type);
+               for (index = 0; index < number_of_resource_type; index++) {
+                       const char *rt = OCGetResourceTypeName((OCResourceHandle) res->resource_handle, index);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "=====>  RT : %s ", rt);
+                       OCRepPayloadAddResourceType(payload, rt);
+               }
+       } else if (strstr(query, OC_RSRVD_INTERFACE_BATCH)) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Batch only supported by Collection Resource");
+       } else if (strstr(query, OC_RSRVD_INTERFACE_LL)) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Link-List only supported by Collection Resource");
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not supporting Interface type : %s", query);
+       }
+
+       return payload;
+}
+
+void /*OCRepPayload */ *get_rep_payload(struct things_resource_s *res)
+{
+       if (res->rep != NULL) {
+               // Create Payload for the mother resource
+               // It applies not only single resource but also the collection resource..
+               things_resource_s *p_temp;
+               OCRepPayload *rep_payload;
+
+               if (NULL != res->things_get_children(res) && (NULL != strstr(res->uri, URI_DEVICE_COL)) && (strstr(res->query, OIC_INTERFACE_BATCH) != NULL)) {
+                       p_temp = res->next;
+                       rep_payload = p_temp->things_create_payload(p_temp, p_temp->query);
+                       p_temp = p_temp->next;
+               }
+
+               else {
+                       rep_payload = res->things_create_payload(res, res->query);
+                       // Create payload for the children resource(s)
+                       p_temp = res->things_get_children(res);
+               }
+
+               while (NULL != p_temp) {
+                       if (NULL != p_temp->rep) {
+                               OCRepPayloadAppend(rep_payload, p_temp->things_create_payload(p_temp, p_temp->query));
+                       }
+                       p_temp = p_temp->next;
+               }
+
+               return rep_payload;
+       } else {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "ROOT(Parent) Paylaod is NULL.");
+               return NULL;
+       }
+}
+
+bool is_supporting_interface_type(struct things_resource_s *res, char *query)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       bool result = false;
+       uint8_t number_of_interfaces = 0;
+
+       OCGetNumberOfResourceInterfaces((OCResourceHandle) res->resource_handle, &number_of_interfaces);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "@@  IF # : %d ", number_of_interfaces);
+       //2.a Find interface type(s) & insert it/them into payload
+       for (uint8_t index = 0; index < number_of_interfaces; index++) {
+               const char *interface = OCGetResourceInterfaceName((OCResourceHandle) res->resource_handle, index);
+
+               // THINGS_LOG_D(THINGS_DEBUG, TAG, "Supporting Interface :: %s(%s)", query, interface);
+               if (NULL != query) {
+                       if (strstr(query, interface) != NULL) {
+                               // THINGS_LOG_D(THINGS_DEBUG, TAG, "Confirm Interface.");
+                               result = true;
+                               break;
+                       }
+               }
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return result;
+}
+
+bool is_supporting_resource_type(struct things_resource_s *res, char *query)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       bool result = false;
+       uint8_t number_of_resource_type = 0;
+
+       OCGetNumberOfResourceTypes((OCResourceHandle) res->resource_handle, &number_of_resource_type);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "@@  RT # : %d ", number_of_resource_type);
+       //2.a Find resource type(s) & insert it/them into payload
+       for (uint8_t index = 0; index < number_of_resource_type; index++) {
+               const char *rtype = OCGetResourceTypeName((OCResourceHandle) res->resource_handle, index);
+
+               // THINGS_LOG_D(THINGS_DEBUG, TAG, "Supporting rtype :: %s(%s)", query, rtype);
+               if (strstr(query, rtype) != NULL) {
+                       // THINGS_LOG_D(THINGS_DEBUG, TAG, "Confirm rtype.");
+                       result = true;
+                       break;
+               }
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return result;
+}
+
+void set_command_id(things_resource_s *res, char *cmd_id)
+{
+       duplicate_string(cmd_id, &res->cmd_id);
+}
+
+things_resource_s *get_next(things_resource_s *res)
+{
+       if (NULL != res) {
+               if (NULL != res->next) {
+                       return res->next;
+               }
+       }
+
+       return NULL;
+}
+
+void add_child(things_resource_s *root, things_resource_s *child)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       things_resource_s *p_node = NULL;
+
+       p_node = root;
+       while (NULL != p_node->things_get_next(p_node)) {
+               p_node = p_node->things_get_next(p_node);
+       }
+
+       p_node->next = child;
+       root->size++;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+things_representation_s *things_create_representation_inst(void *rep_payload)
+{
+       things_representation_s *rep = (things_representation_s *) things_malloc(sizeof(things_representation_s));
+       if (NULL == rep) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, THINGS_MEMORY_ERROR);
+               return NULL;
+       }
+
+       rep->things_set_value = &things_set_value;
+       rep->things_set_bool_value = &things_set_bool_value;
+       rep->things_set_double_value = &things_set_double_value;
+       rep->things_set_int_value = &things_set_int_value;
+       rep->things_set_byte_value = &things_set_byte_value;
+       rep->things_set_object_value = &things_set_object_value;
+
+       rep->things_set_arrayvalue = &things_set_arrayvalue;
+       rep->things_get_arrayvalue = &things_get_arrayvalue;
+       rep->things_set_string_arrayvalue = &things_set_string_arrayvalue;
+       rep->things_get_string_arrayvalue = &things_get_string_arrayvalue;
+
+       rep->things_set_double_arrayvalue = &things_set_double_arrayvalue;
+       rep->things_get_double_arrayvalue = &things_get_double_arrayvalue;
+       rep->things_set_int_arrayvalue = &things_set_int_arrayvalue;
+       rep->things_get_int_arrayvalue = &things_get_int_arrayvalue;
+
+       rep->things_get_value = &things_get_value;
+       rep->things_get_bool_value = &things_get_bool_value;
+       rep->things_get_int_value = &things_get_int_value;
+       rep->things_get_double_value = &things_get_double_value;
+       rep->things_get_byte_value = &things_get_byte_value;
+       rep->things_get_object_value = &things_get_object_value;
+
+       rep->payload = NULL;
+       rep->children_payload = NULL;
+       rep->children = NULL;
+       rep->num_children = 0;
+
+       if (rep_payload != NULL) {
+               rep->payload = OCRepPayloadClone((OCRepPayload *) rep_payload);
+       } else {
+               rep->payload = OCRepPayloadCreate();
+       }
+
+       return rep;
+}
+
+things_resource_s *create_resource_inst_impl(void *requesthd, void *resourcehd, void *query, void *rep_payload)
+{
+       things_resource_s *res = (things_resource_s *) things_malloc(sizeof(things_resource_s));
+       if (NULL == res) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, THINGS_MEMORY_ERROR);
+               return NULL;
+       }
+
+       res->error = 0;                         // OC_EH_OK;
+
+       res->dev_addr = NULL;
+
+       res->things_set_dev_addr = &set_dev_addr;
+       res->things_get_dev_addr = &get_dev_addr;
+
+       res->things_set_uri = &set_uri;
+       res->things_set_error = &set_error;
+
+       res->things_set_command_id = &set_command_id;
+
+       res->things_add_child = &add_child;
+       res->things_get_children = &get_children;
+
+       res->things_get_uri = &get_uri;
+       res->things_get_res_type = &get_res_type;
+       res->things_get_num_of_res_types = &get_num_of_res_types;
+       res->things_get_inf_type = &get_inf_type;
+       res->things_get_num_of_inf_types = &get_num_of_inf_types;
+       res->things_set_representation = &set_representation;
+       res->things_get_representation = &get_representation;
+
+       res->things_get_query = &get_query;
+       res->things_get_rep_payload = &get_rep_payload;
+       res->things_create_payload = &create_payload;
+       res->things_is_supporting_interface_type = &is_supporting_interface_type;
+       res->things_is_supporting_resource_type = &is_supporting_resource_type;
+
+       res->next = NULL;
+       res->things_get_next = &get_next;
+
+       res->resource_handle = resourcehd;
+       res->request_handle = requesthd;
+
+       res->uri = NULL;
+       const char *uri = OCGetResourceUri(resourcehd);
+       if (uri != NULL && strlen(uri) > 0) {
+               res->uri = (char *)things_malloc(sizeof(char) * strlen(uri) + 1);
+               memset(res->uri, 0, strlen(uri) + 1);
+               things_strncpy(res->uri, uri, strlen(uri));
+       }
+
+       res->res_type = NULL;
+       res->interface_type = NULL;
+       res->req_type = 0;
+       res->cmd_id = NULL;
+       res->rep = NULL;
+       res->query = NULL;
+       res->size = 1;
+
+       if (NULL != query) {
+               duplicate_string((char *)query, &(res->query));
+       }
+
+       if (NULL != rep_payload) {
+               res->rep = things_create_representation_inst(rep_payload);
+       }
+       // else
+       // {
+       //     THINGS_LOG_D(THINGS_DEBUG,TAG, "Representation not created!!");
+       // }
+
+       return res;
+}
+
+things_resource_s *things_create_resource_inst(OCRequestHandle requesthd, OCResourceHandle resourcehd, void *query, void *rep_payload)
+{
+       things_resource_s *res = create_resource_inst_impl(requesthd,
+                                                        resourcehd,
+                                                        query,
+                                                        rep_payload);
+
+       if (NULL != rep_payload) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Representation Inserted to Clone~!!!");
+               OCRepPayload *pl = ((OCRepPayload *) rep_payload)->next;
+
+               things_resource_s *pTempRes = NULL;
+               while (pl) {
+                       if (NULL != pl->uri) {
+                               pTempRes = create_resource_inst_impl(requesthd, resourcehd, NULL, pl);
+
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Child Resource URI : %s", pl->uri);
+                               pTempRes->things_set_uri(pTempRes, pl->uri);
+                               res->things_add_child(res, pTempRes);
+                               //res->size++;
+                       } else {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "No Uri in this payload for child, this payload was ignored.");
+                       }
+
+                       pl = pl->next;
+               }
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "\t Child Count : %d", res->size);
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "No Representation to Clone : %x", rep_payload);
+       }
+
+       return res;
+}
+
+// BTD
+things_resource_s *clone_resource_inst(things_resource_s *pori)
+{
+       if (pori == NULL) {
+               return NULL;
+       }
+
+       things_resource_s *pclone = create_resource_inst_impl(pori->request_handle,
+                                                               pori->resource_handle,
+                                                               pori->query,
+                                                               (pori->rep == NULL) ? NULL : pori->rep->payload);
+       pclone->things_set_uri(pclone, pori->uri);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "@@@@@@@@@@@@@@@ URI  %s", pclone->uri);
+
+       things_resource_s *p_temp = pori->next;
+       while (p_temp) {
+               things_resource_s *p_new = create_resource_inst_impl(p_temp->request_handle,
+                                                                  p_temp->resource_handle,
+                                                                  p_temp->query,
+                                                                  ((p_temp->rep == NULL) ? NULL : p_temp->rep->payload));
+
+               p_new->things_set_uri(p_new, p_temp->uri);
+               p_temp->things_add_child(p_temp, p_new);
+               p_temp = p_temp->next;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "@@@@@@@@@@@@@@@ Address of cloned %x", pclone);
+       return pclone;
+}
+
+void things_clone_resource_inst2(things_resource_s *pori, things_resource_s **pclone)
+{
+       if (pori == NULL) {
+               return;
+       }
+
+       *pclone = create_resource_inst_impl(pori->request_handle, pori->resource_handle, pori->query, ((pori->rep == NULL) ? NULL : pori->rep->payload));
+
+       (*pclone)->things_set_uri(*pclone, pori->uri);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "@@@@@@@@@@@@@@@ URI  %s", (*pclone)->uri);
+
+       return;
+}
+
+void things_release_representation_inst(things_representation_s *rep)
+{
+       if (rep != NULL) {
+               if (rep->children_payload != NULL) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Representation has %lld Children.", rep->num_children);
+                       for (int64_t iter = 0; iter < rep->num_children; iter++) {
+                               if ((rep->children_payload[iter]) != NULL) {
+                                       THINGS_LOG_D(THINGS_DEBUG, TAG, "\t RELEASED.");
+                                       OCPayloadDestroy((OCPayload *)(rep->children_payload[iter]));
+                                       rep->children_payload[iter] = NULL;
+                               }
+                       }
+               }
+               if (rep->payload != NULL) {
+                       OCPayloadDestroy((OCPayload *)(rep->payload));
+                       rep->payload = NULL;
+               }
+
+               things_free(rep);
+               rep = NULL;
+       }
+}
+
+void release_resource_inst_impl(things_resource_s *res)
+{
+       if (res != NULL) {
+               if (res->uri != NULL) {
+                       things_free(res->uri);
+                       res->uri = NULL;
+               }
+               if (res->res_type != NULL) {
+                       things_free(res->res_type);
+                       res->res_type = NULL;
+               }
+               if (res->interface_type != NULL) {
+                       things_free(res->interface_type);
+                       res->interface_type = NULL;
+               }
+               if (res->cmd_id != NULL) {
+                       things_free(res->cmd_id);
+                       res->cmd_id = NULL;
+               }
+               if (res->query != NULL) {
+                       things_free(res->query);
+                       res->query = NULL;
+               }
+               if (res->rep != NULL) {
+                       things_release_representation_inst(res->rep);
+               }
+               if (res->dev_addr != NULL) {
+                       things_free(res->dev_addr);
+               }
+               things_free(res);
+               res = NULL;
+       }
+}
+
+void things_release_resource_inst(things_resource_s *res)
+{
+       if (res != NULL) {
+               if (NULL != res->next) {
+                       things_resource_s *p_temp = res->next;
+                       things_resource_s *pDel = NULL;
+                       while (NULL != p_temp) {
+                               pDel = p_temp;
+                               p_temp = p_temp->next;
+
+                               release_resource_inst_impl(pDel);
+                               pDel = NULL;
+                       }
+               }
+
+               release_resource_inst_impl(res);
+               res = NULL;
+       }
+}
diff --git a/framework/src/st_things/things_stack/src/common/framework/things_security_manager.c b/framework/src/st_things/things_stack/src/common/framework/things_security_manager.c
new file mode 100644 (file)
index 0000000..ad8a93e
--- /dev/null
@@ -0,0 +1,1164 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 <stdlib.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+#include <netpacket/packet.h>
+
+#include "securevirtualresourcetypes.h"
+
+//Added as workround to test cert based (D)TLS connection
+#include "srmresourcestrings.h"
+
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_security_manager.h"
+#include "things_common.h"
+#include "credresource.h"
+#include "ss_sha2.h"
+#include "oxmverifycommon.h"
+#include "oic_string.h"
+#include "utlist.h"
+#include "aclresource.h"
+#include "srmutility.h"
+
+#include <wifi_manager/wifi_manager.h>
+
+#if defined(CONFIG_TLS_WITH_SSS) && defined(CONFIG_HW_ECDSA)
+#if defined(CONFIG_IOTIVITY_SSS_STORAGE)       // pkss
+#ifndef USE_SSS
+#define USE_SSS
+#endif
+#endif                                                 // pkss
+#endif
+
+#define TAG "OIC_SEC_MGR"
+
+typedef enum {
+       OIC_SEC_OK = 0,
+       OIC_SEC_ERROR = 1,
+       OIC_SEC_INVALID_PARAM = 2
+} OICSecurityResult;
+
+#if __MIPS__
+#define STRING_SVR_DB_PATH "/data1/oic_svr_db_server.dat"
+#elif __TIZEN__
+#define STRING_SVR_DB_PATH "/opt/data/ocfData/oic_svr_db_server.dat"
+#else
+#define STRING_SVR_DB_PATH "./oic_svr_db_server.dat"
+#endif
+
+#define MD_MAX_LEN 64
+#define MAC_BUF_SIZE 64
+#define MAX_PATH_LEN 100
+
+static char SVR_DB_PATH[MAX_PATH_LEN] = { 0 };
+
+static things_auth_type_e g_auth_type = AUTH_JUST_WORKS;
+static bool g_is_svr_db_exist = false;
+static bool g_is_mfg_cert_required = false;
+#ifdef __ST_THINGS_RTOS__
+#define USER_CONFIRM 1
+#define SetVerifyOption(x) {}
+#define sync() {}
+#endif
+const unsigned char OIC_SVR_DB_COMMON[] = {
+       0xBF, 0x63, 0x61, 0x63, 0x6C, 0x59, 0x03, 0x2B, 0xA4, 0x66, 0x61, 0x63, 0x6C, 0x69, 0x73, 0x74,
+       0xA1, 0x64, 0x61, 0x63, 0x65, 0x73, 0x84, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74,
+       0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73,
+       0x83, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x68, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73,
+       0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63, 0x2E, 0x77, 0x6B, 0x2E, 0x72, 0x65, 0x73, 0x62,
+       0x69, 0x66, 0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x6C, 0x6C, 0x63, 0x72, 0x65,
+       0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x64, 0x62,
+       0x72, 0x74, 0x81, 0x68, 0x6F, 0x69, 0x63, 0x2E, 0x77, 0x6B, 0x2E, 0x64, 0x62, 0x69, 0x66, 0x82,
+       0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65,
+       0x68, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x72, 0x63, 0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64,
+       0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x70, 0x62, 0x72, 0x74, 0x81, 0x68,
+       0x6F, 0x69, 0x63, 0x2E, 0x77, 0x6B, 0x2E, 0x70, 0x62, 0x69, 0x66, 0x82, 0x6F, 0x6F, 0x69, 0x63,
+       0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x68, 0x6F, 0x69, 0x63,
+       0x2E, 0x69, 0x66, 0x2E, 0x72, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69,
+       0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75,
+       0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x84,
+       0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F,
+       0x64, 0x6F, 0x78, 0x6D, 0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64,
+       0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62,
+       0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72,
+       0x65, 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x70, 0x73, 0x74, 0x61,
+       0x74, 0x62, 0x72, 0x74, 0x81, 0x6B, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x70, 0x73, 0x74, 0x61,
+       0x74, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73,
+       0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66,
+       0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x61, 0x63, 0x6C, 0x62, 0x72, 0x74,
+       0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x61, 0x63, 0x6C, 0x62, 0x69, 0x66, 0x81, 0x6F,
+       0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63,
+       0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F,
+       0x73, 0x65, 0x63, 0x2F, 0x63, 0x72, 0x65, 0x64, 0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63,
+       0x2E, 0x72, 0x2E, 0x63, 0x72, 0x65, 0x64, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E,
+       0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60,
+       0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75,
+       0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F,
+       0x75, 0x72, 0x63, 0x65, 0x73, 0x81, 0xA3, 0x64, 0x68, 0x72, 0x65, 0x66, 0x75, 0x2F, 0x73, 0x65,
+       0x63, 0x2F, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x69, 0x6E, 0x67, 0x69, 0x6E,
+       0x66, 0x6F, 0x62, 0x72, 0x74, 0x81, 0x78, 0x1E, 0x78, 0x2E, 0x63, 0x6F, 0x6D, 0x2E, 0x73, 0x61,
+       0x6D, 0x73, 0x75, 0x6E, 0x67, 0x2E, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x69,
+       0x6E, 0x67, 0x69, 0x6E, 0x66, 0x6F, 0x62, 0x69, 0x66, 0x81, 0x68, 0x6F, 0x69, 0x63, 0x2E, 0x69,
+       0x66, 0x2E, 0x61, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x07, 0xA3,
+       0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72,
+       0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x81, 0xA3, 0x64, 0x68, 0x72, 0x65, 0x66, 0x74,
+       0x2F, 0x73, 0x65, 0x63, 0x2F, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x70, 0x6F, 0x69, 0x6E, 0x74,
+       0x6C, 0x69, 0x73, 0x74, 0x62, 0x72, 0x74, 0x81, 0x78, 0x1D, 0x78, 0x2E, 0x63, 0x6F, 0x6D, 0x2E,
+       0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x2E, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x70, 0x6F,
+       0x69, 0x6E, 0x74, 0x6C, 0x69, 0x73, 0x74, 0x62, 0x69, 0x66, 0x81, 0x68, 0x6F, 0x69, 0x63, 0x2E,
+       0x69, 0x66, 0x2E, 0x73, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02,
+       0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x30, 0x30, 0x30,
+       0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D,
+       0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+       0x30, 0x62, 0x72, 0x74, 0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x61, 0x63, 0x6C, 0x62,
+       0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C,
+       0x69, 0x6E, 0x65, 0x65, 0x70, 0x73, 0x74, 0x61, 0x74, 0x58, 0x9D, 0xA9, 0x64, 0x69, 0x73, 0x6F,
+       0x70, 0xF4, 0x62, 0x63, 0x6D, 0x02, 0x62, 0x74, 0x6D, 0x00, 0x62, 0x6F, 0x6D, 0x04, 0x62, 0x73,
+       0x6D, 0x04, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x30,
+       0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30,
+       0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+       0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24,
+       0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30,
+       0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+       0x30, 0x30, 0x30, 0x30, 0x62, 0x72, 0x74, 0x81, 0x6B, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x70,
+       0x73, 0x74, 0x61, 0x74, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E,
+       0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x64, 0x64, 0x6F, 0x78, 0x6D, 0x58
+};
+
+//, 0xD9 + oxm array size /*length of doxm header + length of doxm payload */,
+#define DOXM_PAYLOAD_SIZE (0xD4)
+
+const unsigned char OIC_SVR_DB_DOXM_HEADER[] = {
+       0xBF, 0x64, 0x6F, 0x78, 0x6D, 0x73
+};
+
+//0x80 + oxm array size /*oxm size*/,
+#define DOXM_OXM_SIZE (0x80)
+
+// 0x00, 0x01, 0x02 : oxm value as array
+
+const unsigned char OIC_SVR_DB_DOXM_PAYLOAD[] = {
+       0x66, 0x6F, 0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77,
+       0x6E, 0x65, 0x64, 0xF4, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78,
+       0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30,
+       0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+       0x30, 0x30, 0x30, 0x30, 0x30, /*0x63, 0x6D, 0x6F, 0x6D, 0x01, *//*"mom":1 */ 0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77,
+       0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+       0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30,
+       0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F,
+       0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+       0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30,
+       0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x62, 0x72,
+       0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64, 0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66,
+       0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E,
+       0x65, 0xFF, 0xFF
+};
+
+FILE *server_fopen(const char *path, const char *mode) // pkss
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "F SVR DB File Path : %s", SVR_DB_PATH);
+       (void)path;
+       return fopen(SVR_DB_PATH, mode);
+}
+
+size_t server_fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream)
+{
+       struct timeval start, end;
+       size_t ret = 0;
+       gettimeofday(&start, NULL);
+       ret = fread(ptr, size, n_items, stream);
+       gettimeofday(&end, NULL);
+       return ret;
+}
+
+size_t server_fwrite(FAR const void *ptr, size_t size, size_t n_items, FAR FILE *stream)
+{
+       struct timeval start, end;
+       size_t ret = 0;
+       gettimeofday(&start, NULL);
+
+       ret = fwrite(ptr, size, n_items, stream);
+
+       gettimeofday(&end, NULL);
+       return ret;
+}
+
+int server_fclose(FILE *stream)
+{
+       int ret = fclose(stream);
+       return ret;
+}
+
+/*
+ * This API Setup Seckey from filepath
+ */
+static OCStackResult seckey_setup(const char *filename, OicSecKey_t *key, OicEncodingType_t encoding)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IN: %s", __func__);
+
+       size_t size = 0;
+       key->data = NULL;
+       key->len = 0;
+       key->encoding = OIC_ENCODING_UNKNOW;
+       FILE *fp = fopen(filename, "rb");
+
+       if (fp == NULL) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "Can not open file[%s].", filename);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OUT[FAIL]: %s", __func__);
+               return OC_STACK_ERROR;
+       }
+
+       if (0 == fseek(fp, 0L, SEEK_END)) {
+               size = ftell(fp);
+               rewind(fp);
+               key->data = (uint8_t *) things_malloc(size);
+               if (key->data == NULL) {
+                       THINGS_LOG_D(THINGS_ERROR, TAG, "Memory Full");
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "OUT[FAIL]: %s", __func__);
+                       return OC_STACK_NO_MEMORY;
+               }
+               fread(key->data, 1, size, fp);
+               key->len = size;
+               key->encoding = encoding;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "OUT: %s", __func__);
+       return OC_STACK_OK;
+}
+
+/*
+ * This API added as workaround to test certificate based (D)TLS connection.
+ * It will be replaced to use TZ or eSE based key protection.
+ */
+static OCStackResult save_signed_asymmetric_key(OicUuid_t *subject_uuid);
+
+static int GenerateSvrDb()
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "In %s", __func__);
+
+       if (AUTH_UNKNOW == g_auth_type) {
+               THINGS_LOG(THINGS_INFO, TAG, "Unknown authentication type for ownership transfer.");
+               THINGS_LOG(THINGS_INFO, TAG, "please make sure your configuration in json file.");
+               THINGS_LOG(THINGS_INFO, TAG, "----------------------");
+               THINGS_LOG(THINGS_INFO, TAG, "Justwork authentication will be used as default authentication method.");
+               THINGS_LOG(THINGS_INFO, TAG, "----------------------");
+               g_auth_type = AUTH_JUST_WORKS;
+       }
+
+       FILE *fp = NULL;
+       fp = fopen(SVR_DB_PATH, "w");
+
+       OICSecurityResult res = OIC_SEC_ERROR;
+
+       if (NULL != fp) {
+               int idx = 0;
+               unsigned char *svrdb = NULL;
+               unsigned char *cur_pos = NULL;
+               //To generate OxM Array.
+               uint16_t oxms[OIC_OXM_COUNT + 3 /*Number of vendor specific OxM */] = { 0 };
+               size_t oxm_cnt = 0;
+               size_t oxm_size = 0;
+               size_t svrdb_size = 0;
+
+               if (g_auth_type & AUTH_JUST_WORKS) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Justworks OxM.");
+                       oxms[oxm_cnt++] = OIC_JUST_WORKS;
+                       oxm_size++;
+               }
+               if (g_auth_type & AUTH_RANDOM_PIN) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Random PIN based OxM.");
+                       oxms[oxm_cnt++] = OIC_RANDOM_DEVICE_PIN;
+                       oxm_size++;
+               }
+               if (g_auth_type & AUTH_CERTIFICATE || g_auth_type & AUTH_CERTIFICATE_CONFIRM) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Certificate based OxM.");
+                       oxms[oxm_cnt++] = OIC_MANUFACTURER_CERTIFICATE;
+                       oxm_size++;
+               }
+               if (g_auth_type & AUTH_DECENTRALIZED_PUB_KEY) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Decentralized public key based OxM.");
+                       oxms[oxm_cnt++] = OIC_DECENTRALIZED_PUBLIC_KEY;
+                       oxm_size++;
+               }
+               if (g_auth_type & AUTH_PRECONF_PIN) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Preconfigured-PIN based OxM (for MOT only).");
+                       oxms[oxm_cnt++] = 0xFF00;       //OIC_PRECONFIG_PIN
+                       oxm_size += 3;
+               }
+               if (g_auth_type & AUTH_JUST_WORKS_MUTUAL_VERIFIED) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Mutual Verification Justworks based OxM.");
+                       oxms[oxm_cnt++] = 0xFF01;
+                       oxm_size += 3;
+               }
+               if (g_auth_type & AUTH_CERTIFICATE || g_auth_type & AUTH_CERTIFICATE_CONFIRM) {
+                       THINGS_LOG(THINGS_DEBUG, TAG, "Added Certificate+Confirm based OxM.");
+                       oxms[oxm_cnt++] = 0xFF02;
+                       oxm_size += 3;
+               }
+               if (0 == oxm_cnt) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to extract authentication types.");
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Please make sure your configuration in json file.");
+                       res = OIC_SEC_INVALID_PARAM;
+                       goto error;
+               }
+
+               svrdb_size = sizeof(OIC_SVR_DB_COMMON) + sizeof(OIC_SVR_DB_DOXM_HEADER) + sizeof(OIC_SVR_DB_DOXM_PAYLOAD) + 2 /*size of payload length */  + oxm_size;
+               svrdb = (unsigned char *)things_malloc(svrdb_size + 32);
+               if (NULL == svrdb) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to memory allocation.");
+                       goto error;
+               }
+               //
+               //Generate default SVR DB
+               cur_pos = svrdb;
+
+               //Construct Common part of SVR DB
+               memcpy(cur_pos, OIC_SVR_DB_COMMON, sizeof(OIC_SVR_DB_COMMON));
+               cur_pos += sizeof(OIC_SVR_DB_COMMON);
+
+               //Construct Doxm payload size
+               *cur_pos = (unsigned char)(DOXM_PAYLOAD_SIZE + oxm_size);
+               cur_pos++;
+
+               //Construct Doxm Header
+               memcpy(cur_pos, OIC_SVR_DB_DOXM_HEADER, sizeof(OIC_SVR_DB_DOXM_HEADER));
+               cur_pos += sizeof(OIC_SVR_DB_DOXM_HEADER);
+
+               //Construct Length of OxM array
+               *cur_pos = (unsigned char)(DOXM_OXM_SIZE + oxm_cnt);
+               cur_pos++;
+
+               //Construct OxM array
+               for (idx = 0; idx < oxm_cnt; idx++) {
+                       if (oxms[idx] < OIC_OXM_COUNT) {
+                               *cur_pos = oxms[idx];
+                               cur_pos++;
+                       } else if (oxms[idx] == 0xFF00) {
+                               *cur_pos = 0x19;
+                               cur_pos++;
+                               *cur_pos = 0xFF;
+                               cur_pos++;
+                               *cur_pos = 0x00;
+                               cur_pos++;
+                       } else if (oxms[idx] == 0xFF01) {
+                               *cur_pos = 0x19;
+                               cur_pos++;
+                               *cur_pos = 0xFF;
+                               cur_pos++;
+                               *cur_pos = 0x01;
+                               cur_pos++;
+                       } else if (oxms[idx] == 0xFF02) {
+                               *cur_pos = 0x19;
+                               cur_pos++;
+                               *cur_pos = 0xFF;
+                               cur_pos++;
+                               *cur_pos = 0x02;
+                               cur_pos++;
+                       }
+               }
+
+               //Construct Doxm payload
+               memcpy(cur_pos, OIC_SVR_DB_DOXM_PAYLOAD, sizeof(OIC_SVR_DB_DOXM_PAYLOAD));
+
+               //End of default SVR DB generation
+               //
+
+               //Save the constructed SVR DB into persistent storage.
+               fwrite(svrdb, 1, svrdb_size, fp);
+               fclose(fp);
+               things_free(svrdb);
+               THINGS_LOG_D(THINGS_INFO, TAG, "Out %s", __func__);
+               return OIC_SEC_OK;
+error:
+               fclose(fp);
+               things_free(svrdb);
+               return OIC_SEC_ERROR;
+       } else {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Can not open the [%s], Please make sure the access permision of file system.", SVR_DB_PATH);
+       }
+
+       return res;                                     // return 0 when failed, 1 otherwise..
+}
+
+static int get_mac_addr(unsigned char *p_id_buf, size_t p_id_buf_size, unsigned int *p_id_out_len)
+{
+       char mac_addr[MAC_BUF_SIZE];
+       struct ifaddrs *ifaddr = NULL;
+       struct ifaddrs *ifa = NULL;
+       int family = 0;
+       int i = 0;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "In %s", __func__);
+
+#ifdef __ST_THINGS_RTOS__
+       wifi_manager_info_s st_wifi_info;
+       wifi_manager_get_info(&st_wifi_info);
+
+       if (wifi_manager_get_info(&st_wifi_info) != WIFI_MANAGER_SUCCESS) {
+               
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "MAC Get Error\n");
+               return OIC_SEC_ERROR;
+       }
+
+       snprintf((char *)p_id_buf, MAC_BUF_SIZE - 1, "%02X%02X%02X%02X%02X%02X", st_wifi_info.mac_address[0], st_wifi_info.mac_address[1], st_wifi_info.mac_address[2], st_wifi_info.mac_address[3], st_wifi_info.mac_address[4], st_wifi_info.mac_address[5]);
+#else
+       if (getifaddrs(&ifaddr) == -1) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Failed to read network address information.");
+               return OIC_SEC_ERROR;
+       } else {
+               for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+                       if ((ifa->ifa_addr) && (ifa->ifa_addr->sa_family == AF_PACKET)) {
+                               struct sockaddr_ll *s = (struct sockaddr_ll *)ifa->ifa_addr;
+
+                               memset(p_id_buf, 0x00, p_id_buf_size);
+                               for (i = 0; i < s->sll_halen && i < p_id_buf_size; i++) {
+                                       snprintf((char *)(p_id_buf + (i * 2)), MAC_BUF_SIZE - i, "%02X", (s->sll_addr[i]));
+                               }
+                       }
+               }
+               freeifaddrs(ifaddr);
+       }
+#endif
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "MAC Address : %s", (char *)p_id_buf);
+       *p_id_out_len = strlen((char *)p_id_buf);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Out %s", __func__);
+
+       return OIC_SEC_OK;
+}
+
+// ++ Added by Chul Lee : To support MAC based UUID
+int sm_generate_mac_based_device_id(bool is_forced)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "In %s", __func__);
+
+       if (g_is_svr_db_exist && !is_forced) {
+               THINGS_LOG_D(THINGS_WARNING, TAG, "MAC based device UUID generation is not required.");
+               return OIC_SEC_OK;
+       }
+
+       OICSecurityResult res = OIC_SEC_ERROR;
+       OicUuid_t device_id;
+       unsigned char mac_id[MAC_BUF_SIZE];
+       unsigned char hash_value[SS_SHA256_DIGEST_SIZE + 1];
+       unsigned int id_len = 0;
+
+       res = get_mac_addr(mac_id, MAC_BUF_SIZE, &id_len);
+       if (OIC_SEC_OK != res) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to read MAC Address.");
+               return res;
+       }
+       THINGS_LOG_V(THINGS_INFO, TAG, "MAC Address : %s", mac_id);
+
+       ss_sha256_ctx sha256_ctx;
+       ss_sha256_init(&sha256_ctx);
+       ss_sha256_update(&sha256_ctx, mac_id, id_len);
+       ss_sha256_final(&sha256_ctx, hash_value);
+
+       memcpy(device_id.id, hash_value, sizeof(device_id.id));
+
+       OCStackResult oc_res = SetDoxmDeviceID(&device_id);
+       if (OC_STACK_OK != oc_res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Error in SetDoxmDeviceID : %d", (int)oc_res);
+               return OIC_SEC_ERROR;
+       }
+       // Added as workaround for cert based D2D & D2S connection
+       oc_res = save_signed_asymmetric_key(&device_id);
+       if (OC_STACK_OK != oc_res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Error in save_signed_asymmetric_key : %d", (int)oc_res);
+               return OIC_SEC_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Out %s", __func__);
+
+       return res;
+}
+
+// ++ Added by Chul Lee : To support MAC based UUID
+//
+
+int sm_init_things_security(int auth_type, const char *db_path)
+{
+       OICSecurityResult res = OIC_SEC_ERROR;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "In %s", __func__);
+
+       memset(SVR_DB_PATH, 0x00, MAX_PATH_LEN);
+
+       if (db_path != NULL && strlen(db_path) > 0) {
+               things_strncpy(SVR_DB_PATH, db_path, MAX_PATH_LEN);
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "DB Path Not Inserted. Using Default Value");
+               things_strncpy(SVR_DB_PATH, STRING_SVR_DB_PATH, MAX_PATH_LEN);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "SVR DB PATH : %s", SVR_DB_PATH);
+
+       g_auth_type = auth_type;
+       if ((g_auth_type & AUTH_JUST_WORKS_MUTUAL_VERIFIED) || (g_auth_type & AUTH_CERTIFICATE_CONFIRM)) {
+               SetVerifyOption(USER_CONFIRM);
+       }
+
+       g_is_mfg_cert_required = false;
+       if ((g_auth_type & AUTH_CERTIFICATE) || (g_auth_type & AUTH_CERTIFICATE_CONFIRM)) {
+               g_is_mfg_cert_required = true;
+       }
+
+       res = SM_InitSvrDb();
+       if (OIC_SEC_OK != res) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to create SVR DB.");
+               return res;
+       }
+
+       static OCPersistentStorage ps = { server_fopen, server_fread, server_fwrite, server_fclose, unlink };
+       THINGS_LOG(THINGS_INFO, TAG, "******* WARNING : SVR DB will be used without encryption *******");
+       
+       OCStackResult oc_res = OCRegisterPersistentStorageHandler(&ps);
+       if (OC_STACK_INCONSISTENT_DB == oc_res || OC_STACK_SVR_DB_NOT_EXIST == oc_res) {
+               //If failed to load SVR DB
+               THINGS_LOG_D(THINGS_WARNING, TAG, "SVR DB[%s] is inconsistent or not exist : %d", SVR_DB_PATH, oc_res);
+               THINGS_LOG_D(THINGS_WARNING, TAG, "SVR DB will be reinstalled as default SVR DB.");
+
+               //re-generate and re-install SVR DB
+               g_is_svr_db_exist = false;
+               res = SM_InitSvrDb();
+               if (OIC_SEC_OK != res) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to create SVR DB.");
+                       return res;
+               }
+               //Re-register PSI
+               oc_res = OCRegisterPersistentStorageHandler(&ps);
+               if (OC_STACK_OK != oc_res) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Failed to register persistent storage for SVR DB : %d", (int)oc_res);
+                       return OIC_SEC_ERROR;
+               }
+       } else if (OC_STACK_OK != oc_res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Failed to register persistent storage for SVR DB : %d", (int)oc_res);
+               return OIC_SEC_ERROR;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Out %s", __func__);
+
+       return OIC_SEC_OK;
+}
+
+int SM_InitSvrDb()
+{
+       FILE *fp = fopen(SVR_DB_PATH, "r");
+       if (fp == NULL) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "Can not find the [%s], SVR DB will be automatically generated...", SVR_DB_PATH);
+               THINGS_LOG_D(THINGS_INFO, TAG, "Out %s", __func__);
+               return GenerateSvrDb();
+       } else {
+               THINGS_LOG_D(THINGS_INFO, TAG, "SVR DB [%s] is already exist.", SVR_DB_PATH);
+               g_is_svr_db_exist = true;
+       }
+
+       fclose(fp);
+       THINGS_LOG_D(THINGS_INFO, TAG, "Out %s", __func__);
+
+       return OIC_SEC_OK;
+}
+
+int sm_reset_svrdb()
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "In %s", __func__);
+       OCStackResult oc_res = ResetSecureResourceInPS();
+       if (OC_STACK_OK != oc_res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "ResetSecureResourceInPS error : %d", oc_res);
+               return OIC_SEC_ERROR;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Out %s", __func__);
+       return OIC_SEC_OK;
+}
+
+//
+// ++ Added by Chul Lee : to test certificate based (D)TLS connection for  D2D & D2S
+
+#ifndef _EXCLUDE_TEST_KEY_
+static OicSecKey_t primary_cert;
+static OicSecKey_t primary_key;
+// static OicSecKey_t mfgPrimaryCert;
+// static OicSecKey_t mfgPrimaryKey;
+#endif                                                 //_EXCLUDE_TEST_KEY_
+
+//thawte_Primary_Root_CA.der
+const unsigned char g_global_ci_root_ca[] = {
+       0x30, 0x82, 0x04, 0x20, 0x30, 0x82, 0x03, 0x08, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x34, 0x4E, 0xD5, 0x57, 0x20,
+       0xD5, 0xED, 0xEC, 0x49, 0xF4, 0x2F, 0xCE, 0x37, 0xDB, 0x2B, 0x6D, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
+       0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xA9, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+       0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C,
+       0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1F, 0x43, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+       0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x2F, 0x28, 0x63,
+       0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20,
+       0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+       0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77,
+       0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1E,
+       0x17, 0x0D, 0x30, 0x36, 0x31, 0x31, 0x31, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x33, 0x36, 0x30,
+       0x37, 0x31, 0x36, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0xA9, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+       0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61,
+       0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1F,
+       0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+       0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B,
+       0x13, 0x2F, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49,
+       0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64,
+       0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16,
+       0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20,
+       0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
+       0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xAC, 0xA0, 0xF0, 0xFB, 0x80,
+       0x59, 0xD4, 0x9C, 0xC7, 0xA4, 0xCF, 0x9D, 0xA1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0C, 0x0D, 0x2C, 0x6E, 0x68, 0xF1, 0x6C,
+       0x5B, 0x48, 0x68, 0x49, 0x59, 0x37, 0xFC, 0x0B, 0x33, 0x19, 0xC2, 0x77, 0x7F, 0xCC, 0x10, 0x2D, 0x95, 0x34, 0x1C, 0xE6,
+       0xEB, 0x4D, 0x09, 0xA7, 0x1C, 0xD2, 0xB8, 0xC9, 0x97, 0x36, 0x02, 0xB7, 0x89, 0xD4, 0x24, 0x5F, 0x06, 0xC0, 0xCC, 0x44,
+       0x94, 0x94, 0x8D, 0x02, 0x62, 0x6F, 0xEB, 0x5A, 0xDD, 0x11, 0x8D, 0x28, 0x9A, 0x5C, 0x84, 0x90, 0x10, 0x7A, 0x0D, 0xBD,
+       0x74, 0x66, 0x2F, 0x6A, 0x38, 0xA0, 0xE2, 0xD5, 0x54, 0x44, 0xEB, 0x1D, 0x07, 0x9F, 0x07, 0xBA, 0x6F, 0xEE, 0xE9, 0xFD,
+       0x4E, 0x0B, 0x29, 0xF5, 0x3E, 0x84, 0xA0, 0x01, 0xF1, 0x9C, 0xAB, 0xF8, 0x1C, 0x7E, 0x89, 0xA4, 0xE8, 0xA1, 0xD8, 0x71,
+       0x65, 0x0D, 0xA3, 0x51, 0x7B, 0xEE, 0xBC, 0xD2, 0x22, 0x60, 0x0D, 0xB9, 0x5B, 0x9D, 0xDF, 0xBA, 0xFC, 0x51, 0x5B, 0x0B,
+       0xAF, 0x98, 0xB2, 0xE9, 0x2E, 0xE9, 0x04, 0xE8, 0x62, 0x87, 0xDE, 0x2B, 0xC8, 0xD7, 0x4E, 0xC1, 0x4C, 0x64, 0x1E, 0xDD,
+       0xCF, 0x87, 0x58, 0xBA, 0x4A, 0x4F, 0xCA, 0x68, 0x07, 0x1D, 0x1C, 0x9D, 0x4A, 0xC6, 0xD5, 0x2F, 0x91, 0xCC, 0x7C, 0x71,
+       0x72, 0x1C, 0xC5, 0xC0, 0x67, 0xEB, 0x32, 0xFD, 0xC9, 0x92, 0x5C, 0x94, 0xDA, 0x85, 0xC0, 0x9B, 0xBF, 0x53, 0x7D, 0x2B,
+       0x09, 0xF4, 0x8C, 0x9D, 0x91, 0x1F, 0x97, 0x6A, 0x52, 0xCB, 0xDE, 0x09, 0x36, 0xA4, 0x77, 0xD8, 0x7B, 0x87, 0x50, 0x44,
+       0xD5, 0x3E, 0x6E, 0x29, 0x69, 0xFB, 0x39, 0x49, 0x26, 0x1E, 0x09, 0xA5, 0x80, 0x7B, 0x40, 0x2D, 0xEB, 0xE8, 0x27, 0x85,
+       0xC9, 0xFE, 0x61, 0xFD, 0x7E, 0xE6, 0x7C, 0x97, 0x1D, 0xD5, 0x9D, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x42, 0x30, 0x40,
+       0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06,
+       0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E,
+       0x04, 0x16, 0x04, 0x14, 0x7B, 0x5B, 0x45, 0xCF, 0xAF, 0xCE, 0xCB, 0x7A, 0xFD, 0x31, 0x92, 0x1A, 0x6A, 0xB6, 0xF3, 0x46,
+       0xEB, 0x57, 0x48, 0x50, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+       0x82, 0x01, 0x01, 0x00, 0x79, 0x11, 0xC0, 0x4B, 0xB3, 0x91, 0xB6, 0xFC, 0xF0, 0xE9, 0x67, 0xD4, 0x0D, 0x6E, 0x45, 0xBE,
+       0x55, 0xE8, 0x93, 0xD2, 0xCE, 0x03, 0x3F, 0xED, 0xDA, 0x25, 0xB0, 0x1D, 0x57, 0xCB, 0x1E, 0x3A, 0x76, 0xA0, 0x4C, 0xEC,
+       0x50, 0x76, 0xE8, 0x64, 0x72, 0x0C, 0xA4, 0xA9, 0xF1, 0xB8, 0x8B, 0xD6, 0xD6, 0x87, 0x84, 0xBB, 0x32, 0xE5, 0x41, 0x11,
+       0xC0, 0x77, 0xD9, 0xB3, 0x60, 0x9D, 0xEB, 0x1B, 0xD5, 0xD1, 0x6E, 0x44, 0x44, 0xA9, 0xA6, 0x01, 0xEC, 0x55, 0x62, 0x1D,
+       0x77, 0xB8, 0x5C, 0x8E, 0x48, 0x49, 0x7C, 0x9C, 0x3B, 0x57, 0x11, 0xAC, 0xAD, 0x73, 0x37, 0x8E, 0x2F, 0x78, 0x5C, 0x90,
+       0x68, 0x47, 0xD9, 0x60, 0x60, 0xE6, 0xFC, 0x07, 0x3D, 0x22, 0x20, 0x17, 0xC4, 0xF7, 0x16, 0xE9, 0xC4, 0xD8, 0x72, 0xF9,
+       0xC8, 0x73, 0x7C, 0xDF, 0x16, 0x2F, 0x15, 0xA9, 0x3E, 0xFD, 0x6A, 0x27, 0xB6, 0xA1, 0xEB, 0x5A, 0xBA, 0x98, 0x1F, 0xD5,
+       0xE3, 0x4D, 0x64, 0x0A, 0x9D, 0x13, 0xC8, 0x61, 0xBA, 0xF5, 0x39, 0x1C, 0x87, 0xBA, 0xB8, 0xBD, 0x7B, 0x22, 0x7F, 0xF6,
+       0xFE, 0xAC, 0x40, 0x79, 0xE5, 0xAC, 0x10, 0x6F, 0x3D, 0x8F, 0x1B, 0x79, 0x76, 0x8B, 0xC4, 0x37, 0xB3, 0x21, 0x18, 0x84,
+       0xE5, 0x36, 0x00, 0xEB, 0x63, 0x20, 0x99, 0xB9, 0xE9, 0xFE, 0x33, 0x04, 0xBB, 0x41, 0xC8, 0xC1, 0x02, 0xF9, 0x44, 0x63,
+       0x20, 0x9E, 0x81, 0xCE, 0x42, 0xD3, 0xD6, 0x3F, 0x2C, 0x76, 0xD3, 0x63, 0x9C, 0x59, 0xDD, 0x8F, 0xA6, 0xE1, 0x0E, 0xA0,
+       0x2E, 0x41, 0xF7, 0x2E, 0x95, 0x47, 0xCF, 0xBC, 0xFD, 0x33, 0xF3, 0xF6, 0x0B, 0x61, 0x7E, 0x7E, 0x91, 0x2B, 0x81, 0x47,
+       0xC2, 0x27, 0x30, 0xEE, 0xA7, 0x10, 0x5D, 0x37, 0x8F, 0x5C, 0x39, 0x2B, 0xE4, 0x04, 0xF0, 0x7B, 0x8D, 0x56, 0x8C, 0x68
+};
+
+//thawte_Primary_Root_CA-G2_ECC.der
+const unsigned char g_global_ci_root_ca_g2[] = {
+       0x30, 0x82, 0x02, 0x88, 0x30, 0x82, 0x02, 0x0D, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x35, 0xFC, 0x26, 0x5C, 0xD9,
+       0x84, 0x4F, 0xC9, 0x3D, 0x26, 0x3D, 0x57, 0x9B, 0xAE, 0xD7, 0x56, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
+       0x04, 0x03, 0x03, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+       0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E,
+       0x63, 0x2E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x2F, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30,
+       0x37, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72,
+       0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79,
+       0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72,
+       0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x30, 0x1E,
+       0x17, 0x0D, 0x30, 0x37, 0x31, 0x31, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x33, 0x38, 0x30,
+       0x31, 0x31, 0x38, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+       0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61,
+       0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x2F,
+       0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x37, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63,
+       0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75,
+       0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x74, 0x68,
+       0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41,
+       0x20, 0x2D, 0x20, 0x47, 0x32, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05,
+       0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xA2, 0xD5, 0x9C, 0x82, 0x7B, 0x95, 0x9D, 0xF1, 0x52, 0x78, 0x87,
+       0xFE, 0x8A, 0x16, 0xBF, 0x05, 0xE6, 0xDF, 0xA3, 0x02, 0x4F, 0x0D, 0x07, 0xC6, 0x00, 0x51, 0xBA, 0x0C, 0x02, 0x52, 0x2D,
+       0x22, 0xA4, 0x42, 0x39, 0xC4, 0xFE, 0x8F, 0xEA, 0xC9, 0xC1, 0xBE, 0xD4, 0x4D, 0xFF, 0x9F, 0x7A, 0x9E, 0xE2, 0xB1, 0x7C,
+       0x9A, 0xAD, 0xA7, 0x86, 0x09, 0x73, 0x87, 0xD1, 0xE7, 0x9A, 0xE3, 0x7A, 0xA5, 0xAA, 0x6E, 0xFB, 0xBA, 0xB3, 0x70, 0xC0,
+       0x67, 0x88, 0xA2, 0x35, 0xD4, 0xA3, 0x9A, 0xB1, 0xFD, 0xAD, 0xC2, 0xEF, 0x31, 0xFA, 0xA8, 0xB9, 0xF3, 0xFB, 0x08, 0xC6,
+       0x91, 0xD1, 0xFB, 0x29, 0x95, 0xA3, 0x42, 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04,
+       0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02,
+       0x01, 0x06, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x9A, 0xD8, 0x00, 0x30, 0x00, 0xE7, 0x6B,
+       0x7F, 0x85, 0x18, 0xEE, 0x8B, 0xB6, 0xCE, 0x8A, 0x0C, 0xF8, 0x11, 0xE1, 0xBB, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48,
+       0xCE, 0x3D, 0x04, 0x03, 0x03, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xDD, 0xF8, 0xE0, 0x57, 0x47, 0x5B, 0xA7,
+       0xE6, 0x0A, 0xC3, 0xBD, 0xF5, 0x80, 0x8A, 0x97, 0x35, 0x0D, 0x1B, 0x89, 0x3C, 0x54, 0x86, 0x77, 0x28, 0xCA, 0xA1, 0xF4,
+       0x79, 0xDE, 0xB5, 0xE6, 0x38, 0xB0, 0xF0, 0x65, 0x70, 0x8C, 0x7F, 0x02, 0x54, 0xC2, 0xBF, 0xFF, 0xD8, 0xA1, 0x3E, 0xD9,
+       0xCF, 0x02, 0x31, 0x00, 0xC4, 0x8D, 0x94, 0xFC, 0xDC, 0x53, 0xD2, 0xDC, 0x9D, 0x78, 0x16, 0x1F, 0x15, 0x33, 0x23, 0x53,
+       0x52, 0xE3, 0x5A, 0x31, 0x5D, 0x9D, 0xCA, 0xAE, 0xBD, 0x13, 0x29, 0x44, 0x0D, 0x27, 0x5B, 0xA8, 0xE7, 0x68, 0x9C, 0x12,
+       0xF7, 0x58, 0x3F, 0x2E, 0x72, 0x02, 0x57, 0xA3, 0x8F, 0xA1, 0x14, 0x2E
+};
+
+//thawte_Primary_Root_CA-G3_SHA256.der
+const unsigned char g_global_ci_root_ca_g3[] = {
+       0x30, 0x82, 0x04, 0x2A, 0x30, 0x82, 0x03, 0x12, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x60, 0x01, 0x97, 0xB7, 0x46,
+       0xA7, 0xEA, 0xB4, 0xB4, 0x9A, 0xD6, 0x4B, 0x2F, 0xF7, 0x90, 0xFB, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
+       0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x81, 0xAE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+       0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C,
+       0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1F, 0x43, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+       0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x2F, 0x28, 0x63,
+       0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20,
+       0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+       0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x74, 0x68, 0x61, 0x77,
+       0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D,
+       0x20, 0x47, 0x33, 0x30, 0x1E, 0x17, 0x0D, 0x30, 0x38, 0x30, 0x34, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A,
+       0x17, 0x0D, 0x33, 0x37, 0x31, 0x32, 0x30, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0xAE, 0x31, 0x0B,
+       0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A,
+       0x13, 0x0C, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03,
+       0x55, 0x04, 0x0B, 0x13, 0x1F, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53,
+       0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x38, 0x30, 0x36,
+       0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x2F, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77,
+       0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F,
+       0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03,
+       0x55, 0x04, 0x03, 0x13, 0x1B, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20,
+       0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09,
+       0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A,
+       0x02, 0x82, 0x01, 0x01, 0x00, 0xB2, 0xBF, 0x27, 0x2C, 0xFB, 0xDB, 0xD8, 0x5B, 0xDD, 0x78, 0x7B, 0x1B, 0x9E, 0x77, 0x66,
+       0x81, 0xCB, 0x3E, 0xBC, 0x7C, 0xAE, 0xF3, 0xA6, 0x27, 0x9A, 0x34, 0xA3, 0x68, 0x31, 0x71, 0x38, 0x33, 0x62, 0xE4, 0xF3,
+       0x71, 0x66, 0x79, 0xB1, 0xA9, 0x65, 0xA3, 0xA5, 0x8B, 0xD5, 0x8F, 0x60, 0x2D, 0x3F, 0x42, 0xCC, 0xAA, 0x6B, 0x32, 0xC0,
+       0x23, 0xCB, 0x2C, 0x41, 0xDD, 0xE4, 0xDF, 0xFC, 0x61, 0x9C, 0xE2, 0x73, 0xB2, 0x22, 0x95, 0x11, 0x43, 0x18, 0x5F, 0xC4,
+       0xB6, 0x1F, 0x57, 0x6C, 0x0A, 0x05, 0x58, 0x22, 0xC8, 0x36, 0x4C, 0x3A, 0x7C, 0xA5, 0xD1, 0xCF, 0x86, 0xAF, 0x88, 0xA7,
+       0x44, 0x02, 0x13, 0x74, 0x71, 0x73, 0x0A, 0x42, 0x59, 0x02, 0xF8, 0x1B, 0x14, 0x6B, 0x42, 0xDF, 0x6F, 0x5F, 0xBA, 0x6B,
+       0x82, 0xA2, 0x9D, 0x5B, 0xE7, 0x4A, 0xBD, 0x1E, 0x01, 0x72, 0xDB, 0x4B, 0x74, 0xE8, 0x3B, 0x7F, 0x7F, 0x7D, 0x1F, 0x04,
+       0xB4, 0x26, 0x9B, 0xE0, 0xB4, 0x5A, 0xAC, 0x47, 0x3D, 0x55, 0xB8, 0xD7, 0xB0, 0x26, 0x52, 0x28, 0x01, 0x31, 0x40, 0x66,
+       0xD8, 0xD9, 0x24, 0xBD, 0xF6, 0x2A, 0xD8, 0xEC, 0x21, 0x49, 0x5C, 0x9B, 0xF6, 0x7A, 0xE9, 0x7F, 0x55, 0x35, 0x7E, 0x96,
+       0x6B, 0x8D, 0x93, 0x93, 0x27, 0xCB, 0x92, 0xBB, 0xEA, 0xAC, 0x40, 0xC0, 0x9F, 0xC2, 0xF8, 0x80, 0xCF, 0x5D, 0xF4, 0x5A,
+       0xDC, 0xCE, 0x74, 0x86, 0xA6, 0x3E, 0x6C, 0x0B, 0x53, 0xCA, 0xBD, 0x92, 0xCE, 0x19, 0x06, 0x72, 0xE6, 0x0C, 0x5C, 0x38,
+       0x69, 0xC7, 0x04, 0xD6, 0xBC, 0x6C, 0xCE, 0x5B, 0xF6, 0xF7, 0x68, 0x9C, 0xDC, 0x25, 0x15, 0x48, 0x88, 0xA1, 0xE9, 0xA9,
+       0xF8, 0x98, 0x9C, 0xE0, 0xF3, 0xD5, 0x31, 0x28, 0x61, 0x11, 0x6C, 0x67, 0x96, 0x8D, 0x39, 0x99, 0xCB, 0xC2, 0x45, 0x24,
+       0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x42, 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF,
+       0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03,
+       0x02, 0x01, 0x06, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xAD, 0x6C, 0xAA, 0x94, 0x60, 0x9C,
+       0xED, 0xE4, 0xFF, 0xFA, 0x3E, 0x0A, 0x74, 0x2B, 0x63, 0x03, 0xF7, 0xB6, 0x59, 0xBF, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86,
+       0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x1A, 0x40, 0xD8, 0x95, 0x65, 0xAC,
+       0x09, 0x92, 0x89, 0xC6, 0x39, 0xF4, 0x10, 0xE5, 0xA9, 0x0E, 0x66, 0x53, 0x5D, 0x78, 0xDE, 0xFA, 0x24, 0x91, 0xBB, 0xE7,
+       0x44, 0x51, 0xDF, 0xC6, 0x16, 0x34, 0x0A, 0xEF, 0x6A, 0x44, 0x51, 0xEA, 0x2B, 0x07, 0x8A, 0x03, 0x7A, 0xC3, 0xEB, 0x3F,
+       0x0A, 0x2C, 0x52, 0x16, 0xA0, 0x2B, 0x43, 0xB9, 0x25, 0x90, 0x3F, 0x70, 0xA9, 0x33, 0x25, 0x6D, 0x45, 0x1A, 0x28, 0x3B,
+       0x27, 0xCF, 0xAA, 0xC3, 0x29, 0x42, 0x1B, 0xDF, 0x3B, 0x4C, 0xC0, 0x33, 0x34, 0x5B, 0x41, 0x88, 0xBF, 0x6B, 0x2B, 0x65,
+       0xAF, 0x28, 0xEF, 0xB2, 0xF5, 0xC3, 0xAA, 0x66, 0xCE, 0x7B, 0x56, 0xEE, 0xB7, 0xC8, 0xCB, 0x67, 0xC1, 0xC9, 0x9C, 0x1A,
+       0x18, 0xB8, 0xC4, 0xC3, 0x49, 0x03, 0xF1, 0x60, 0x0E, 0x50, 0xCD, 0x46, 0xC5, 0xF3, 0x77, 0x79, 0xF7, 0xB6, 0x15, 0xE0,
+       0x38, 0xDB, 0xC7, 0x2F, 0x28, 0xA0, 0x0C, 0x3F, 0x77, 0x26, 0x74, 0xD9, 0x25, 0x12, 0xDA, 0x31, 0xDA, 0x1A, 0x1E, 0xDC,
+       0x29, 0x41, 0x91, 0x22, 0x3C, 0x69, 0xA7, 0xBB, 0x02, 0xF2, 0xB6, 0x5C, 0x27, 0x03, 0x89, 0xF4, 0x06, 0xEA, 0x9B, 0xE4,
+       0x72, 0x82, 0xE3, 0xA1, 0x09, 0xC1, 0xE9, 0x00, 0x19, 0xD3, 0x3E, 0xD4, 0x70, 0x6B, 0xBA, 0x71, 0xA6, 0xAA, 0x58, 0xAE,
+       0xF4, 0xBB, 0xE9, 0x6C, 0xB6, 0xEF, 0x87, 0xCC, 0x9B, 0xBB, 0xFF, 0x39, 0xE6, 0x56, 0x61, 0xD3, 0x0A, 0xA7, 0xC4, 0x5C,
+       0x4C, 0x60, 0x7B, 0x05, 0x77, 0x26, 0x7A, 0xBF, 0xD8, 0x07, 0x52, 0x2C, 0x62, 0xF7, 0x70, 0x63, 0xD9, 0x39, 0xBC, 0x6F,
+       0x1C, 0xC2, 0x79, 0xDC, 0x76, 0x29, 0xAF, 0xCE, 0xC5, 0x2C, 0x64, 0x04, 0x5E, 0x88, 0x36, 0x6E, 0x31, 0xD4, 0x40, 0x1A,
+       0x62, 0x34, 0x36, 0x3F, 0x35, 0x01, 0xAE, 0xAC, 0x63, 0xA0
+};
+
+//Samsung_OCF_RootCA.der
+const unsigned char g_regional_root_ca[] = {
+       0x30, 0x82, 0x02, 0x5D, 0x30, 0x82, 0x02, 0x01, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0C, 0x06, 0x08,
+       0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x6B, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x13, 0x1F, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69,
+       0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
+       0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A,
+       0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74,
+       0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4B, 0x52, 0x30,
+       0x20, 0x17, 0x0D, 0x31, 0x36, 0x31, 0x31, 0x32, 0x34, 0x30, 0x32, 0x35, 0x35, 0x31, 0x31, 0x5A, 0x18, 0x0F, 0x32, 0x30,
+       0x36, 0x39, 0x31, 0x32, 0x33, 0x31, 0x31, 0x34, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x6B, 0x31, 0x28, 0x30, 0x26, 0x06,
+       0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72,
+       0x6F, 0x6E, 0x69, 0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30,
+       0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31,
+       0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C,
+       0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+       0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48,
+       0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x62, 0xC7, 0xFF, 0x2B, 0x1F, 0xAC, 0x50, 0x50, 0x50, 0x11, 0x26,
+       0xEE, 0xCA, 0xD4, 0xC3, 0x3F, 0x02, 0xCF, 0x21, 0xED, 0x17, 0xFF, 0xCF, 0xC1, 0xD4, 0xBE, 0xDB, 0xDD, 0xA6, 0xF1, 0x13,
+       0xDC, 0x34, 0x81, 0x06, 0x40, 0x7C, 0x8F, 0x16, 0x61, 0x49, 0x0A, 0x7C, 0xD7, 0xCF, 0xEC, 0x75, 0xE1, 0xD4, 0xCE, 0x52,
+       0x0A, 0x73, 0xA4, 0x7F, 0x05, 0xAB, 0x6A, 0x5B, 0x46, 0x38, 0xA4, 0xDE, 0x5F, 0xA3, 0x81, 0x91, 0x30, 0x81, 0x8E, 0x30,
+       0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0xC6, 0x30, 0x32, 0x06, 0x03, 0x55,
+       0x1D, 0x1F, 0x04, 0x2B, 0x30, 0x29, 0x30, 0x27, 0xA0, 0x25, 0xA0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F,
+       0x2F, 0x70, 0x72, 0x6F, 0x64, 0x63, 0x61, 0x2E, 0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E,
+       0x63, 0x6F, 0x6D, 0x2F, 0x63, 0x72, 0x6C, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30,
+       0x03, 0x01, 0x01, 0xFF, 0x30, 0x37, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2B, 0x30, 0x29,
+       0x30, 0x27, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F,
+       0x2F, 0x6F, 0x63, 0x73, 0x70, 0x2E, 0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E, 0x63, 0x6F,
+       0x6D, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45,
+       0x02, 0x20, 0x11, 0x63, 0xD6, 0x92, 0x13, 0x7D, 0x2A, 0xDF, 0x5A, 0xB9, 0xBF, 0xC0, 0x78, 0xB0, 0x97, 0x33, 0x06, 0xA3,
+       0xA9, 0xEC, 0x0B, 0x03, 0xF6, 0x8F, 0x19, 0x22, 0xE3, 0x66, 0x1F, 0xB2, 0x30, 0x4B, 0x02, 0x21, 0x00, 0xB7, 0xD1, 0xE7,
+       0xA8, 0xDC, 0x5E, 0x81, 0x62, 0xB3, 0xF9, 0xC3, 0xC7, 0x4B, 0x50, 0xDB, 0x14, 0xC8, 0xFD, 0xFD, 0x1B, 0xEC, 0x5E, 0xAD,
+       0x58, 0xFA, 0xA3, 0xDA, 0xFC, 0x8A, 0x41, 0xE3, 0x51
+};
+
+#ifndef _EXCLUDE_TEST_KEY_
+//Samsung_OCF_TestRootCA.der
+const unsigned char g_regional_test_root_ca[] = {
+       0x30, 0x82, 0x02, 0x68, 0x30, 0x82, 0x02, 0x0C, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0C, 0x06, 0x08,
+       0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x70, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x13, 0x24, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69,
+       0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x54, 0x45, 0x53, 0x54, 0x31,
+       0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43,
+       0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20,
+       0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+       0x13, 0x02, 0x4B, 0x52, 0x30, 0x20, 0x17, 0x0D, 0x31, 0x36, 0x31, 0x31, 0x32, 0x34, 0x30, 0x32, 0x34, 0x37, 0x32, 0x37,
+       0x5A, 0x18, 0x0F, 0x32, 0x30, 0x36, 0x39, 0x31, 0x32, 0x33, 0x31, 0x31, 0x34, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x70,
+       0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45,
+       0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20,
+       0x43, 0x41, 0x20, 0x54, 0x45, 0x53, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43,
+       0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13,
+       0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31,
+       0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86,
+       0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x1C,
+       0xF3, 0xBA, 0xBC, 0xBB, 0xA7, 0xC1, 0xC0, 0x35, 0x59, 0xFE, 0xBF, 0x80, 0x88, 0x6B, 0x68, 0x7F, 0x47, 0xF4, 0x80, 0xB7,
+       0x75, 0x55, 0xB2, 0xDF, 0xAF, 0x4E, 0xFE, 0x3F, 0x91, 0x1F, 0xA5, 0x81, 0x4D, 0x4E, 0x12, 0x24, 0xF7, 0xB7, 0xDF, 0xA6,
+       0x39, 0x61, 0x3B, 0x27, 0xEA, 0x1D, 0x76, 0x94, 0x68, 0x7C, 0x55, 0xB6, 0x0D, 0xD7, 0x89, 0x92, 0x97, 0xD0, 0x51, 0x53,
+       0xA7, 0xE0, 0xD3, 0xA3, 0x81, 0x92, 0x30, 0x81, 0x8F, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04,
+       0x04, 0x03, 0x02, 0x01, 0xC6, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0xA0, 0x21,
+       0xA0, 0x1F, 0x86, 0x1D, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x63, 0x61, 0x2E, 0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E,
+       0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x63, 0x72, 0x6C, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13,
+       0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x3C, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
+       0x01, 0x01, 0x04, 0x30, 0x30, 0x2E, 0x30, 0x2C, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x20,
+       0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6F, 0x63, 0x73, 0x70, 0x2D, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x73, 0x61, 0x6D,
+       0x73, 0x75, 0x6E, 0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
+       0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0x88, 0xB2, 0x2D, 0xC1, 0x70, 0xE4,
+       0x0C, 0x5C, 0xEF, 0xE9, 0x0A, 0x25, 0x00, 0xF9, 0x2E, 0xF9, 0x6D, 0x81, 0x56, 0x4B, 0x6E, 0xC4, 0x18, 0x0A, 0xBD, 0x7B,
+       0x61, 0x37, 0xFA, 0x14, 0x36, 0x4C, 0x02, 0x20, 0x5A, 0xB4, 0xE2, 0x78, 0x50, 0x19, 0xE7, 0x14, 0x47, 0xDC, 0x19, 0xD2,
+       0x1C, 0x6F, 0x97, 0x10, 0x5D, 0x87, 0x3C, 0x3F, 0x7D, 0xCB, 0xF4, 0x98, 0x49, 0xAE, 0x93, 0xE7, 0xD6, 0x16, 0xFA, 0x31
+};
+
+//global_ocf_connect_cert_root.der
+const unsigned char g_trust_ca_chain1[] = {
+       0x30, 0x82, 0x04, 0x20, 0x30, 0x82, 0x03, 0x08, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x34, 0x4E, 0xD5, 0x57, 0x20,
+       0xD5, 0xED, 0xEC, 0x49, 0xF4, 0x2F, 0xCE, 0x37, 0xDB, 0x2B, 0x6D, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
+       0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xA9, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+       0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C,
+       0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1F, 0x43, 0x65, 0x72, 0x74,
+       0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+       0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x2F, 0x28, 0x63,
+       0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20,
+       0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+       0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77,
+       0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1E,
+       0x17, 0x0D, 0x30, 0x36, 0x31, 0x31, 0x31, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x33, 0x36, 0x30,
+       0x37, 0x31, 0x36, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0xA9, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+       0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0C, 0x74, 0x68, 0x61,
+       0x77, 0x74, 0x65, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1F,
+       0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+       0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x0B,
+       0x13, 0x2F, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2C, 0x20, 0x49,
+       0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64,
+       0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16,
+       0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20,
+       0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
+       0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xAC, 0xA0, 0xF0, 0xFB, 0x80,
+       0x59, 0xD4, 0x9C, 0xC7, 0xA4, 0xCF, 0x9D, 0xA1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0C, 0x0D, 0x2C, 0x6E, 0x68, 0xF1, 0x6C,
+       0x5B, 0x48, 0x68, 0x49, 0x59, 0x37, 0xFC, 0x0B, 0x33, 0x19, 0xC2, 0x77, 0x7F, 0xCC, 0x10, 0x2D, 0x95, 0x34, 0x1C, 0xE6,
+       0xEB, 0x4D, 0x09, 0xA7, 0x1C, 0xD2, 0xB8, 0xC9, 0x97, 0x36, 0x02, 0xB7, 0x89, 0xD4, 0x24, 0x5F, 0x06, 0xC0, 0xCC, 0x44,
+       0x94, 0x94, 0x8D, 0x02, 0x62, 0x6F, 0xEB, 0x5A, 0xDD, 0x11, 0x8D, 0x28, 0x9A, 0x5C, 0x84, 0x90, 0x10, 0x7A, 0x0D, 0xBD,
+       0x74, 0x66, 0x2F, 0x6A, 0x38, 0xA0, 0xE2, 0xD5, 0x54, 0x44, 0xEB, 0x1D, 0x07, 0x9F, 0x07, 0xBA, 0x6F, 0xEE, 0xE9, 0xFD,
+       0x4E, 0x0B, 0x29, 0xF5, 0x3E, 0x84, 0xA0, 0x01, 0xF1, 0x9C, 0xAB, 0xF8, 0x1C, 0x7E, 0x89, 0xA4, 0xE8, 0xA1, 0xD8, 0x71,
+       0x65, 0x0D, 0xA3, 0x51, 0x7B, 0xEE, 0xBC, 0xD2, 0x22, 0x60, 0x0D, 0xB9, 0x5B, 0x9D, 0xDF, 0xBA, 0xFC, 0x51, 0x5B, 0x0B,
+       0xAF, 0x98, 0xB2, 0xE9, 0x2E, 0xE9, 0x04, 0xE8, 0x62, 0x87, 0xDE, 0x2B, 0xC8, 0xD7, 0x4E, 0xC1, 0x4C, 0x64, 0x1E, 0xDD,
+       0xCF, 0x87, 0x58, 0xBA, 0x4A, 0x4F, 0xCA, 0x68, 0x07, 0x1D, 0x1C, 0x9D, 0x4A, 0xC6, 0xD5, 0x2F, 0x91, 0xCC, 0x7C, 0x71,
+       0x72, 0x1C, 0xC5, 0xC0, 0x67, 0xEB, 0x32, 0xFD, 0xC9, 0x92, 0x5C, 0x94, 0xDA, 0x85, 0xC0, 0x9B, 0xBF, 0x53, 0x7D, 0x2B,
+       0x09, 0xF4, 0x8C, 0x9D, 0x91, 0x1F, 0x97, 0x6A, 0x52, 0xCB, 0xDE, 0x09, 0x36, 0xA4, 0x77, 0xD8, 0x7B, 0x87, 0x50, 0x44,
+       0xD5, 0x3E, 0x6E, 0x29, 0x69, 0xFB, 0x39, 0x49, 0x26, 0x1E, 0x09, 0xA5, 0x80, 0x7B, 0x40, 0x2D, 0xEB, 0xE8, 0x27, 0x85,
+       0xC9, 0xFE, 0x61, 0xFD, 0x7E, 0xE6, 0x7C, 0x97, 0x1D, 0xD5, 0x9D, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x42, 0x30, 0x40,
+       0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06,
+       0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E,
+       0x04, 0x16, 0x04, 0x14, 0x7B, 0x5B, 0x45, 0xCF, 0xAF, 0xCE, 0xCB, 0x7A, 0xFD, 0x31, 0x92, 0x1A, 0x6A, 0xB6, 0xF3, 0x46,
+       0xEB, 0x57, 0x48, 0x50, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+       0x82, 0x01, 0x01, 0x00, 0x79, 0x11, 0xC0, 0x4B, 0xB3, 0x91, 0xB6, 0xFC, 0xF0, 0xE9, 0x67, 0xD4, 0x0D, 0x6E, 0x45, 0xBE,
+       0x55, 0xE8, 0x93, 0xD2, 0xCE, 0x03, 0x3F, 0xED, 0xDA, 0x25, 0xB0, 0x1D, 0x57, 0xCB, 0x1E, 0x3A, 0x76, 0xA0, 0x4C, 0xEC,
+       0x50, 0x76, 0xE8, 0x64, 0x72, 0x0C, 0xA4, 0xA9, 0xF1, 0xB8, 0x8B, 0xD6, 0xD6, 0x87, 0x84, 0xBB, 0x32, 0xE5, 0x41, 0x11,
+       0xC0, 0x77, 0xD9, 0xB3, 0x60, 0x9D, 0xEB, 0x1B, 0xD5, 0xD1, 0x6E, 0x44, 0x44, 0xA9, 0xA6, 0x01, 0xEC, 0x55, 0x62, 0x1D,
+       0x77, 0xB8, 0x5C, 0x8E, 0x48, 0x49, 0x7C, 0x9C, 0x3B, 0x57, 0x11, 0xAC, 0xAD, 0x73, 0x37, 0x8E, 0x2F, 0x78, 0x5C, 0x90,
+       0x68, 0x47, 0xD9, 0x60, 0x60, 0xE6, 0xFC, 0x07, 0x3D, 0x22, 0x20, 0x17, 0xC4, 0xF7, 0x16, 0xE9, 0xC4, 0xD8, 0x72, 0xF9,
+       0xC8, 0x73, 0x7C, 0xDF, 0x16, 0x2F, 0x15, 0xA9, 0x3E, 0xFD, 0x6A, 0x27, 0xB6, 0xA1, 0xEB, 0x5A, 0xBA, 0x98, 0x1F, 0xD5,
+       0xE3, 0x4D, 0x64, 0x0A, 0x9D, 0x13, 0xC8, 0x61, 0xBA, 0xF5, 0x39, 0x1C, 0x87, 0xBA, 0xB8, 0xBD, 0x7B, 0x22, 0x7F, 0xF6,
+       0xFE, 0xAC, 0x40, 0x79, 0xE5, 0xAC, 0x10, 0x6F, 0x3D, 0x8F, 0x1B, 0x79, 0x76, 0x8B, 0xC4, 0x37, 0xB3, 0x21, 0x18, 0x84,
+       0xE5, 0x36, 0x00, 0xEB, 0x63, 0x20, 0x99, 0xB9, 0xE9, 0xFE, 0x33, 0x04, 0xBB, 0x41, 0xC8, 0xC1, 0x02, 0xF9, 0x44, 0x63,
+       0x20, 0x9E, 0x81, 0xCE, 0x42, 0xD3, 0xD6, 0x3F, 0x2C, 0x76, 0xD3, 0x63, 0x9C, 0x59, 0xDD, 0x8F, 0xA6, 0xE1, 0x0E, 0xA0,
+       0x2E, 0x41, 0xF7, 0x2E, 0x95, 0x47, 0xCF, 0xBC, 0xFD, 0x33, 0xF3, 0xF6, 0x0B, 0x61, 0x7E, 0x7E, 0x91, 0x2B, 0x81, 0x47,
+       0xC2, 0x27, 0x30, 0xEE, 0xA7, 0x10, 0x5D, 0x37, 0x8F, 0x5C, 0x39, 0x2B, 0xE4, 0x04, 0xF0, 0x7B, 0x8D, 0x56, 0x8C, 0x68
+};
+
+//Samsung_OCF_RootCA.der
+const unsigned char g_trust_ca_chain2[] = {
+       0x30, 0x82, 0x02, 0x5D, 0x30, 0x82, 0x02, 0x01, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0C, 0x06, 0x08,
+       0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x6B, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x13, 0x1F, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69,
+       0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
+       0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A,
+       0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74,
+       0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4B, 0x52, 0x30,
+       0x20, 0x17, 0x0D, 0x31, 0x36, 0x31, 0x31, 0x32, 0x34, 0x30, 0x32, 0x35, 0x35, 0x31, 0x31, 0x5A, 0x18, 0x0F, 0x32, 0x30,
+       0x36, 0x39, 0x31, 0x32, 0x33, 0x31, 0x31, 0x34, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x6B, 0x31, 0x28, 0x30, 0x26, 0x06,
+       0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72,
+       0x6F, 0x6E, 0x69, 0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30,
+       0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31,
+       0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C,
+       0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+       0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48,
+       0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x62, 0xC7, 0xFF, 0x2B, 0x1F, 0xAC, 0x50, 0x50, 0x50, 0x11, 0x26,
+       0xEE, 0xCA, 0xD4, 0xC3, 0x3F, 0x02, 0xCF, 0x21, 0xED, 0x17, 0xFF, 0xCF, 0xC1, 0xD4, 0xBE, 0xDB, 0xDD, 0xA6, 0xF1, 0x13,
+       0xDC, 0x34, 0x81, 0x06, 0x40, 0x7C, 0x8F, 0x16, 0x61, 0x49, 0x0A, 0x7C, 0xD7, 0xCF, 0xEC, 0x75, 0xE1, 0xD4, 0xCE, 0x52,
+       0x0A, 0x73, 0xA4, 0x7F, 0x05, 0xAB, 0x6A, 0x5B, 0x46, 0x38, 0xA4, 0xDE, 0x5F, 0xA3, 0x81, 0x91, 0x30, 0x81, 0x8E, 0x30,
+       0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0xC6, 0x30, 0x32, 0x06, 0x03, 0x55,
+       0x1D, 0x1F, 0x04, 0x2B, 0x30, 0x29, 0x30, 0x27, 0xA0, 0x25, 0xA0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F,
+       0x2F, 0x70, 0x72, 0x6F, 0x64, 0x63, 0x61, 0x2E, 0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E,
+       0x63, 0x6F, 0x6D, 0x2F, 0x63, 0x72, 0x6C, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30,
+       0x03, 0x01, 0x01, 0xFF, 0x30, 0x37, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2B, 0x30, 0x29,
+       0x30, 0x27, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F,
+       0x2F, 0x6F, 0x63, 0x73, 0x70, 0x2E, 0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E, 0x63, 0x6F,
+       0x6D, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45,
+       0x02, 0x20, 0x11, 0x63, 0xD6, 0x92, 0x13, 0x7D, 0x2A, 0xDF, 0x5A, 0xB9, 0xBF, 0xC0, 0x78, 0xB0, 0x97, 0x33, 0x06, 0xA3,
+       0xA9, 0xEC, 0x0B, 0x03, 0xF6, 0x8F, 0x19, 0x22, 0xE3, 0x66, 0x1F, 0xB2, 0x30, 0x4B, 0x02, 0x21, 0x00, 0xB7, 0xD1, 0xE7,
+       0xA8, 0xDC, 0x5E, 0x81, 0x62, 0xB3, 0xF9, 0xC3, 0xC7, 0x4B, 0x50, 0xDB, 0x14, 0xC8, 0xFD, 0xFD, 0x1B, 0xEC, 0x5E, 0xAD,
+       0x58, 0xFA, 0xA3, 0xDA, 0xFC, 0x8A, 0x41, 0xE3, 0x51
+};
+
+//Samsung_OCF_TestRootCA.der
+const unsigned char g_trust_ca_chain3[] = {
+       0x30, 0x82, 0x02, 0x68, 0x30, 0x82, 0x02, 0x0C, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0C, 0x06, 0x08,
+       0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x70, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04,
+       0x03, 0x13, 0x24, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69,
+       0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x54, 0x45, 0x53, 0x54, 0x31,
+       0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43,
+       0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20,
+       0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+       0x13, 0x02, 0x4B, 0x52, 0x30, 0x20, 0x17, 0x0D, 0x31, 0x36, 0x31, 0x31, 0x32, 0x34, 0x30, 0x32, 0x34, 0x37, 0x32, 0x37,
+       0x5A, 0x18, 0x0F, 0x32, 0x30, 0x36, 0x39, 0x31, 0x32, 0x33, 0x31, 0x31, 0x34, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x70,
+       0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45,
+       0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x20, 0x4F, 0x43, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20,
+       0x43, 0x41, 0x20, 0x54, 0x45, 0x53, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0B, 0x4F, 0x43,
+       0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13,
+       0x53, 0x61, 0x6D, 0x73, 0x75, 0x6E, 0x67, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x31,
+       0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86,
+       0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x1C,
+       0xF3, 0xBA, 0xBC, 0xBB, 0xA7, 0xC1, 0xC0, 0x35, 0x59, 0xFE, 0xBF, 0x80, 0x88, 0x6B, 0x68, 0x7F, 0x47, 0xF4, 0x80, 0xB7,
+       0x75, 0x55, 0xB2, 0xDF, 0xAF, 0x4E, 0xFE, 0x3F, 0x91, 0x1F, 0xA5, 0x81, 0x4D, 0x4E, 0x12, 0x24, 0xF7, 0xB7, 0xDF, 0xA6,
+       0x39, 0x61, 0x3B, 0x27, 0xEA, 0x1D, 0x76, 0x94, 0x68, 0x7C, 0x55, 0xB6, 0x0D, 0xD7, 0x89, 0x92, 0x97, 0xD0, 0x51, 0x53,
+       0xA7, 0xE0, 0xD3, 0xA3, 0x81, 0x92, 0x30, 0x81, 0x8F, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04,
+       0x04, 0x03, 0x02, 0x01, 0xC6, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0xA0, 0x21,
+       0xA0, 0x1F, 0x86, 0x1D, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x63, 0x61, 0x2E, 0x73, 0x61, 0x6D, 0x73, 0x75, 0x6E,
+       0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x63, 0x72, 0x6C, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13,
+       0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x3C, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
+       0x01, 0x01, 0x04, 0x30, 0x30, 0x2E, 0x30, 0x2C, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x20,
+       0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6F, 0x63, 0x73, 0x70, 0x2D, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x73, 0x61, 0x6D,
+       0x73, 0x75, 0x6E, 0x67, 0x69, 0x6F, 0x74, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
+       0x3D, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0x88, 0xB2, 0x2D, 0xC1, 0x70, 0xE4,
+       0x0C, 0x5C, 0xEF, 0xE9, 0x0A, 0x25, 0x00, 0xF9, 0x2E, 0xF9, 0x6D, 0x81, 0x56, 0x4B, 0x6E, 0xC4, 0x18, 0x0A, 0xBD, 0x7B,
+       0x61, 0x37, 0xFA, 0x14, 0x36, 0x4C, 0x02, 0x20, 0x5A, 0xB4, 0xE2, 0x78, 0x50, 0x19, 0xE7, 0x14, 0x47, 0xDC, 0x19, 0xD2,
+       0x1C, 0x6F, 0x97, 0x10, 0x5D, 0x87, 0x3C, 0x3F, 0x7D, 0xCB, 0xF4, 0x98, 0x49, 0xAE, 0x93, 0xE7, 0xD6, 0x16, 0xFA, 0x31
+};
+
+#endif                                                 //_EXCLUDE_TEST_KEY_
+
+/*
+ * This API added as workaround to test certificate based TLS connection.
+ * It will be replaced to use TZ or eSE based key protection.
+ *
+ * NOTE : This API should be invoked after sm_generate_mac_based_device_id invoked.
+ */
+static OCStackResult save_signed_asymmetric_key(OicUuid_t *subject_uuid)
+{
+       OCStackResult res = OC_STACK_ERROR;
+       uint16_t cred_id = 0;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IN: %s", __func__);
+
+       // For D2S
+
+       /*
+        * 1. Save the Trust CA cert chain.
+        */
+       res = CredSaveTrustCertChain(subject_uuid, g_trust_ca_chain1, sizeof(g_trust_ca_chain1), OIC_ENCODING_DER, TRUST_CA, &cred_id);
+       if (OC_STACK_OK != res) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "SRPCredSaveTrustCertChain #1 error");
+               return res;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "global_ocf_connect_cert_root.der saved w/ cred ID=%d", cred_id);
+
+       res = CredSaveTrustCertChain(subject_uuid, g_trust_ca_chain2, sizeof(g_trust_ca_chain2), OIC_ENCODING_DER, TRUST_CA, &cred_id);
+       if (OC_STACK_OK != res) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "SRPCredSaveTrustCertChain #2 error");
+               return res;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Samsung_OCF_RootCA.der saved w/ cred ID=%d", cred_id);
+
+       res = CredSaveTrustCertChain(subject_uuid, g_trust_ca_chain3, sizeof(g_trust_ca_chain3), OIC_ENCODING_DER, TRUST_CA, &cred_id);
+       if (OC_STACK_OK != res) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "SRPCredSaveTrustCertChain #3 error");
+               return res;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Samsung_OCF_TestRootCA.der saved w/ cred ID=%d", cred_id);
+
+#ifndef _EXCLUDE_TEST_KEY_
+       /*
+        * 2. Save the key for D2S (primary cert & key)
+        */
+       res = seckey_setup(dm_get_certificate_file_path(), &primary_cert, OIC_ENCODING_DER);
+       if (OC_STACK_OK != res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "seckey_setup error");
+               return res;
+       }
+       res = seckey_setup(dm_get_privatekey_file_path(), &primary_key, OIC_ENCODING_RAW);
+       if (OC_STACK_OK != res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "seckey_setup error");
+               return res;
+       }
+       res = CredSaveOwnCert(subject_uuid, &primary_cert, &primary_key, PRIMARY_CERT, &cred_id);
+       if (OC_STACK_OK != res) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "SRPCredSaveOwnCertChain error");
+               return res;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Primary cert & key saved w/ cred ID=%d", cred_id);
+#endif                                                 //_EXCLUDE_TEST_KEY_
+
+       // For D2D
+       if (g_is_mfg_cert_required) {
+               /*
+                * 3. Save the MFG trust CA cert chain.
+                */
+#ifndef _EXCLUDE_TEST_KEY_
+               res = CredSaveTrustCertChain(subject_uuid, g_regional_test_root_ca, sizeof(g_regional_test_root_ca), OIC_ENCODING_DER, MF_TRUST_CA, &cred_id);
+#else
+               res = CredSaveTrustCertChain(subject_uuid, g_regional_root_ca, sizeof(g_regional_root_ca), OIC_ENCODING_DER, MF_TRUST_CA, &cred_id);
+#endif                                                 //_EXCLUDE_TEST_KEY_
+               if (OC_STACK_OK != res) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "SRPCredSaveOwnCertChain error");
+                       return res;
+               }
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "MFG trust CA chain saved w/ cred ID=%d", cred_id);
+#ifndef _EXCLUDE_TEST_KEY_
+               /*
+                * 4. Save the key for D2D (manufacturer cert & key)
+                */
+               res = CredSaveOwnCert(subject_uuid, &primary_cert, &primary_key, MF_PRIMARY_CERT, &cred_id);
+               if (OC_STACK_OK != res) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "SRPCredSaveOwnCertChain error");
+                       return res;
+               }
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "MFG primary cert & key saved w/ cred ID=%d", cred_id);
+#endif                                                 //_EXCLUDE_TEST_KEY_
+       }
+#ifndef _EXCLUDE_TEST_KEY_
+       if (primary_cert.data != NULL) {
+               things_free(primary_cert.data);
+       }
+
+       if (primary_key.data != NULL) {
+               things_free(primary_key.data);
+       }
+#endif                                                 //_EXCLUDE_TEST_KEY_
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Out: %s", __func__);
+
+       return res;
+}
+
+int sm_save_cloud_acl(const char *cloud_uuid)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IN : %s", __func__);
+
+       if (!cloud_uuid) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "cloud_uuid is NULL");
+               return OIC_SEC_ERROR;
+       }
+
+       OicUuid_t oic_uuid;
+       if (OC_STACK_OK != ConvertStrToUuid(cloud_uuid, &oic_uuid)) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "cloud_uuid is NULL");
+               return OIC_SEC_ERROR;
+       }
+       // allocate memory for |acl| struct
+       OicSecAcl_t *acl = (OicSecAcl_t *) things_calloc(1, sizeof(OicSecAcl_t));
+       if (!acl) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, " %s : things_calloc error return", __func__);
+               return OIC_SEC_ERROR;
+       }
+       OicSecAce_t *ace = (OicSecAce_t *) things_calloc(1, sizeof(OicSecAce_t));
+       if (!ace) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : things_calloc error return", __func__);
+               return OIC_SEC_ERROR;
+       }
+       LL_APPEND(acl->aces, ace);
+
+       memcpy(ace->subjectuuid.id, oic_uuid.id, sizeof(oic_uuid.id));
+
+       OicSecRsrc_t *rsrc = (OicSecRsrc_t *) things_calloc(1, sizeof(OicSecRsrc_t));
+       if (!rsrc) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : things_calloc error return", __func__);
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+
+       char href[] = "*";
+       size_t len = strlen(href) + 1;  // '1' for null termination
+       rsrc->href = (char *)things_calloc(len, sizeof(char));
+       if (!rsrc->href) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : things_calloc error return", __func__);
+               FreeRsrc(rsrc);
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+       things_strncpy(rsrc->href, href, len);
+
+       size_t arrLen = 1;
+       rsrc->typeLen = arrLen;
+       rsrc->types = (char **)things_calloc(arrLen, sizeof(char *));
+       if (!rsrc->types) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : things_calloc error return", __func__);
+               FreeRsrc(rsrc);
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+       rsrc->types[0] = OICStrdup("x.com.samsung.cloudconnection");    // ignore
+       if (!rsrc->types[0]) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : OICStrdup error return", __func__);
+               FreeRsrc(rsrc);
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+
+       rsrc->interfaceLen = 1;
+       rsrc->interfaces = (char **)things_calloc(arrLen, sizeof(char *));
+       if (!rsrc->interfaces) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : things_calloc error return", __func__);
+               FreeRsrc(rsrc);
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+       rsrc->interfaces[0] = OICStrdup("oic.if.baseline");     // ignore
+       if (!rsrc->interfaces[0]) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : OICStrdup error return", __func__);
+               FreeRsrc(rsrc);
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+       LL_APPEND(ace->resources, rsrc);
+
+       ace->permission = 31;           // CRUDN
+
+       OCStackResult installRes = InstallACL(acl);
+       if (OC_STACK_DUPLICATE_REQUEST == installRes) {
+               THINGS_LOG_D(THINGS_WARNING, TAG, "%s : [%s]'s ACL already installed.", __func__, cloud_uuid);
+       } else if (OC_STACK_OK != installRes) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "%s : OICStrdup error return", __func__);
+               /*SVACE warning fix */
+               DeleteACLList(acl);
+               return OIC_SEC_ERROR;
+       }
+       DeleteACLList(acl);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "OUT : %s", __func__);
+
+       return OIC_SEC_OK;
+}
+
+void sm_set_otm_event_handler(OicSecOtmEventHandler_t otmEventHandler)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IN : %s", __func__);
+
+       SetOtmEventHandler(otmEventHandler);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "OUT : %s", __func__);
+}
diff --git a/framework/src/st_things/things_stack/src/common/framework/things_server_builder.c b/framework/src/st_things/things_stack/src/common/framework/things_server_builder.c
new file mode 100644 (file)
index 0000000..f888f54
--- /dev/null
@@ -0,0 +1,501 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#define _BSD_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "things_def.h"
+#include "things_common.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_string_util.h"
+#include "ocpayload.h"
+#include "things_resource.h"
+#include "things_server_builder.h"
+#include "resource_handler.h"
+
+#include "things_thread.h"
+#ifdef __ST_THINGS_RTOS__
+#include "things_rtos_util.h"
+#endif
+#define TAG "[things_svrbldr]"
+
+#define DEFAULT_DATA_MODEL_VERSIONS "res.1.1.0,sh.1.1.0"
+
+#define KEY_ATTR_DEVICE_NAME                "n"
+#define KEY_ATTR_PLATFORM_VENDERID          "vid"
+
+static pthread_t g_thread_id_server;
+static pthread_t g_thread_id_presence;
+
+static int g_quit_flag = 0;
+static uint g_presence_flag = 0;
+static int g_presence_duration = 20;
+static volatile bool is_presence = false;
+
+things_server_builder_s *g_builder = NULL;
+
+void *server_execute_loop(void *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       while (!g_quit_flag) {
+               if (OCProcess() != OC_STACK_OK) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "OCProcess Error");
+                       //   need to insert error handling logic from here
+               }
+               //   The proper time period for looping need to be decided..
+               usleep(10 * 1000);
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return NULL;
+}
+
+void *presence_noti_loop(void *param)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (OCStartPresence(0) == OC_STACK_OK) {
+               /*        while (!g_quit_flag)
+                  {
+                  g_presence_flag++;
+                  //THINGS_LOG_D(THINGS_DEBUG, TAG, "COUNT : %d", g_presence_flag);
+                  if (g_presence_flag > g_presence_duration)
+                  {
+                  g_presence_flag = 0;
+                  OCStopPresence();
+                  THINGS_LOG(THINGS_INFO, TAG, "Stop Sending Presence Packet");
+                  is_presence = false;
+                  break;
+                  }
+                  sleep(1);
+                  }
+                */
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "OCStartPresence Error");
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return NULL;
+}
+
+void register_req_handler(struct things_server_builder_s *builder, request_handler_cb handler)
+{
+       if (handler == NULL || builder == NULL) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid Param");
+               return;
+       }
+       builder->handler = handler;
+}
+
+struct things_resource_s *create_resource(struct things_server_builder_s *builder, char *uri, char *type, char *interface, int isDiscoverable, int isObserable, int isSecure)
+{
+       things_resource_s *res = NULL;
+       OCResourceHandle hd = NULL;
+       uint8_t rsc_properties = OC_DISCOVERABLE;
+
+       if (builder->handler == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Handler for serverbuilder is not registered");
+               return res;
+       }
+
+       if (1 != isDiscoverable) {
+               rsc_properties = OC_ACTIVE;
+       }
+
+       if (1 == isObserable) {
+               rsc_properties |= OC_OBSERVABLE;
+       }
+       // if( strstr(uri, URI_ACCESSPOINTLIST) == 0
+       //     && strstr(uri, URI_PROVINFO) == 0 )
+       if (1 == isSecure) {
+#ifdef __SECURED__
+               rsc_properties |= OC_SECURE;
+#else
+               THINGS_LOG(THINGS_DEBUG, TAG, "Stack is in UNSECURED Mode");
+#endif
+       }
+
+       OCStackResult ret = OCCreateResource(&hd,
+                                                                                type,
+                                                                                interface,
+                                                                                uri,
+                                                                                builder->handler,
+                                                                                NULL,
+                                                                                rsc_properties);
+
+       if (ret != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Resource Creation Failed - ret = %d, %s", ret, uri);
+               return NULL;
+       }
+
+       res = things_create_resource_inst(NULL, hd, NULL, NULL);
+
+       if (NULL == res) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "things_create_resource_inst is failed");
+               return res;
+       }
+
+       res->res_type = type;
+
+       builder->gres_arr[builder->res_num++] = res;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Created hd [%x], prop [0x%X] uri : %s", res->resource_handle, rsc_properties, res->uri);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "DISCOVERABLE : %s", (isDiscoverable == 1 ? "YES" : "NO"));
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "OBSERABLE : %s", (isObserable == 1 ? "YES" : "NO"));
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "SECURE : %s", (isSecure == 1 ? "YES" : "NO"));
+       return res;
+}
+
+struct things_resource_s *create_collection_resource(struct things_server_builder_s *builder, char *uri, char *type, char *interface)
+{
+       things_resource_s *res = NULL;
+       OCResourceHandle hd = NULL;
+       uint8_t rsc_properties = OC_DISCOVERABLE | OC_OBSERVABLE;
+
+       if (builder->handler == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Handler for serverbuilder is not registered");
+               return res;
+       }
+#ifdef __SECURED__
+
+       rsc_properties |= OC_SECURE;
+
+#endif                                                 //#ifdef __SECURED__
+
+       OCStackResult ret = OCCreateResource(&hd,
+                                                                                uri,
+                                                                                type,
+                                                                                uri,
+                                                                                builder->handler,
+                                                                                NULL,
+                                                                                rsc_properties);
+
+       if (ret != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Resource Creation Failed - ret = %d, %s", ret, uri);
+               return NULL;
+       }
+       //    Baseline interface will be binded automatically by IoTivity Stack.
+
+       res = things_create_resource_inst(NULL, hd, NULL, NULL);
+
+       if (NULL == res) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "things_create_resource_inst is failed");
+               return res;
+       }
+
+       res->res_type = type;
+
+       builder->gres_arr[builder->res_num++] = res;
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "Created hd [%x], prop [0x%X] uri : %s", res->resource_handle, rsc_properties, uri);
+
+       return res;
+}
+
+void delete_resource(struct things_server_builder_s *builder)
+{
+       for (size_t iter = 0; iter < builder->res_num; iter++) {
+               OCStackResult ret = OCDeleteResource((OCResourceHandle)(builder->gres_arr[iter]->resource_handle));
+               if (ret != OC_STACK_OK) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to delete the resource");
+               }
+       }
+}
+
+int add_interface_type(things_resource_s *resource, char *interface)
+{
+       if (NULL != resource && NULL != interface) {
+               if (NULL != resource->resource_handle) {
+                       if (OC_STACK_OK == OCBindResourceInterfaceToResource(resource->resource_handle, interface)) {
+                               return OC_STACK_OK;
+                       }
+               }
+       }
+
+       return OC_STACK_ERROR;
+}
+
+int add_resource_type(things_resource_s *resource, char *type)
+{
+       if (NULL != resource && NULL != type) {
+               if (NULL != resource->resource_handle) {
+                       if (OC_STACK_OK == OCBindResourceTypeToResource(resource->resource_handle, type)) {
+                               return OC_STACK_OK;
+                       }
+               }
+       }
+
+       return OC_STACK_ERROR;
+}
+
+void things_bind(struct things_resource_s *res, struct things_resource_s *bind)
+{
+       if (res == NULL || bind == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Invalid Resource");
+               return;
+       }
+
+       if (res->resource_handle == bind->resource_handle) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "It's identical resource");
+               return;
+       }
+
+       OCStackResult ret = OCBindResource((OCResourceHandle)(res->resource_handle),
+                                                                          (OCResourceHandle)(bind->resource_handle));
+       if (ret != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "bind Failed ");
+       }
+}
+
+void bind_all(struct things_resource_s *res, struct things_resource_s *bind[], size_t size)
+{
+       for (size_t iter = 0; iter < size; iter++) {
+               things_bind(res, bind[iter]);
+               //    This time value achieved via testing
+               //       May need to re-test to find the opt. value for give platform.
+               usleep(100 * 1000);
+       }
+}
+
+struct things_resource_s *get_resource(things_server_builder_s *builder, const char *uri)
+{
+       things_resource_s *ret = NULL;
+       for (size_t iter = 0; iter < builder->res_num; iter++) {
+               const char *rURI = OCGetResourceUri((OCResourceHandle)(builder->gres_arr[iter]->resource_handle));
+
+               if (compare_strings(rURI, uri) == 0) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "URI Compare : %s , %s", uri, rURI);
+                       ret = builder->gres_arr[iter];
+                       break;
+               }
+       }
+       return ret;
+}
+
+int broadcast_presence(things_server_builder_s *builder, int max_cnt)
+{
+       if (max_cnt <= 0) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "check your max_cnt value.(must max_cnt > 0)");
+               return 1;
+       }
+
+       if (!is_presence) {
+               is_presence = true;
+               g_presence_flag = 0;
+               g_presence_duration = max_cnt;
+#ifdef __ST_THINGS_RTOS__
+               pthread_create_rtos(&g_thread_id_presence, NULL, presence_noti_loop, (void *)NULL, THINGS_STACK_PRESENCE_NOTI_THREAD);
+#else
+               things_thread_create(&g_thread_id_presence, NULL, presence_noti_loop, (void *)NULL);
+#endif
+       } else if ((uint) g_presence_duration < g_presence_flag + ((uint) max_cnt)) {
+               g_presence_duration = max_cnt;
+               g_presence_flag = 0;
+       }
+
+       return 0;
+}
+
+void init_builder(struct things_server_builder_s *builder, request_handler_cb cb)
+{
+       //if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+       //if(OC_STACK_OK != OCInit1 (OC_CLIENT_SERVER,OC_IP_USE_V4, OC_IP_USE_V4) )
+       OCTransportAdapter m_transport = (OC_ADAPTER_IP | OC_ADAPTER_TCP);
+       if (OC_STACK_OK != OCInit2(OC_CLIENT_SERVER, OC_IP_USE_V4, OC_IP_USE_V4, m_transport)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "RESOURCE SERVER START FAILED");
+               return;
+       }
+
+       THINGS_LOG(THINGS_INFO, TAG, "Resource Server IS NOW STARTING...");
+
+       g_quit_flag = 0;
+
+#ifdef __ST_THINGS_RTOS__
+       pthread_create_rtos(&g_thread_id_server, NULL, server_execute_loop, (void *)NULL, THINGS_STACK_SERVEREXCETUE_LOOP_THREAD);
+#else
+       things_thread_create(&g_thread_id_server, NULL, server_execute_loop, (void *)NULL);
+#endif
+
+       register_req_handler(builder, cb);
+}
+
+void deinit_builder(things_server_builder_s *builder)
+{
+       if (builder != NULL) {
+               g_quit_flag = 1;
+               pthread_cancel(g_thread_id_server);
+               pthread_join(g_thread_id_server, NULL);
+               pthread_detach(g_thread_id_server);
+               g_thread_id_server = NULL;
+
+               pthread_cancel(g_thread_id_presence);
+               pthread_join(g_thread_id_presence, NULL);
+               pthread_detach(g_thread_id_presence);
+               g_thread_id_presence = NULL;
+
+               // 1.    Need to unregister those registered resource in the Stack
+               // 2.    Free the payload of each resources
+               for (size_t iter = 0; iter < builder->res_num; iter++) {
+
+                       if (builder->gres_arr[iter]->rep != NULL) {
+                               things_release_representation_inst(builder->gres_arr[iter]->rep);
+                       }
+               }
+       }
+
+       if (OCStop() != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "OCStack process error");
+       }
+}
+
+void set_device_info(things_server_builder_s *builder, char *device_name, char *device_type)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/d] name :%s", device_name);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/d] type :%s", device_type);
+
+       OCDeviceInfo device_info;
+       device_info.deviceName = NULL;
+       device_info.types = NULL;
+       device_info.specVersion = NULL;
+       device_info.dataModelVersions = NULL;
+
+       duplicate_string(device_name, &device_info.deviceName);
+       duplicate_string(OC_SPEC_VERSION, &device_info.specVersion);
+       device_info.dataModelVersions = OCCreateOCStringLL(DEFAULT_DATA_MODEL_VERSIONS);
+       device_info.types = OCCreateOCStringLL(device_type);
+       OCResourcePayloadAddStringLL(&device_info.types, OC_RSRVD_RESOURCE_TYPE_DEVICE);
+       OCSetDeviceInfo(device_info);
+
+       // OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, KEY_ATTR_DEVICE_NAME, device_name);
+
+       free(device_info.deviceName);
+       free(device_info.specVersion);
+       OCFreeOCStringLL(device_info.dataModelVersions);
+       OCFreeOCStringLL(device_info.types);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+void set_platform_info(things_server_builder_s *builder, char *model_num, char *pver, char *osver, char *hwver, char *fwver, char *venderid)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (model_num == NULL || strlen(model_num) < 1) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid input for registering platform Info");
+               return;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Manufacturer :%s", MANUFACTURER_NAME);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Model Name :%s", model_num);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. Plaform :%s", pver);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. OS :%s", osver);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. HW :%s", hwver);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. FW :%s", fwver);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[/oic/p] Ver. vid :%s", venderid);
+
+       OCPlatformInfo platform_info;
+
+       platform_info.platformID = (char *)OCGetServerInstanceIDString();
+       platform_info.manufacturerName = MANUFACTURER_NAME;
+       platform_info.modelNumber = model_num;
+       platform_info.platformVersion = pver;
+       platform_info.operatingSystemVersion = osver;
+       platform_info.hardwareVersion = hwver;
+       platform_info.firmwareVersion = fwver;
+
+       platform_info.manufacturerUrl = MANUFACTURER_URL;
+       platform_info.dateOfManufacture = NULL;
+       platform_info.supportUrl = NULL;
+       platform_info.systemTime = NULL;
+
+       OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, KEY_ATTR_PLATFORM_VENDERID, venderid);
+
+       OCSetPlatformInfo(platform_info);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+things_server_builder_s *get_builder_instance()
+{
+       if (g_builder == NULL) {
+               g_builder = (things_server_builder_s *) things_malloc(sizeof(things_server_builder_s));
+               if (g_builder != NULL) {
+                       g_builder->init_module = &init_builder;
+                       g_builder->deinit_module = &deinit_builder;
+                       g_builder->set_device_info = &set_device_info;
+                       g_builder->set_platform_info = &set_platform_info;
+                       g_builder->create_resource = &create_resource;
+                       // g_builder->CreateActiveResource = &CreateActiveResource;
+                       g_builder->create_collection_resource = &create_collection_resource;
+                       g_builder->get_resource = &get_resource;
+                       g_builder->delete_resource = &delete_resource;
+                       g_builder->add_interface_type = &add_interface_type;
+                       g_builder->add_resource_type = &add_resource_type;
+                       g_builder->bind = &things_bind;
+                       g_builder->bind_all = &bind_all;
+                       g_builder->broadcast_presence = &broadcast_presence;
+                       g_builder->res_num = 0;
+                       g_builder->handler = NULL;
+
+                       is_presence = false;
+
+                       return g_builder;
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Not enough Memory for Builder Instance");
+                       return NULL;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Builder Instance Already Created");
+               return g_builder;
+       }
+}
+
+void release_builder_instance(things_server_builder_s *builder)
+{
+       if (builder) {
+               //    Thread should be terminated first..
+               if (!g_quit_flag) {
+                       builder->deinit_module(builder);
+               }
+
+               if (builder->res_num > 0) {
+                       for (size_t iter = 0; iter < builder->res_num; iter++) {
+                               if (builder->gres_arr[iter] != NULL) {
+                                       /*! Added by st_things for memory Leak fix
+                                        */
+                                       release_resource_inst_impl(builder->gres_arr[iter]);
+                                       builder->gres_arr[iter] = NULL;
+                               }
+                       }
+               }
+
+               things_free(builder);
+               g_builder = NULL;
+               is_presence = false;
+       }
+}
diff --git a/framework/src/st_things/things_stack/src/common/inc/things_def.h b/framework/src/st_things/things_stack/src/common/inc/things_def.h
new file mode 100644 (file)
index 0000000..33f5a43
--- /dev/null
@@ -0,0 +1,175 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_DEF_
+#define _THINGS_DEF_
+
+/**
+ * Defines used in more than 2 devices are defined here
+ * All the other device specific values are defined
+ * in the "oicXXdef.h"
+ */
+
+#define OIC_STACK_FIRMWARE_VERSION      "OIC_0.9.1.D.17.03.31_1_30dbca2"
+
+#define MANUFACTURER_NAME               "Samsung Electronics"
+#define MANUFACTURER_URL                "http://www.samsung.com"
+
+/* Resource Types */
+#define OIC_INTERFACE_BASELINE          "oic.if.baseline"
+#define OIC_INTERFACE_LINKEDLIST        "oic.if.ll"
+#define OIC_INTERFACE_LINKEDBATCH       "oic.if.lb"
+#define OIC_INTERFACE_BATCH             "oic.if.b"
+#define OIC_INTERFACE_ACTUATOR          "oic.if.a"
+#define OIC_INTERFACE_SENSOR            "oic.if.s"
+
+#define OIC_RTYPE_COLLECTION_WK         "oic.wk.col"
+#define OIC_RTYPE_MAINTENANCE_WK        "oic.wk.mnt"
+#define OIC_RTYPE_BINARY_SWITCH         "oic.r.switch.binary"
+#define OIC_RTYPE_MODE                  "oic.r.mode"
+#define OIC_RTYPE_TEMPERATURE           "oic.r.temperature"
+#define OIC_RTYPE_LIGHT_DIMMING         "oic.r.light.dimming"
+
+#define SEC_RTYPE_ALARM                 "x.com.samsung.da.alarms"
+#define SEC_RTYPE_THINGS_DEVICE         "x.com.samsung.devcol"
+#define SEC_RTYPE_TEMPERATURE           "x.com.samsung.da.temperatures"
+#define SEC_RTYPE_BIXBY                 "x.com.samsung.bixby"
+#define SEC_RTYPE_FILE_LIST             "x.com.samsung.file.list"
+#define SEC_RTYPE_FILE_TRANSFER         "x.com.samsung.file.transfer"
+#define SEC_RTYPE_CONTENTS_PROVIDER     "x.com.samsung.contents.provider"
+#define SEC_RTYPE_CONTENTS_RENDERER     "x.com.samsung.contents.renderer"
+#define SEC_RTYPE_DISHWASHER            "x.com.samsung.da.dishwasher"
+#define SEC_RTYPE_PROV_INFO             "x.com.samsung.provisioninginfo"
+
+/* Atrribute Keys */
+#define SEC_ATTRIBUTE_LENGTH                      "x.com.samsung.da.length"
+#define SEC_ATTRIBUTE_TYPE                        "x.com.samsung.da.type"
+#define SEC_ATTRIBUTE_ID                          "x.com.samsung.da.id"
+#define SEC_ATTRIBUTE_NUMBER                      "x.com.samsung.da.number"
+#define SEC_ATTRIBUTE_DESCRIPTION                 "x.com.samsung.da.description"
+
+#define SEC_ATTRIBUTE_THINGS_NAME                 "x.com.samsung.da.name"
+#define SEC_ATTRIBUTE_MODEL_NUM                   "x.com.samsung.da.model_num"
+#define SEC_ATTRIBUTE_DESCRIPTION                 "x.com.samsung.da.description"
+#define SEC_ATTRIBUTE_SERIAL_NUM                  "x.com.samsung.da.serialNum"
+#define SEC_ATTRIBUTE_VERSION_ID                  "x.com.samsung.da.versionId"
+#define SEC_ATTRIBUTE_APPROVED_STATE              "x.com.samsung.da.approvedState"
+#define SEC_ATTRIBUTE_VERSION_AVAILABLE           "x.com.samsung.da.newVersionAvailable"
+#define SEC_ATTRIBUTE_ITEMS                     "x.com.samsung.da.items"
+
+// Common Attribute Keys
+#define SEC_ATTRIBUTE_COMMON_ITEMS          "x.com.samsung.items"
+#define SEC_ATTRIBUTE_COMMON_ID             "x.com.samsung.id"
+#define SEC_ATTRIBUTE_COMMON_TARGET         "x.com.samsung.target"
+#define SEC_ATTRIBUTE_COMMON_VALUE          "x.com.samsung.value"
+#define SEC_ATTRIBUTE_LOG_COLLECT           "x.com.samsung.collectlogs"
+#define SEC_ATTRIBUTE_LOG_IDS               "x.com.samsung.logids"
+#define SEC_ATTRIBUTE_FILE_BLOB             "x.com.samsung.blob"
+#define SEC_ATTRIBUTE_NAME                  "x.com.samsung.name"
+
+#define SEC_ATTRIBUTE_PROV_TARGETS          "x.com.samsung.provisioning.targets"
+#define SEC_ATTRIBUTE_PROV_EZSETDI          "x.com.samsung.provisioning.easysetupdi"
+#define SEC_ATTRIBUTE_PROV_RESET            "x.com.samsung.provisioning.reset"
+#define SEC_ATTRIBUTE_PROV_TARGET_OWNED     "x.com.samsung.provisioning.owned"
+#define SEC_ATTRIBUTE_PROV_TERMINATE_AP     "x.com.samsung.provisioning.stopAP"
+#define SEC_ATTRIBUTE_PROV_ABORT            "x.com.samsung.provisioning.abort"
+#define SEC_ATTRIBUTE_PROV_TARGET_ID        "x.com.samsung.targetDi"
+#define SEC_ATTRIBUTE_PROV_TARGET_RT        "x.com.samsung.targetRt"
+#define SEC_ATTRIBUTE_PROV_TARGET_PUBED     "x.com.samsung.published"
+
+#define SEC_ATTRIBUTE_AP_ITEMS              "x.com.samsung.accesspoint.items"
+#define SEC_ATTRIBUTE_AP_CHANNAL            "x.com.samsung.channel"
+#define SEC_ATTRIBUTE_AP_ENCTYPE            "x.com.samsung.encryptionType"
+#define SEC_ATTRIBUTE_AP_MACADDR            "x.com.samsung.macAddress"
+#define SEC_ATTRIBUTE_AP_MAXRATE            "x.com.samsung.maxRate"
+#define SEC_ATTRIBUTE_AP_RSSI               "x.com.samsung.rssi"
+#define SEC_ATTRIBUTE_AP_SECTYPE            "x.com.samsung.securityType"
+#define SEC_ATTRIBUTE_AP_SSID               "x.com.samsung.ssid"
+
+#define SEC_ATTRIBUTE_CONTENTS              "x.com.samsung.contents"
+#define SEC_ATTRIBUTE_CONTENTS_RT           "x.com.samsung.rt"
+#define SEC_ATTRIBUTE_CONTENTS_PROVIDER     "x.com.samsung.provider"
+#define SEC_ATTRIBUTE_CONTENTS_HOST         "x.com.samsung.host"
+#define SEC_ATTRIBUTE_CONTENTS_PATH         "x.com.samsung.path"
+#define SEC_ATTRIBUTE_CONTENTS_QUERY        "x.com.samsung.query"
+#define SEC_ATTRIBUTE_CONTENTS_MIME_TYPE    "x.com.samsung.mimeType"
+#define SEC_ATTRIBUTE_CONTENTS_TRANSPORT    "x.com.samsung.transport"
+#define SEC_ATTRIBUTE_CONTENTS_ENCODING     "x.com.samsung.encoding"
+#define SEC_ATTRIBUTE_CONTENTS_PAYLOAD      "x.com.samsung.payload"
+#define SEC_ATTRIBUTE_CONTENTS_ACTION       "x.com.samsung.action"
+#define SEC_ATTRIBUTE_CONTENTS_CAPA_TYPE    "x.com.samsung.capability.type"
+#define SEC_ATTRIBUTE_CONTENTS_DATETIME     "x.com.samsung.datetime"
+
+#define OIC_QUERY_KEY_OP                    "op"
+#define OIC_QUERY_VALUE_UPDATE              "update"
+
+/* Resource URI */
+#define URI_OIC                         "/oic"
+#define URI_SEC                         "/sec"
+#define URI_WK_MAINTENANCE              "/mnt"
+#define URI_OVEN                        "/oven"
+#define URI_DEVICE_COL                  "/device"
+#define URI_TEMPERATURE                 "/temperature"
+#define URI_TEMPERATURES                "/temperatures"
+#define URI_BIXBY                       "/bixby"
+#define URI_ACTIONS                     "/actions"
+#define URI_ALARMS                      "/alarms"
+#define URI_INFORMATION                 "/information"
+#define URI_SENSOR                      "/sensors"
+#define URI_VENDER_SPECIFIC             "/vs"
+#define URI_COOK                        "/cook"
+#define URI_DOOR                        "/door"
+#define URI_DOORS                       "/doors"
+#define URI_FILE                        "/file"
+#define URI_LIST                        "/list"
+#define URI_TRANSFER                    "/transfer"
+#define URI_CONTENTS                    "/contents"
+#define URI_PROVIDER                    "/provider"
+#define URI_RENDERER                    "/renderer"
+#define URI_PROVINFO                    "/provisioninginfo"
+
+/* Temperature Type Resources */
+#define URI_FRIDGE_COOLER               "/cooler"
+#define URI_FRIDGE_FREEZER              "/freezer"
+#define URI_FRIDGE_CVROOM               "/cvroom"
+#define URI_OVEN_PROBE                  "/prob"
+#define URI_ACCESSPOINTLIST             "/accesspointlist"
+
+/* Notification */
+#define URI_PUSHSERVICE                 "/service/pushservice"
+#define KEY_MESSAGE                     "message"
+#define KEY_EXTRA                       "x.com.samsung.da.notification"
+#define KEY_PUSH_CODE                   "x.com.samsung.code"
+#define KEY_PUSH_DATA                   "x.com.samsung.data"
+#define KEY_PUSH_DATA_ET                "et"
+#define KEY_PUSH_DATA_DT                "dt"   //Device Type
+#define KEY_PUSH_DATA_RT                "rt"   //Resource Type
+#define KEY_PUSH_DATA_DNAME             "dname"        //Device Name
+#define KEY_PUSH_DATA_REP               "rep"  //Representation
+#define KEY_PUSH_NS_MESSAGE_ID          "x.org.iotivity.ns.messageid"
+#define KEY_PUSH_NS_PROVIDER_ID         "x.org.iotivity.ns.providerid"
+
+#define MAX_LEN_FILE_ID                  (10)
+#define MAX_NUM_OICINFO                 (200)
+#define MAX_NUM_OICFILE                  (10)
+#define MAX_NUM_OICCONTENT              (100)
+#define MAX_NUM_SCHEDULE                 (15)
+#define MAX_NUM_AP                       (50)
+#define MAX_NUM_AP                      50
+
+#endif                                                 // _THINGS_DEF_
diff --git a/framework/src/st_things/things_stack/src/common/logging/Make.defs b/framework/src/st_things/things_stack/src/common/logging/Make.defs
new file mode 100644 (file)
index 0000000..35bbc36
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += things_logger.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/logging/
+VPATH += :src/st_things/things_stack/src/common/logging/
diff --git a/framework/src/st_things/things_stack/src/common/logging/inc/things_logger.h b/framework/src/st_things/things_stack/src/common/logging/inc/things_logger.h
new file mode 100644 (file)
index 0000000..814abc4
--- /dev/null
@@ -0,0 +1,138 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef THINGS_LOGGER_H_
+#define THINGS_LOGGER_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "things_def.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Log Value Macro's */
+#define THINGS_FUNC_ENTRY "IN"
+#define THINGS_FUNC_EXIT "OUT"
+#define THINGS_MEMORY_ERROR "Memory Error"
+#define THINGS_INVALID_PARAM "Invalid Parameter"
+
+#define THINGS_OIC "OIC"
+
+#define PCF(str) str
+
+// Max buffer size used in variable argument log function
+#define MAX_LOG_V_BUFFER_SIZE (256)
+
+// Log levels
+
+typedef enum {
+       THINGS_DEBUG = 0, THINGS_INFO, THINGS_WARNING, THINGS_ERROR, THINGS_FATAL
+} things_log_level_e;
+
+/**
+ * Initialize the logger.
+ */
+void things_log_init();
+
+/**
+ * Called to Free dyamically allocated resources used with custom logging.
+ * Not necessary if default logging is used
+ *
+ */
+void things_log_shutdown();
+
+/**
+ * Set the Version.
+ */
+void things_log_set_version(char *version);
+
+/**
+ * Output a log string with the specified priority level.
+ * Only defined for Linux and Android
+ *
+ * @param level  - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag    - Module name
+ * @param log_str - log string
+ */
+void things_log(things_log_level_e level, const char *tag, const char *funcName, const int16_t line_num, const char *log_str);
+
+/**
+ * Output a variable argument list log string with the specified priority level.
+ * Only defined for Linux and Android
+ *
+ * @param level  - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag    - Module name
+ * @param format - variadic log string
+ */
+void things_logv(things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *format, ...);
+//#endif //#ifdef __TIZEN__
+
+const char *__get_timestamp__();
+
+#ifdef TB_LOG
+#define THINGS_LOG_INIT()   things_log_init()
+#define THINGS_LOG_SHUTDOWN()   things_log_shutdown()
+#define THINGS_LOG(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+#define THINGS_LOG_D(level, tag, ...)   things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_V(level, tag, ...)   things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define PROFILING_TIME(...)
+#else                                                  //TB_LOG
+/*
+ * Merged RELEASE & LOGGING option into RELEASE
+ * THINGS_LOG_D will be disabled in RELEASE mode
+ * THINGS_LOG & THINGS_LOG_V will be enabled in RELEASE mode
+ *
+ */
+#define THINGS_LOG_CONFIG(ctx)
+#define THINGS_LOG_SHUTDOWN()
+
+#define THINGS_LOG(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+#define THINGS_LOG_V(level, tag, ...)   things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_D(level, tag, ...)   things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define THINGS_LOG_DEBUG(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+#define THINGS_LOG_INFO(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+#define THINGS_LOG_WARNING(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+#define THINGS_LOG_ERROR(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+#define THINGS_LOG_FATAL(level, tag, log_str)  things_log((level), (tag), __FUNCTION__, __LINE__, (log_str))
+
+#define THINGS_LOG_V_DEBUG(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_V_INFO(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_V_WARNING(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_V_ERROR(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_V_FATAL(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define THINGS_LOG_D_DEBUG(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_D_INFO(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_D_WARNING(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_D_ERROR(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+#define THINGS_LOG_D_FATAL(level, tag, ...)  things_logv((level), (tag), __FUNCTION__, __LINE__, __VA_ARGS__)
+// Fot set loglevel //
+
+#define PROFILING_TIME(...)
+#define THINGS_LOG_INIT()
+// #define ENABLE_MALLOC_DEBUG
+#endif                                                 // TB_LOG
+
+#ifdef __cplusplus
+}
+#endif                                                 // __cplusplus
+#endif                                                 /* THINGS_LOGGER_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/logging/things_logger.c b/framework/src/st_things/things_stack/src/common/logging/things_logger.c
new file mode 100644 (file)
index 0000000..41b09af
--- /dev/null
@@ -0,0 +1,162 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <unistd.h>
+
+// if we have unistd.h, we're a Unix system
+#include <time.h>
+#include <sys/time.h>
+
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "string.h"
+
+static const char *LEVEL[] __attribute__((unused)) = {
+       "DEBUG", "INFOR", "WARNING", "ERROR", "FATAL"
+};
+static char ts_buf[64] = { 0 };
+
+char *p_version = NULL;
+things_log_level_e glevel = THINGS_INFO;
+void set_things_log_level(int level)
+{
+       if (level > 4) {
+               return;
+       }
+       int lev = level - 4;
+       glevel = abs(lev);
+}
+
+void things_log_init()
+{
+       /*
+        * Initialize p_version variable
+        */
+       p_version = NULL;
+}
+
+void things_log_shutdown()
+{
+       /*
+        * Free the memory allocated for p_version
+        */
+       things_free(p_version);
+}
+
+void things_log_set_version(char *version)
+{
+       if (NULL != p_version) {
+               things_free(p_version);
+       }
+
+       /*
+        * Allocate memory for p_version and set the version information
+        */
+       p_version = (char *)things_malloc(strlen(version) + 1);
+       if (NULL == p_version) {
+               printf("Error while allocating memory for version");
+               return;
+       }
+       memset(p_version, 0, strlen(version) + 1);
+       things_strncpy(p_version, version, strlen(version));
+}
+
+/**
+ * Output a log string with the specified priority level.
+ * Only defined for Linux and Android
+ *
+ * @param level  - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag    - Module name
+ * @param logStr - log string
+ */
+void things_log(things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *logStr)
+{
+       if (!logStr || !tag) {
+               return;
+       }
+       if (level < glevel) {
+               return;
+       }
+
+       struct timeval tv;
+       time_t nowtime = 0;
+       struct tm *nowtm = NULL;
+       char buf[64] = { 0 };
+
+       gettimeofday(&tv, NULL);
+       nowtime = tv.tv_sec;
+       nowtm = localtime(&nowtime);
+       strftime(buf, sizeof buf, "%m/%d %H:%M:%S", nowtm);
+
+       /* If Version information is not NULL, display the Version Information
+        * Logger Format is given below
+        * [<MM/YY H:M:S.uS> <LOGGER_VERSION>] <LOG_LEVEL> <TAG> <API> <LINE_NO> <LOG_STR>
+        */
+       if (p_version) {
+               printf("[%s %s] %s %s %s %d %s\n", buf, p_version, LEVEL[level], tag, func_name, line_num, logStr);
+       } else {
+               printf("T%d [%s] %s %s %s %d %s\n", getpid(), buf, LEVEL[level], tag, func_name, line_num, logStr);
+       }
+}
+
+/**
+ * Output a variable argument list log string with the specified priority level.
+ * Only defined for Linux and Android
+ *
+ * @param level  - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag    - Module name
+ * @param format - variadic log string
+ */
+void things_logv(things_log_level_e level, const char *tag, const char *func_name, const int16_t line_num, const char *format, ...)
+{
+       if (!format || !tag) {
+               return;
+       }
+       if (level < glevel) {
+               return;
+       }
+       /*
+        * Using Variable arguments to extract each argument and passing it things_log API
+        */
+       char buffer[MAX_LOG_V_BUFFER_SIZE] = { 0 };
+       va_list args;
+       va_start(args, format);
+       vsnprintf(buffer, sizeof buffer - 1, format, args);
+       va_end(args);
+       things_log(level, tag, func_name, line_num, buffer);
+}
+
+//#endif
+
+const char *__get_timestamp__()
+{
+       struct timeval tv;
+       time_t nowtime = 0;
+       struct tm *nowtm = NULL;
+
+       gettimeofday(&tv, NULL);
+       nowtime = tv.tv_sec;
+       nowtm = localtime(&nowtime);
+       strftime(ts_buf, sizeof ts_buf, "%m/%d %H:%M:%S", nowtm);
+
+       return ts_buf;
+}
diff --git a/framework/src/st_things/things_stack/src/common/memory/Make.defs b/framework/src/st_things/things_stack/src/common/memory/Make.defs
new file mode 100644 (file)
index 0000000..4567cde
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += things_malloc.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/memory
+VPATH += :src/st_things/things_stack/src/common/memory
diff --git a/framework/src/st_things/things_stack/src/common/memory/inc/things_malloc.h b/framework/src/st_things/things_stack/src/common/memory/inc/things_malloc.h
new file mode 100644 (file)
index 0000000..b7b6125
--- /dev/null
@@ -0,0 +1,39 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef THINGS_MALLOC_H_
+#define THINGS_MALLOC_H_
+
+#include <stdio.h>
+
+#ifndef ENABLE_THINGS_MALLOC
+
+#define things_malloc(x) malloc(x)
+#define things_free(x) free(x)
+#define things_realloc(x, y) realloc(x, y)
+#define things_calloc(x, y) calloc(x, y)
+
+#else
+
+extern void *things_malloc(size_t size);
+extern void *things_realloc(void *ptr, size_t size);
+extern void *things_calloc(size_t num, size_t size);
+extern void things_free(void *ptr);
+#endif
+
+#endif                                                 /* THINGS_MALLOC_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/memory/things_malloc.c b/framework/src/st_things/things_stack/src/common/memory/things_malloc.c
new file mode 100644 (file)
index 0000000..2ffc7ae
--- /dev/null
@@ -0,0 +1,103 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 <stdlib.h>
+#include "things_malloc.h"
+
+#include "things_logger.h"
+
+#ifdef ENABLE_MALLOC_DEBUG
+#define TAG "[things_malloc]"
+#endif
+
+#ifdef ENABLE_MALLOC_DEBUG
+static uint32_t count;
+#endif
+
+#ifdef ENABLE_THINGS_MALLOC
+void *things_malloc(size_t size)
+{
+       if (0 == size) {
+               return NULL;
+       }
+
+       /* Allocating Memory for given size using malloc API
+        */
+#ifdef ENABLE_MALLOC_DEBUG
+       void *ptr = malloc(size);
+       count++;
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "malloc: ptr=%p, size=%u, count=%u", ptr, size, count);
+       return ptr;
+#else
+       return malloc(size);
+#endif
+}
+
+void *things_calloc(size_t num, size_t size)
+{
+       if (0 == size || 0 == num) {
+               return NULL;
+       }
+
+       /* Allocating Memory for given size using calloc API
+        */
+#ifdef ENABLE_MALLOC_DEBUG
+       void *ptr = calloc(num, size);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "calloc: ptr=%p, num=%u, size=%u", ptr, num, size);
+       return ptr;
+#else
+       return calloc(num, size);
+#endif
+}
+
+void *things_realloc(void *ptr, size_t size)
+{
+       // Override realloc() behavior for NULL pointer which normally would
+       // work as per malloc(), however we suppress the behavior of possibly
+       // returning a non-null unique pointer.
+       if (ptr == NULL) {
+               return things_malloc(size);
+       }
+       // Otherwise leave the behavior up to realloc() itself:
+
+#ifdef ENABLE_MALLOC_DEBUG
+       void *newptr = realloc(ptr, size);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "realloc: ptr=%p, newptr=%p, size=%u", ptr, newptr, size);
+       // Very important to return the correct pointer here, as it only *somtimes*
+       // differs and thus can be hard to notice/test:
+       return newptr;
+#else
+       return realloc(ptr, size);
+#endif
+}
+
+void things_free(void *ptr)
+{
+#ifdef ENABLE_MALLOC_DEBUG
+       // Since things_malloc() did not increment count if it returned NULL,
+       // guard the decrement:
+       if (ptr) {
+               count--;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "free: ptr=%p, count=%u", ptr, count);
+#endif
+
+       free(ptr);
+       ptr = NULL;
+}
+#endif
diff --git a/framework/src/st_things/things_stack/src/common/security/ssCrypto/include/ss_sha2.h b/framework/src/st_things/things_stack/src/common/security/ssCrypto/include/ss_sha2.h
new file mode 100644 (file)
index 0000000..5bbd730
--- /dev/null
@@ -0,0 +1,123 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+/*
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 02/02/2007
+ * Issue date:  04/30/2005
+ *
+ * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Chul Lee(chuls.lee@samsung.com)'s posting:
+ *   Modification for naming confilct.
+ *   Attach prefix 'SS_' for all function and constants.
+ *   Change name of data context to 'SS_SHAxxxContext' (xxx is bit length of digest)
+ */
+
+#ifndef SHA2_H
+#define SHA2_H
+
+#define SS_SHA224_DIGEST_SIZE (224 / 8)
+#define SS_SHA256_DIGEST_SIZE (256 / 8)
+#define SS_SHA384_DIGEST_SIZE (384 / 8)
+#define SS_SHA512_DIGEST_SIZE (512 / 8)
+
+#define SS_SHA256_BLOCK_SIZE  (512 / 8)
+#define SS_SHA512_BLOCK_SIZE  (1024 / 8)
+#define SS_SHA384_BLOCK_SIZE  SS_SHA512_BLOCK_SIZE
+#define SS_SHA224_BLOCK_SIZE  SS_SHA256_BLOCK_SIZE
+
+#ifndef SHA2_TYPES
+#define SHA2_TYPES
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+       unsigned int tot_len;
+       unsigned int len;
+       unsigned char block[2 * SS_SHA256_BLOCK_SIZE];
+       uint32 h[8];
+} ss_sha256_ctx;
+
+typedef struct {
+       unsigned int tot_len;
+       unsigned int len;
+       unsigned char block[2 * SS_SHA512_BLOCK_SIZE];
+       uint64 h[8];
+} ss_sha512_ctx;
+
+typedef ss_sha512_ctx ss_sha384_ctx;
+typedef ss_sha256_ctx ss_sha224_ctx;
+
+void ss_sha224_init(ss_sha224_ctx *ctx);
+void ss_sha224_update(ss_sha224_ctx *ctx, const unsigned char *message, unsigned int len);
+void ss_sha224_final(ss_sha224_ctx *ctx, unsigned char *digest);
+void ss_sha224(const unsigned char *message, unsigned int len, unsigned char *digest);
+
+void ss_sha256_init(ss_sha256_ctx *ctx);
+void ss_sha256_update(ss_sha256_ctx *ctx, const unsigned char *message, unsigned int len);
+void ss_sha256_final(ss_sha256_ctx *ctx, unsigned char *digest);
+void ss_sha256(const unsigned char *message, unsigned int len, unsigned char *digest);
+
+void ss_sha384_init(ss_sha384_ctx *ctx);
+void ss_sha384_update(ss_sha384_ctx *ctx, const unsigned char *message, unsigned int len);
+void ss_sha384_final(ss_sha384_ctx *ctx, unsigned char *digest);
+void ss_sha384(const unsigned char *message, unsigned int len, unsigned char *digest);
+
+void ss_sha512_init(ss_sha512_ctx *ctx);
+void ss_sha512_update(ss_sha512_ctx *ctx, const unsigned char *message, unsigned int len);
+void ss_sha512_final(ss_sha512_ctx *ctx, unsigned char *digest);
+void ss_sha512(const unsigned char *message, unsigned int len, unsigned char *digest);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                                                 /* !SHA2_H */
diff --git a/framework/src/st_things/things_stack/src/common/security/ssCrypto/src/Make.defs b/framework/src/st_things/things_stack/src/common/security/ssCrypto/src/Make.defs
new file mode 100644 (file)
index 0000000..574abec
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += ss_sha2.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/security/ssCrypto/src
+VPATH += :src/st_things/things_stack/src/common/security/ssCrypto/src
diff --git a/framework/src/st_things/things_stack/src/common/security/ssCrypto/src/ss_sha2.c b/framework/src/st_things/things_stack/src/common/security/ssCrypto/src/ss_sha2.c
new file mode 100644 (file)
index 0000000..afbd2db
--- /dev/null
@@ -0,0 +1,1006 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+/*
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 02/02/2007
+ * Issue date:  04/30/2005
+ *
+ * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Chul Lee(chuls.lee@samsung.com)'s posting:
+ *   Modification for naming confilct.
+ *   Attach prefix 'SS_' for all function and constants.
+ *   Change name of data context to 'SS_SHAxxxContext' (xxx is bit length of digest)
+ */
+
+#if 0
+#define UNROLL_LOOPS                   /* Enable loops unrolling */
+#endif
+
+#include <string.h>
+
+#include "ss_sha2.h"
+
+#define SS_SHFR(x, n)    (x >> n)
+#define SS_ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
+#define SS_ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
+#define SS_CH(x, y, z)  ((x & y) ^ (~x & z))
+#define SS_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+#define SS_SHA256_F1(x) (SS_ROTR(x,  2) ^ SS_ROTR(x, 13) ^ SS_ROTR(x, 22))
+#define SS_SHA256_F2(x) (SS_ROTR(x,  6) ^ SS_ROTR(x, 11) ^ SS_ROTR(x, 25))
+#define SS_SHA256_F3(x) (SS_ROTR(x,  7) ^ SS_ROTR(x, 18) ^ SS_SHFR(x,  3))
+#define SS_SHA256_F4(x) (SS_ROTR(x, 17) ^ SS_ROTR(x, 19) ^ SS_SHFR(x, 10))
+
+#define SS_SHA512_F1(x) (SS_ROTR(x, 28) ^ SS_ROTR(x, 34) ^ SS_ROTR(x, 39))
+#define SS_SHA512_F2(x) (SS_ROTR(x, 14) ^ SS_ROTR(x, 18) ^ SS_ROTR(x, 41))
+#define SS_SHA512_F3(x) (SS_ROTR(x,  1) ^ SS_ROTR(x,  8) ^ SS_SHFR(x,  7))
+#define SS_SHA512_F4(x) (SS_ROTR(x, 19) ^ SS_ROTR(x, 61) ^ SS_SHFR(x,  6))
+
+#define SS_UNPACK32(x, str)                      \
+{                                             \
+       *((str) + 3) = (uint8) ((x));       \
+       *((str) + 2) = (uint8) ((x) >>  8);       \
+       *((str) + 1) = (uint8) ((x) >> 16);       \
+       *((str) + 0) = (uint8) ((x) >> 24);       \
+}
+
+#define SS_PACK32(str, x)                        \
+{                                             \
+       *(x) =   ((uint32) *((str) + 3))    \
+                       | ((uint32) *((str) + 2) <<  8)    \
+                       | ((uint32) *((str) + 1) << 16)    \
+                       | ((uint32) *((str) + 0) << 24);   \
+}
+
+#define SS_UNPACK64(x, str)                      \
+{                                             \
+       *((str) + 7) = (uint8) ((x));       \
+       *((str) + 6) = (uint8) ((x) >>  8);       \
+       *((str) + 5) = (uint8) ((x) >> 16);       \
+       *((str) + 4) = (uint8) ((x) >> 24);       \
+       *((str) + 3) = (uint8) ((x) >> 32);       \
+       *((str) + 2) = (uint8) ((x) >> 40);       \
+       *((str) + 1) = (uint8) ((x) >> 48);       \
+       *((str) + 0) = (uint8) ((x) >> 56);       \
+}
+
+#define SS_PACK64(str, x)                        \
+{                                             \
+       *(x) =   ((uint64) *((str) + 7))    \
+                       | ((uint64) *((str) + 6) <<  8)    \
+                       | ((uint64) *((str) + 5) << 16)    \
+                       | ((uint64) *((str) + 4) << 24)    \
+                       | ((uint64) *((str) + 3) << 32)    \
+                       | ((uint64) *((str) + 2) << 40)    \
+                       | ((uint64) *((str) + 1) << 48)    \
+                       | ((uint64) *((str) + 0) << 56);   \
+}
+
+/* Macros used for loops unrolling */
+
+#define SS_SHA256_SCR(i)                         \
+{                                             \
+       w[i] =  SS_SHA256_F4(w[i -  2]) + w[i -  7]  \
+                       + SS_SHA256_F3(w[i - 15]) + w[i - 16]; \
+}
+
+#define SS_SHA512_SCR(i)                         \
+{                                             \
+       w[i] =  SS_SHA512_F4(w[i -  2]) + w[i -  7]  \
+                       + SS_SHA512_F3(w[i - 15]) + w[i - 16]; \
+}
+
+#define SS_SHA256_EXP(a, b, c, d, e, f, g, h, j)               \
+{                                                           \
+       t1 = wv[h] + SS_SHA256_F2(wv[e]) + SS_CH(wv[e], wv[f], wv[g]) \
+               + ss_sha256_k[j] + w[j];                              \
+       t2 = SS_SHA256_F1(wv[a]) + SS_MAJ(wv[a], wv[b], wv[c]);       \
+       wv[d] += t1;                                            \
+       wv[h] = t1 + t2;                                        \
+}
+
+#define SS_SHA512_EXP(a, b, c, d, e, f, g, h, j)               \
+{                                                           \
+       t1 = wv[h] + SS_SHA512_F2(wv[e]) + SS_CH(wv[e], wv[f], wv[g]) \
+               + ss_sha512_k[j] + w[j];                              \
+       t2 = SS_SHA512_F1(wv[a]) + SS_MAJ(wv[a], wv[b], wv[c]);       \
+       wv[d] += t1;                                            \
+       wv[h] = t1 + t2;                                        \
+}
+
+uint32 ss_sha224_h0[8] = { 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+                                                  0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
+                                                };
+
+uint32 ss_sha256_h0[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+                                                  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+                                                };
+
+uint64 ss_sha384_h0[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
+                                                  0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
+                                                  0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+                                                  0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
+                                                };
+
+uint64 ss_sha512_h0[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+                                                  0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+                                                  0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+                                                  0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+                                                };
+
+uint32 ss_sha256_k[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+                                                  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+                                                  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+                                                  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+                                                  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+                                                  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+                                                  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+                                                  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+                                                  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+                                                  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+                                                  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+                                                  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+                                                  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+                                                  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+                                                  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+                                                  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+                                                };
+
+uint64 ss_sha512_k[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+                                                  0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+                                                  0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+                                                  0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+                                                  0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+                                                  0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+                                                  0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+                                                  0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+                                                  0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+                                                  0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+                                                  0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+                                                  0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+                                                  0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+                                                  0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+                                                  0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+                                                  0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+                                                  0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+                                                  0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+                                                  0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+                                                  0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+                                                  0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+                                                  0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+                                                  0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+                                                  0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+                                                  0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+                                                  0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+                                                  0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+                                                  0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+                                                  0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+                                                  0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+                                                  0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+                                                  0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+                                                  0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+                                                  0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+                                                  0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+                                                  0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+                                                  0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+                                                  0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+                                                  0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+                                                  0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+                                                };
+
+/* SHA-256 functions */
+
+void ss_sha256_transf(ss_sha256_ctx *ctx, const unsigned char *message, unsigned int block_nb)
+{
+       uint32 w[64];
+       uint32 wv[8];
+       uint32 t1, t2;
+       const unsigned char *sub_block;
+       int i;
+
+#ifndef UNROLL_LOOPS
+       int j;
+#endif
+
+       for (i = 0; i < (int)block_nb; i++) {
+               sub_block = message + (i << 6);
+
+#ifndef UNROLL_LOOPS
+               for (j = 0; j < 16; j++) {
+                       SS_PACK32(&sub_block[j << 2], &w[j]);
+               }
+
+               for (j = 16; j < 64; j++) {
+                       SS_SHA256_SCR(j);
+               }
+
+               for (j = 0; j < 8; j++) {
+                       wv[j] = ctx->h[j];
+               }
+
+               for (j = 0; j < 64; j++) {
+                       t1 = wv[7] + SS_SHA256_F2(wv[4]) + SS_CH(wv[4], wv[5], wv[6])
+                                + ss_sha256_k[j] + w[j];
+                       t2 = SS_SHA256_F1(wv[0]) + SS_MAJ(wv[0], wv[1], wv[2]);
+                       wv[7] = wv[6];
+                       wv[6] = wv[5];
+                       wv[5] = wv[4];
+                       wv[4] = wv[3] + t1;
+                       wv[3] = wv[2];
+                       wv[2] = wv[1];
+                       wv[1] = wv[0];
+                       wv[0] = t1 + t2;
+               }
+
+               for (j = 0; j < 8; j++) {
+                       ctx->h[j] += wv[j];
+               }
+#else
+               SS_PACK32(&sub_block[0], &w[0]);
+               SS_PACK32(&sub_block[4], &w[1]);
+               SS_PACK32(&sub_block[8], &w[2]);
+               SS_PACK32(&sub_block[12], &w[3]);
+               SS_PACK32(&sub_block[16], &w[4]);
+               SS_PACK32(&sub_block[20], &w[5]);
+               SS_PACK32(&sub_block[24], &w[6]);
+               SS_PACK32(&sub_block[28], &w[7]);
+               SS_PACK32(&sub_block[32], &w[8]);
+               SS_PACK32(&sub_block[36], &w[9]);
+               SS_PACK32(&sub_block[40], &w[10]);
+               SS_PACK32(&sub_block[44], &w[11]);
+               SS_PACK32(&sub_block[48], &w[12]);
+               SS_PACK32(&sub_block[52], &w[13]);
+               SS_PACK32(&sub_block[56], &w[14]);
+               SS_PACK32(&sub_block[60], &w[15]);
+
+               SS_SHA256_SCR(16);
+               SS_SHA256_SCR(17);
+               SS_SHA256_SCR(18);
+               SS_SHA256_SCR(19);
+               SS_SHA256_SCR(20);
+               SS_SHA256_SCR(21);
+               SS_SHA256_SCR(22);
+               SS_SHA256_SCR(23);
+               SS_SHA256_SCR(24);
+               SS_SHA256_SCR(25);
+               SS_SHA256_SCR(26);
+               SS_SHA256_SCR(27);
+               SS_SHA256_SCR(28);
+               SS_SHA256_SCR(29);
+               SS_SHA256_SCR(30);
+               SS_SHA256_SCR(31);
+               SS_SHA256_SCR(32);
+               SS_SHA256_SCR(33);
+               SS_SHA256_SCR(34);
+               SS_SHA256_SCR(35);
+               SS_SHA256_SCR(36);
+               SS_SHA256_SCR(37);
+               SS_SHA256_SCR(38);
+               SS_SHA256_SCR(39);
+               SS_SHA256_SCR(40);
+               SS_SHA256_SCR(41);
+               SS_SHA256_SCR(42);
+               SS_SHA256_SCR(43);
+               SS_SHA256_SCR(44);
+               SS_SHA256_SCR(45);
+               SS_SHA256_SCR(46);
+               SS_SHA256_SCR(47);
+               SS_SHA256_SCR(48);
+               SS_SHA256_SCR(49);
+               SS_SHA256_SCR(50);
+               SS_SHA256_SCR(51);
+               SS_SHA256_SCR(52);
+               SS_SHA256_SCR(53);
+               SS_SHA256_SCR(54);
+               SS_SHA256_SCR(55);
+               SS_SHA256_SCR(56);
+               SS_SHA256_SCR(57);
+               SS_SHA256_SCR(58);
+               SS_SHA256_SCR(59);
+               SS_SHA256_SCR(60);
+               SS_SHA256_SCR(61);
+               SS_SHA256_SCR(62);
+               SS_SHA256_SCR(63);
+
+               wv[0] = ctx->h[0];
+               wv[1] = ctx->h[1];
+               wv[2] = ctx->h[2];
+               wv[3] = ctx->h[3];
+               wv[4] = ctx->h[4];
+               wv[5] = ctx->h[5];
+               wv[6] = ctx->h[6];
+               wv[7] = ctx->h[7];
+
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 0);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 1);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 2);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 3);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 4);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 5);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 6);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 7);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 8);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 9);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 10);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 11);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 12);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 13);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 14);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 15);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 16);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 17);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 18);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 19);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 20);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 21);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 22);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 23);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 24);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 25);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 26);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 27);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 28);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 29);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 30);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 31);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 32);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 33);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 34);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 35);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 36);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 37);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 38);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 39);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 40);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 41);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 42);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 43);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 44);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 45);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 46);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 47);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 48);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 49);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 50);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 51);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 52);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 53);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 54);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 55);
+               SS_SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 56);
+               SS_SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 57);
+               SS_SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 58);
+               SS_SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 59);
+               SS_SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 60);
+               SS_SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 61);
+               SS_SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 62);
+               SS_SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 63);
+
+               ctx->h[0] += wv[0];
+               ctx->h[1] += wv[1];
+               ctx->h[2] += wv[2];
+               ctx->h[3] += wv[3];
+               ctx->h[4] += wv[4];
+               ctx->h[5] += wv[5];
+               ctx->h[6] += wv[6];
+               ctx->h[7] += wv[7];
+#endif                                                 /* !UNROLL_LOOPS */
+       }
+}
+
+void ss_sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
+{
+       ss_sha256_ctx ctx;
+
+       ss_sha256_init(&ctx);
+       ss_sha256_update(&ctx, message, len);
+       ss_sha256_final(&ctx, digest);
+}
+
+void ss_sha256_init(ss_sha256_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+       int i;
+       for (i = 0; i < 8; i++) {
+               ctx->h[i] = ss_sha256_h0[i];
+       }
+#else
+       ctx->h[0] = ss_sha256_h0[0];
+       ctx->h[1] = ss_sha256_h0[1];
+       ctx->h[2] = ss_sha256_h0[2];
+       ctx->h[3] = ss_sha256_h0[3];
+       ctx->h[4] = ss_sha256_h0[4];
+       ctx->h[5] = ss_sha256_h0[5];
+       ctx->h[6] = ss_sha256_h0[6];
+       ctx->h[7] = ss_sha256_h0[7];
+#endif                                                 /* !UNROLL_LOOPS */
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void ss_sha256_update(ss_sha256_ctx *ctx, const unsigned char *message, unsigned int len)
+{
+       unsigned int block_nb;
+       unsigned int new_len, rem_len, tmp_len;
+       const unsigned char *shifted_message;
+
+       tmp_len = SS_SHA256_BLOCK_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SS_SHA256_BLOCK_SIZE) {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SS_SHA256_BLOCK_SIZE;
+
+       shifted_message = message + rem_len;
+
+       ss_sha256_transf(ctx, ctx->block, 1);
+       ss_sha256_transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SS_SHA256_BLOCK_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void ss_sha256_final(ss_sha256_ctx *ctx, unsigned char *digest)
+{
+       unsigned int block_nb;
+       unsigned int pm_len;
+       unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+       int i;
+#endif
+
+       block_nb = (1 + ((SS_SHA256_BLOCK_SIZE - 9)
+                                        < (ctx->len % SS_SHA256_BLOCK_SIZE)));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 6;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SS_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       ss_sha256_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+       for (i = 0; i < 8; i++) {
+               SS_UNPACK32(ctx->h[i], &digest[i << 2]);
+       }
+#else
+       SS_UNPACK32(ctx->h[0], &digest[0]);
+       SS_UNPACK32(ctx->h[1], &digest[4]);
+       SS_UNPACK32(ctx->h[2], &digest[8]);
+       SS_UNPACK32(ctx->h[3], &digest[12]);
+       SS_UNPACK32(ctx->h[4], &digest[16]);
+       SS_UNPACK32(ctx->h[5], &digest[20]);
+       SS_UNPACK32(ctx->h[6], &digest[24]);
+       SS_UNPACK32(ctx->h[7], &digest[28]);
+#endif                                                 /* !UNROLL_LOOPS */
+}
+
+/* SHA-512 functions */
+
+void ss_sha512_transf(ss_sha512_ctx *ctx, const unsigned char *message, unsigned int block_nb)
+{
+       uint64 w[80];
+       uint64 wv[8];
+       uint64 t1, t2;
+       const unsigned char *sub_block;
+       int i, j;
+
+       for (i = 0; i < (int)block_nb; i++) {
+               sub_block = message + (i << 7);
+
+#ifndef UNROLL_LOOPS
+               for (j = 0; j < 16; j++) {
+                       SS_PACK64(&sub_block[j << 3], &w[j]);
+               }
+
+               for (j = 16; j < 80; j++) {
+                       SS_SHA512_SCR(j);
+               }
+
+               for (j = 0; j < 8; j++) {
+                       wv[j] = ctx->h[j];
+               }
+
+               for (j = 0; j < 80; j++) {
+                       t1 = wv[7] + SS_SHA512_F2(wv[4]) + SS_CH(wv[4], wv[5], wv[6])
+                                + ss_sha512_k[j] + w[j];
+                       t2 = SS_SHA512_F1(wv[0]) + SS_MAJ(wv[0], wv[1], wv[2]);
+                       wv[7] = wv[6];
+                       wv[6] = wv[5];
+                       wv[5] = wv[4];
+                       wv[4] = wv[3] + t1;
+                       wv[3] = wv[2];
+                       wv[2] = wv[1];
+                       wv[1] = wv[0];
+                       wv[0] = t1 + t2;
+               }
+
+               for (j = 0; j < 8; j++) {
+                       ctx->h[j] += wv[j];
+               }
+#else
+               SS_PACK64(&sub_block[0], &w[0]);
+               SS_PACK64(&sub_block[8], &w[1]);
+               SS_PACK64(&sub_block[16], &w[2]);
+               SS_PACK64(&sub_block[24], &w[3]);
+               SS_PACK64(&sub_block[32], &w[4]);
+               SS_PACK64(&sub_block[40], &w[5]);
+               SS_PACK64(&sub_block[48], &w[6]);
+               SS_PACK64(&sub_block[56], &w[7]);
+               SS_PACK64(&sub_block[64], &w[8]);
+               SS_PACK64(&sub_block[72], &w[9]);
+               SS_PACK64(&sub_block[80], &w[10]);
+               SS_PACK64(&sub_block[88], &w[11]);
+               SS_PACK64(&sub_block[96], &w[12]);
+               SS_PACK64(&sub_block[104], &w[13]);
+               SS_PACK64(&sub_block[112], &w[14]);
+               SS_PACK64(&sub_block[120], &w[15]);
+
+               SS_SHA512_SCR(16);
+               SS_SHA512_SCR(17);
+               SS_SHA512_SCR(18);
+               SS_SHA512_SCR(19);
+               SS_SHA512_SCR(20);
+               SS_SHA512_SCR(21);
+               SS_SHA512_SCR(22);
+               SS_SHA512_SCR(23);
+               SS_SHA512_SCR(24);
+               SS_SHA512_SCR(25);
+               SS_SHA512_SCR(26);
+               SS_SHA512_SCR(27);
+               SS_SHA512_SCR(28);
+               SS_SHA512_SCR(29);
+               SS_SHA512_SCR(30);
+               SS_SHA512_SCR(31);
+               SS_SHA512_SCR(32);
+               SS_SHA512_SCR(33);
+               SS_SHA512_SCR(34);
+               SS_SHA512_SCR(35);
+               SS_SHA512_SCR(36);
+               SS_SHA512_SCR(37);
+               SS_SHA512_SCR(38);
+               SS_SHA512_SCR(39);
+               SS_SHA512_SCR(40);
+               SS_SHA512_SCR(41);
+               SS_SHA512_SCR(42);
+               SS_SHA512_SCR(43);
+               SS_SHA512_SCR(44);
+               SS_SHA512_SCR(45);
+               SS_SHA512_SCR(46);
+               SS_SHA512_SCR(47);
+               SS_SHA512_SCR(48);
+               SS_SHA512_SCR(49);
+               SS_SHA512_SCR(50);
+               SS_SHA512_SCR(51);
+               SS_SHA512_SCR(52);
+               SS_SHA512_SCR(53);
+               SS_SHA512_SCR(54);
+               SS_SHA512_SCR(55);
+               SS_SHA512_SCR(56);
+               SS_SHA512_SCR(57);
+               SS_SHA512_SCR(58);
+               SS_SHA512_SCR(59);
+               SS_SHA512_SCR(60);
+               SS_SHA512_SCR(61);
+               SS_SHA512_SCR(62);
+               SS_SHA512_SCR(63);
+               SS_SHA512_SCR(64);
+               SS_SHA512_SCR(65);
+               SS_SHA512_SCR(66);
+               SS_SHA512_SCR(67);
+               SS_SHA512_SCR(68);
+               SS_SHA512_SCR(69);
+               SS_SHA512_SCR(70);
+               SS_SHA512_SCR(71);
+               SS_SHA512_SCR(72);
+               SS_SHA512_SCR(73);
+               SS_SHA512_SCR(74);
+               SS_SHA512_SCR(75);
+               SS_SHA512_SCR(76);
+               SS_SHA512_SCR(77);
+               SS_SHA512_SCR(78);
+               SS_SHA512_SCR(79);
+
+               wv[0] = ctx->h[0];
+               wv[1] = ctx->h[1];
+               wv[2] = ctx->h[2];
+               wv[3] = ctx->h[3];
+               wv[4] = ctx->h[4];
+               wv[5] = ctx->h[5];
+               wv[6] = ctx->h[6];
+               wv[7] = ctx->h[7];
+
+               j = 0;
+
+               do {
+                       SS_SHA512_EXP(0, 1, 2, 3, 4, 5, 6, 7, j);
+                       j++;
+                       SS_SHA512_EXP(7, 0, 1, 2, 3, 4, 5, 6, j);
+                       j++;
+                       SS_SHA512_EXP(6, 7, 0, 1, 2, 3, 4, 5, j);
+                       j++;
+                       SS_SHA512_EXP(5, 6, 7, 0, 1, 2, 3, 4, j);
+                       j++;
+                       SS_SHA512_EXP(4, 5, 6, 7, 0, 1, 2, 3, j);
+                       j++;
+                       SS_SHA512_EXP(3, 4, 5, 6, 7, 0, 1, 2, j);
+                       j++;
+                       SS_SHA512_EXP(2, 3, 4, 5, 6, 7, 0, 1, j);
+                       j++;
+                       SS_SHA512_EXP(1, 2, 3, 4, 5, 6, 7, 0, j);
+                       j++;
+               } while (j < 80);
+
+               ctx->h[0] += wv[0];
+               ctx->h[1] += wv[1];
+               ctx->h[2] += wv[2];
+               ctx->h[3] += wv[3];
+               ctx->h[4] += wv[4];
+               ctx->h[5] += wv[5];
+               ctx->h[6] += wv[6];
+               ctx->h[7] += wv[7];
+#endif                                                 /* !UNROLL_LOOPS */
+       }
+}
+
+void ss_sha512(const unsigned char *message, unsigned int len, unsigned char *digest)
+{
+       ss_sha512_ctx ctx;
+
+       ss_sha512_init(&ctx);
+       ss_sha512_update(&ctx, message, len);
+       ss_sha512_final(&ctx, digest);
+}
+
+void ss_sha512_init(ss_sha512_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+       int i;
+       for (i = 0; i < 8; i++) {
+               ctx->h[i] = ss_sha512_h0[i];
+       }
+#else
+       ctx->h[0] = ss_sha512_h0[0];
+       ctx->h[1] = ss_sha512_h0[1];
+       ctx->h[2] = ss_sha512_h0[2];
+       ctx->h[3] = ss_sha512_h0[3];
+       ctx->h[4] = ss_sha512_h0[4];
+       ctx->h[5] = ss_sha512_h0[5];
+       ctx->h[6] = ss_sha512_h0[6];
+       ctx->h[7] = ss_sha512_h0[7];
+#endif                                                 /* !UNROLL_LOOPS */
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void ss_sha512_update(ss_sha512_ctx *ctx, const unsigned char *message, unsigned int len)
+{
+       unsigned int block_nb;
+       unsigned int new_len, rem_len, tmp_len;
+       const unsigned char *shifted_message;
+
+       tmp_len = SS_SHA512_BLOCK_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SS_SHA512_BLOCK_SIZE) {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SS_SHA512_BLOCK_SIZE;
+
+       shifted_message = message + rem_len;
+
+       ss_sha512_transf(ctx, ctx->block, 1);
+       ss_sha512_transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SS_SHA512_BLOCK_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 7], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 7;
+}
+
+void ss_sha512_final(ss_sha512_ctx *ctx, unsigned char *digest)
+{
+       unsigned int block_nb;
+       unsigned int pm_len;
+       unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+       int i;
+#endif
+
+       block_nb = 1 + ((SS_SHA512_BLOCK_SIZE - 17)
+                                       < (ctx->len % SS_SHA512_BLOCK_SIZE));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 7;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SS_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       ss_sha512_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+       for (i = 0; i < 8; i++) {
+               SS_UNPACK64(ctx->h[i], &digest[i << 3]);
+       }
+#else
+       SS_UNPACK64(ctx->h[0], &digest[0]);
+       SS_UNPACK64(ctx->h[1], &digest[8]);
+       SS_UNPACK64(ctx->h[2], &digest[16]);
+       SS_UNPACK64(ctx->h[3], &digest[24]);
+       SS_UNPACK64(ctx->h[4], &digest[32]);
+       SS_UNPACK64(ctx->h[5], &digest[40]);
+       SS_UNPACK64(ctx->h[6], &digest[48]);
+       SS_UNPACK64(ctx->h[7], &digest[56]);
+#endif                                                 /* !UNROLL_LOOPS */
+}
+
+/* SHA-384 functions */
+
+void ss_sha384(const unsigned char *message, unsigned int len, unsigned char *digest)
+{
+       ss_sha384_ctx ctx;
+
+       ss_sha384_init(&ctx);
+       ss_sha384_update(&ctx, message, len);
+       ss_sha384_final(&ctx, digest);
+}
+
+void ss_sha384_init(ss_sha384_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+       int i;
+       for (i = 0; i < 8; i++) {
+               ctx->h[i] = ss_sha384_h0[i];
+       }
+#else
+       ctx->h[0] = ss_sha384_h0[0];
+       ctx->h[1] = ss_sha384_h0[1];
+       ctx->h[2] = ss_sha384_h0[2];
+       ctx->h[3] = ss_sha384_h0[3];
+       ctx->h[4] = ss_sha384_h0[4];
+       ctx->h[5] = ss_sha384_h0[5];
+       ctx->h[6] = ss_sha384_h0[6];
+       ctx->h[7] = ss_sha384_h0[7];
+#endif                                                 /* !UNROLL_LOOPS */
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void ss_sha384_update(ss_sha384_ctx *ctx, const unsigned char *message, unsigned int len)
+{
+       unsigned int block_nb;
+       unsigned int new_len, rem_len, tmp_len;
+       const unsigned char *shifted_message;
+
+       tmp_len = SS_SHA384_BLOCK_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SS_SHA384_BLOCK_SIZE) {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SS_SHA384_BLOCK_SIZE;
+
+       shifted_message = message + rem_len;
+
+       ss_sha512_transf(ctx, ctx->block, 1);
+       ss_sha512_transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SS_SHA384_BLOCK_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 7], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 7;
+}
+
+void ss_sha384_final(ss_sha384_ctx *ctx, unsigned char *digest)
+{
+       unsigned int block_nb;
+       unsigned int pm_len;
+       unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+       int i;
+#endif
+
+       block_nb = (1 + ((SS_SHA384_BLOCK_SIZE - 17)
+                                        < (ctx->len % SS_SHA384_BLOCK_SIZE)));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 7;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SS_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       ss_sha512_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+       for (i = 0; i < 6; i++) {
+               SS_UNPACK64(ctx->h[i], &digest[i << 3]);
+       }
+#else
+       SS_UNPACK64(ctx->h[0], &digest[0]);
+       SS_UNPACK64(ctx->h[1], &digest[8]);
+       SS_UNPACK64(ctx->h[2], &digest[16]);
+       SS_UNPACK64(ctx->h[3], &digest[24]);
+       SS_UNPACK64(ctx->h[4], &digest[32]);
+       SS_UNPACK64(ctx->h[5], &digest[40]);
+#endif                                                 /* !UNROLL_LOOPS */
+}
+
+/* SHA-224 functions */
+
+void ss_sha224(const unsigned char *message, unsigned int len, unsigned char *digest)
+{
+       ss_sha224_ctx ctx;
+
+       ss_sha224_init(&ctx);
+       ss_sha224_update(&ctx, message, len);
+       ss_sha224_final(&ctx, digest);
+}
+
+void ss_sha224_init(ss_sha224_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+       int i;
+       for (i = 0; i < 8; i++) {
+               ctx->h[i] = ss_sha224_h0[i];
+       }
+#else
+       ctx->h[0] = ss_sha224_h0[0];
+       ctx->h[1] = ss_sha224_h0[1];
+       ctx->h[2] = ss_sha224_h0[2];
+       ctx->h[3] = ss_sha224_h0[3];
+       ctx->h[4] = ss_sha224_h0[4];
+       ctx->h[5] = ss_sha224_h0[5];
+       ctx->h[6] = ss_sha224_h0[6];
+       ctx->h[7] = ss_sha224_h0[7];
+#endif                                                 /* !UNROLL_LOOPS */
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void ss_sha224_update(ss_sha224_ctx *ctx, const unsigned char *message, unsigned int len)
+{
+       unsigned int block_nb;
+       unsigned int new_len, rem_len, tmp_len;
+       const unsigned char *shifted_message;
+
+       tmp_len = SS_SHA224_BLOCK_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SS_SHA224_BLOCK_SIZE) {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SS_SHA224_BLOCK_SIZE;
+
+       shifted_message = message + rem_len;
+
+       ss_sha256_transf(ctx, ctx->block, 1);
+       ss_sha256_transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SS_SHA224_BLOCK_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void ss_sha224_final(ss_sha224_ctx *ctx, unsigned char *digest)
+{
+       unsigned int block_nb;
+       unsigned int pm_len;
+       unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+       int i;
+#endif
+
+       block_nb = (1 + ((SS_SHA224_BLOCK_SIZE - 9)
+                                        < (ctx->len % SS_SHA224_BLOCK_SIZE)));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 6;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SS_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       ss_sha256_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+       for (i = 0; i < 7; i++) {
+               SS_UNPACK32(ctx->h[i], &digest[i << 2]);
+       }
+#else
+       SS_UNPACK32(ctx->h[0], &digest[0]);
+       SS_UNPACK32(ctx->h[1], &digest[4]);
+       SS_UNPACK32(ctx->h[2], &digest[8]);
+       SS_UNPACK32(ctx->h[3], &digest[12]);
+       SS_UNPACK32(ctx->h[4], &digest[16]);
+       SS_UNPACK32(ctx->h[5], &digest[20]);
+       SS_UNPACK32(ctx->h[6], &digest[24]);
+#endif                                                 /* !UNROLL_LOOPS */
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/Make.defs b/framework/src/st_things/things_stack/src/common/utils/Make.defs
new file mode 100644 (file)
index 0000000..5b29be7
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += things_hashmap.c things_list.c things_network.c things_ping.c things_queue.c things_string_util.c things_thread.c things_wait_handler.c things_rtos_util.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/common/utils
+VPATH += :src/st_things/things_stack/src/common/utils
\ No newline at end of file
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_hashmap.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_hashmap.h
new file mode 100644 (file)
index 0000000..878635e
--- /dev/null
@@ -0,0 +1,54 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_HASHMAP_H
+#define _THINGS_HASHMAP_H
+
+/** Hashmap structure (forward declaration) */
+typedef struct {
+       void *data;
+       int flags;
+       long key;
+} h_entry_s;
+
+typedef struct hashmap_s {
+       h_entry_s *table;
+       long size, count;
+} hashmap_s;
+
+// struct s_hashmap;
+// typedef struct s_hashmap hashmap;
+
+/** Creates a new hashmap near the given size. */
+extern struct hashmap_s *hashmap_create(int startsize);
+
+/** Inserts a new element into the hashmap. */
+extern void hashmap_insert(struct hashmap_s *, const void *data, unsigned long key);
+
+/** Returns the element for the key. */
+extern void *hashmap_get(struct hashmap_s *, unsigned long key);
+
+/** Returns the number of saved elements. */
+extern long hashmap_count(struct hashmap_s *);
+
+/** Removes the hashmap structure. */
+extern void hashmap_delete(struct hashmap_s *);
+
+extern unsigned long hashmap_get_hashval(unsigned char *str);
+
+#endif                                                 //_THINGS_HASHMAP_H
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_list.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_list.h
new file mode 100644 (file)
index 0000000..bb609d3
--- /dev/null
@@ -0,0 +1,70 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_LIST_H_
+#define _THINGS_LIST_H_
+
+#include <pthread.h>
+
+#include "octypes.h"
+#include "things_node.h"
+
+typedef int (*key_compare)(void *src_key, const void *dest_key);
+
+typedef struct list_s {
+       things_node_s *head;
+       things_node_s *tail;
+
+       // size of this list
+       int size;
+
+       // begin
+       things_node_s *(*begin)(struct list_s *);
+       // pop
+       void *(*pop)(struct list_s *p_list);
+       // end
+       things_node_s *(*end)(struct list_s *);
+       // size
+       int (*list_size)(struct list_s *);
+       // front
+       things_node_s *(*front)(struct list_s *);
+       // insert
+       void (*insert)(struct list_s *, void *);
+       // next
+       // Node*       (*get_next)             (oic_node_s*);
+       // erase
+       void *(*erase)(struct list_s *, void *);
+       void *(*erase_by_key)(struct list_s *, key_compare, const void *key);
+       // clear
+       void (*clear)(struct list_s *);
+       // find
+       things_node_s *(*find_by_key)(struct list_s *, key_compare, const void *key);
+       pthread_mutex_t q_mutex;        // = PTHREAD_MUTEX_INITIALIZER;
+} list_s;
+
+//-----------------------------------------------------------------------------
+// Function prototype
+//-----------------------------------------------------------------------------
+/**
+ * Create and initiate a Queue
+ */
+list_s *create_list(void);
+
+void terminate_list(list_s *list);
+
+#endif                                                 // _OICLIST_H_
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_network.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_network.h
new file mode 100644 (file)
index 0000000..f18e62f
--- /dev/null
@@ -0,0 +1,69 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_NETWORK_H_
+#define _THINGS_NETWORK_H_
+
+#include "cacommon.h"
+#include "things_api.h"
+
+#define MAX_ESSID            (36)
+#define MAX_SECUIRTYKEY      (64)
+#define MAX_TYPE_AUTH        (16)
+#define MAX_TYPE_ENC         (16)
+#define MAX_CHANNEL           (8)
+#define MAX_LEVEL_SIGNAL     (12)
+#define MAX_BSSID            (20)
+
+typedef struct access_point_info_s {
+       char e_ssid[MAX_ESSID];         // mandatory
+       char security_key[MAX_SECUIRTYKEY];     // mandatory
+       char auth_type[MAX_TYPE_AUTH];  // mandatory (None | WEP | WPA-PSK | WPA2-PSK)
+       char enc_type[MAX_TYPE_ENC];    // mandatory (WEP-64 | WEP-128 | TKIP | AES | TKIP_AES)
+       char channel[MAX_CHANNEL];      // optional
+       char signal_level[MAX_LEVEL_SIGNAL];    // optional
+       char bss_id[MAX_BSSID];         // optional
+} access_point_info_s;
+
+bool things_is_connected_ap(void);
+
+int things_is_net_initialize(void);
+
+void things_wifi_state_changed_cb_init(void);
+
+int things_wifi_state_changed_cb(int state, char *ap_name, char *ip_addr);
+
+void things_adapter_state_cb(CATransportAdapter_t adapter, bool enabled);
+
+void things_tcp_session_state_cb(const CAEndpoint_t *info, bool connected);
+
+int things_set_ap_connection(access_point_info_s *APinfo);
+
+int things_get_ap_list(access_point_info_s ***p_info, int *p_count);
+
+typedef int (*things_set_ap_connection_func_type)(access_point_info_s *p_info, char *p_cmd_id);
+
+typedef int (*things_get_ap_search_list_func_type)(access_point_info_s ***p_info, int *p_count);
+
+/*
+ * If Easy-Setup is Reseted, then need to recover about Current Connected-AP info.
+ * This Function serve to recover Connected-AP info with Customized-method.
+ */
+void things_apply_current_ap(void);
+
+#endif                                                 /* _THINGS_NETWORK_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_node.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_node.h
new file mode 100644 (file)
index 0000000..78c1912
--- /dev/null
@@ -0,0 +1,30 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_NODE_H_
+#define _THINGS_NODE_H_
+
+typedef struct things_node_s {
+       int req;                                        // 0 : Message, 1 : MsgInfo
+       void *item;
+       struct things_node_s *next;
+
+       // struct OicNode* (*Next)(struct OicNode*);
+} things_node_s;
+
+#endif
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_ping.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_ping.h
new file mode 100644 (file)
index 0000000..92039f6
--- /dev/null
@@ -0,0 +1,44 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef THINGS_CLOUD_PING_H_
+#define THINGS_CLOUD_PING_H_
+
+typedef enum ping_state_e {
+       PING_ST_INIT = 0,                       // Ping initialization
+       PING_ST_ISCLOUD = 1,            // remote client is Cloud CIserver
+       PING_ST_SIGNIN = (1 << 1),      // Sign-IN complete
+       PING_ST_TCPCONNECT = (1 << 2),  // TCP session connected
+       PING_ST_STARTTHREAD = (1 << 3), // Ping-Thread created
+       PING_ST_DISCOVERY = (1 << 4),   // Doing discovery /oic/ping resource in Cloud
+       PING_ST_REQUEST = (1 << 5),     // Doing common-ping request to Cloud
+       PING_ST_INTUPDATE = (1 << 6),   // Doing interval-update request to Cloud
+       PING_ST_INTUPDATED = (1 << 7),  // Success interval-update request to Cloud
+       PING_ST_TIMEOUT = (1 << 8),     // Occurred Time-out with regard to any request
+       PING_ALL_FLAG = 0xFFFFFFFF
+} ping_state_e;
+
+bool oic_ping_init(void);
+
+bool oic_ping_terminate(void);
+
+bool oic_ping_set_mask(const char *remote_addr, uint16_t port, ping_state_e state);
+
+bool oic_ping_unset_mask(const char *remote_addr, ping_state_e state);
+
+#endif                                                 /* THINGS_CLOUD_PING_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_queue.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_queue.h
new file mode 100644 (file)
index 0000000..646310a
--- /dev/null
@@ -0,0 +1,44 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _OICQUEUE_H_
+#define _OICQUEUE_H_
+
+#include <pthread.h>
+
+#include "things_node.h"
+
+typedef struct queue_s {
+       things_node_s *head;
+       things_node_s *tail;
+
+       void (*push)(struct queue_s *, void *, int);    // add item to tail
+       // get item from head and remove it from queue
+       void *(*pop)(struct queue_s *, int *);
+       // get item from head but keep it in queue
+       void *(*peek)(struct queue_s *, int *);
+
+       int (*length)(struct queue_s *);
+       // Remove node
+       // size of this queue
+       int size;
+
+       pthread_mutex_t q_mutex;        // = PTHREAD_MUTEX_INITIALIZER;
+} queue_s;
+
+#endif                                                 // _OICQUEUE_H_
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_rtos_util.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_rtos_util.h
new file mode 100644 (file)
index 0000000..41f00a3
--- /dev/null
@@ -0,0 +1,41 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef THINGS_RTOS_UTIL_H_
+#define THINGS_RTOS_UTIL_H_
+#include "pthread.h"
+typedef enum {
+       THINGS_STACK_PING_THREAD = 0,
+       THINGS_STACK_WAITHANDLER_THREAD,
+       THINGS_STACK_RESETLOOP_THREAD,
+       THINGS_STACK_CICONNETION_INIT_THREAD,
+       THINGS_STACK_CICONNETION_WAIT_THREAD,
+       THINGS_STACK_WIFI_PROV_SET_THREAD,
+       THINGS_STACK_CLOUD_REFRESH_THREAD,
+       THINGS_STACK_MESSAGE_HANDLING_THREAD,
+       THINGS_STACK_PRESENCE_NOTI_THREAD,
+       THINGS_STACK_SERVEREXCETUE_LOOP_THREAD,
+       THINGS_STACK_BASE_TIME_OUT_THREAD,
+       THINGS_STACK_OICABORT_THREAD,
+       THINGS_STACK_WIFI_JOIN,
+       THINGS_STACK_MAX_INDEX,
+} things_stack_thread_name;
+
+int pthread_create_rtos(FAR pthread_t *thread, FAR const pthread_attr_t *attr, pthread_startroutine_t start_routine, pthread_addr_t arg, things_stack_thread_name eThreadname);
+
+#endif                                                 /* THINGS_RTOS_UTIL_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_string_util.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_string_util.h
new file mode 100644 (file)
index 0000000..a6121e9
--- /dev/null
@@ -0,0 +1,36 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef THIGNS_STRING_UTIL_H
+#define THIGNS_STRING_UTIL_H
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#define MAX_BUF_LEN 512
+#define MAX_INPUT_QUERY_LEN 100
+
+int compare_strings(const char *src, const char *dst);
+int duplicate_string(const char *src, char **dst);
+void concat_string(char **target, char *attach);
+int hex_string_to_int(const char *hex, int *num);
+int get_id_value_from_query(char id_value[], char *input_query, int size);
+char *things_strcat(char *dest, size_t dest_size, const char *src);
+char *things_strncpy(char *destination, const char *source, size_t num);
+
+#endif
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_thread.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_thread.h
new file mode 100644 (file)
index 0000000..bd5b397
--- /dev/null
@@ -0,0 +1,26 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef THINGS_THREAD_MANAGER_H_
+#define THINGS_THREAD_MANAGER_H_
+
+#include <pthread.h>
+
+int things_thread_create(pthread_t *__newthread, pthread_attr_t *__attr, void *(*__start_routine)(void *), void *__arg);
+
+#endif                                                 /* OIC_THREAD_MANAGER_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/utils/inc/things_wait_handler.h b/framework/src/st_things/things_stack/src/common/utils/inc/things_wait_handler.h
new file mode 100644 (file)
index 0000000..e601d34
--- /dev/null
@@ -0,0 +1,48 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef _THINGS_WAIT_HANDLER_H_
+#define _THINGS_WAIT_HANDLER_H_
+
+#include <octypes.h>
+
+#define DEFAULT_TIMEOUT     60 // default 20 second wait.
+
+typedef struct timeout_s {
+       int cur_counter;                        // current time-out counter
+       int cur_num;                            // current time-out number
+       int ori_num;                            // initial time-out number
+} timeout_s;
+
+typedef void *(*check_time_out_call_func)(timeout_s *param);
+
+OCDoHandle get_request_handle(void);
+
+int cas_request_handle(OCDoHandle EqualVal, OCDoHandle writeHandleVal);
+
+bool is_empty_request_handle(void);
+
+OCDoHandle add_request_handle(OCDoHandle HandleVal);
+
+void del_all_request_handle(void);
+
+long long next_time_out(const long long ori_num, const long long cur_num);     // PDF Gaussian Distribution Time-Out Calculator.
+
+unsigned long int create_time_out_process(OCDoHandle hadler, check_time_out_call_func call_func, timeout_s *time_out);
+
+#endif                                                 /* _THINGS_WAIT_HANDLER_H_ */
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_hashmap.c b/framework/src/st_things/things_stack/src/common/utils/things_hashmap.c
new file mode 100644 (file)
index 0000000..569474d
--- /dev/null
@@ -0,0 +1,188 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 "things_hashmap.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/* this should be prime */
+#define TABLE_STARTSIZE 1021
+
+#define ACTIVE 1
+
+static unsigned long is_prime(unsigned long val)
+{
+       int i = 0, p = 0, exp = 0, a = 0;
+
+       for (i = 9; i--;) {
+               a = (rand() % (val - 4)) + 2;
+               p = 1;
+               exp = val - 1;
+               while (exp) {
+                       if (exp & 1) {
+                               p = (p * a) % val;
+                       }
+
+                       a = (a * a) % val;
+                       exp >>= 1;
+               }
+
+               if (p != 1) {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+static int find_prime_greater_than(int val)
+{
+       if (val & 1) {
+               val += 2;
+       } else {
+               val++;
+       }
+
+       while (!is_prime(val)) {
+               val += 2;
+       }
+
+       return val;
+}
+
+static void rehash(struct hashmap_s *hm)
+{
+       long size = hm->size;
+       h_entry_s *table = hm->table;
+
+       hm->size = find_prime_greater_than(size << 1);
+       hm->table = (h_entry_s *) calloc(sizeof(h_entry_s), hm->size);
+       hm->count = 0;
+
+       while (--size >= 0) {
+               if (table[size].flags == ACTIVE) {
+                       hashmap_insert(hm, table[size].data, table[size].key);
+               }
+       }
+
+       free(table);
+}
+
+struct hashmap_s *hashmap_create(int startsize)
+{
+       struct hashmap_s *hm = (struct hashmap_s *)malloc(sizeof(struct hashmap_s));
+
+       if (!startsize) {
+               startsize = TABLE_STARTSIZE;
+       } else {
+               startsize = find_prime_greater_than(startsize - 2);
+       }
+
+       hm->table = (h_entry_s *) calloc(sizeof(h_entry_s), startsize);
+       hm->size = startsize;
+       hm->count = 0;
+
+       return hm;
+}
+
+void hashmap_insert(struct hashmap_s *hash, const void *data, unsigned long key)
+{
+       long index, i, step;
+
+       if (hash->size <= hash->count) {
+               rehash(hash);
+       }
+
+       do {
+               index = key % hash->size;
+               step = (key % (hash->size - 2)) + 1;
+
+               for (i = 0; i < hash->size; i++) {
+                       if (hash->table[index].flags & ACTIVE) {
+                               if (hash->table[index].key == key) {
+                                       hash->table[index].data = (void *)data;
+                                       return;
+                               }
+                       } else {
+                               hash->table[index].flags |= ACTIVE;
+                               hash->table[index].data = (void *)data;
+                               hash->table[index].key = key;
+                               ++hash->count;
+                               return;
+                       }
+
+                       index = (index + step) % hash->size;
+               }
+
+               /* it should not be possible that we EVER come this far, but unfortunately
+                  not every generated prime number is prime (Carmichael numbers...) */
+               rehash(hash);
+       } while (1);
+}
+
+void *hashmap_get(struct hashmap_s *hash, unsigned long key)
+{
+       if (hash->count) {
+               long index = 0, i = 0, step = 0;
+               index = key % hash->size;
+               step = (key % (hash->size - 2)) + 1;
+
+               for (i = 0; i < hash->size; i++) {
+                       if (hash->table[index].key == key) {
+                               if (hash->table[index].flags & ACTIVE) {
+                                       return hash->table[index].data;
+                               }
+                               break;
+                       } else if (!hash->table[index].data) {
+                               break;
+                       }
+
+                       index = (index + step) % hash->size;
+               }
+       }
+
+       return 0;
+}
+
+long hashmap_count(struct hashmap_s *hash)
+{
+       return hash->count;
+}
+
+void hashmap_delete(struct hashmap_s *hash)
+{
+       if (hash != NULL) {
+               free(hash->table);
+       }
+       free(hash);
+}
+
+/*
+ * Reference : http://www.cse.yorku.ca/~oz/hash.html
+ */
+unsigned long hashmap_get_hashval(unsigned char *str)
+{
+       unsigned long hash = 5381;
+       int c = 0;
+
+       while (c = *str++) {
+               hash = ((hash << 5) + hash) + c;        /* hash * 33 + c */
+       }
+
+       return hash;
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_list.c b/framework/src/st_things/things_stack/src/common/utils/things_list.c
new file mode 100644 (file)
index 0000000..a82f120
--- /dev/null
@@ -0,0 +1,276 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "things_logger.h"
+#include "oic_malloc.h"
+#include "things_list.h"
+
+#define TAG "[things_list]"
+
+static void *erase(list_s *p_list, things_node_s *p_prev_node, things_node_s *p_del_node);
+
+// begin
+things_node_s *begin(list_s *p_list)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return p_list->head;
+}
+
+void *pop(list_s *p_list)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       void *item = NULL;
+       if (p_list == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "p_list is NULL.");
+               return NULL;
+       }
+
+       pthread_mutex_lock(&(p_list->q_mutex));
+       things_node_s *node = p_list->begin(p_list);
+       if (node != NULL) {
+               item = erase(p_list, NULL, node);
+       }
+       pthread_mutex_unlock(&(p_list->q_mutex));
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return item;
+}
+
+// end
+things_node_s *end(list_s *p_list)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return p_list->tail;
+}
+
+// size
+int list_size(list_s *p_list)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       pthread_mutex_lock(&(p_list->q_mutex));
+       int n_size = p_list->list_size;
+       pthread_mutex_unlock(&(p_list->q_mutex));
+
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return n_size;
+}
+
+// front
+things_node_s *front(list_s *p_list)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return p_list->begin(p_list);
+}
+
+static void link_node(list_s *p_list, things_node_s *p_prev_node, things_node_s *p_new_node)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+//    pthread_mutex_lock(&(p_list->q_mutex));
+       if (NULL == p_prev_node) {
+               p_list->head = p_new_node;
+               // Invalid Param
+               // THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_INVALID_PARAM);
+               // return;
+       } else {
+               p_prev_node->next = p_new_node;
+       }
+       p_list->size++;
+
+//    pthread_mutex_unlock(&(p_list->q_mutex));
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+// insert
+void insert(list_s *p_list, void *item)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       things_node_s *p_new_node = (things_node_s *) OICMalloc(sizeof(things_node_s));
+       if (NULL == p_new_node) {
+               //THINGS_LOG_ERROR(THINGS_ERROR, TAG, THINGS_MEMORY_ERROR);
+               return;
+       }
+       p_new_node->item = item;
+       p_new_node->next = NULL;
+
+       pthread_mutex_lock(&(p_list->q_mutex));
+       things_node_s *p_node = p_list->begin(p_list);
+       if (NULL != p_node) {
+               while (p_node->next) {
+                       // THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "p_node->item->key = %s", (char*)(((RequestInfo*)p_node->item)->frameId));
+                       p_node = p_node->next;
+               }
+
+               link_node(p_list, p_node, p_new_node);
+       } else {
+               p_list->head = p_new_node;
+       }
+
+       p_list->tail = p_new_node;
+       pthread_mutex_unlock(&(p_list->q_mutex));
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+// erase
+static void *erase(list_s *p_list, things_node_s *p_prev_node, things_node_s *p_del_node)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (p_del_node == p_list->head) {
+               p_list->head = p_del_node->next;
+               p_prev_node = p_list->head;
+       } else {
+               p_prev_node->next = p_del_node->next;
+       }
+
+       if (p_del_node == p_list->tail) {
+               p_list->tail = p_prev_node;
+       }
+
+       void *item = p_del_node->item;
+       p_del_node->item = NULL;
+       p_del_node->next = NULL;
+       OICFree(p_del_node);
+       p_list->size--;
+
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return item;
+}
+
+void *erase_by_key(list_s *p_list, key_compare compare, const void *key)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       void *item = NULL;
+
+       pthread_mutex_lock(&(p_list->q_mutex));
+       things_node_s *p_node = p_list->begin(p_list);
+
+       if (NULL != p_node) {
+               // Matched key with head's key.
+               if (compare(p_node->item, key)) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Delete Head");
+                       item = erase(p_list, p_list->head, p_node);
+               } else {
+                       while (p_node->next) {
+                               if (compare(p_node->next->item, key)) {
+                                       item = erase(p_list, p_node, p_node->next);
+                                       // THINGS_LOG_D(THINGS_DEBUG, TAG, "src key = %s dst_key = %s", pSrc_key, dst_key);
+                                       // exit(0);
+                                       break;
+                               }
+
+                               p_node = p_node->next;
+                       }
+               }
+       }
+
+       pthread_mutex_unlock(&(p_list->q_mutex));
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return item;
+}
+
+// clear
+void clear(list_s *p_list)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       pthread_mutex_lock(&(p_list->q_mutex));
+       things_node_s *p_node = p_list->begin(p_list);
+       if (NULL != p_node) {
+               while (p_node->next) {
+                       erase(p_list, p_node, p_node->next);
+                       // p_node = p_node->next;
+               }
+       }
+
+       p_list->head = p_list->tail = NULL;
+       pthread_mutex_unlock(&(p_list->q_mutex));
+
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+}
+
+// find
+things_node_s *find_by_key(list_s *p_list, key_compare compare, const void *key)
+{
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       pthread_mutex_lock(&(p_list->q_mutex));
+       things_node_s *p_node = p_list->begin(p_list);
+
+       if (NULL != p_node) {
+               while (p_node) {
+                       if (compare(p_node->item, key)) {
+                               break;
+                       }
+                       p_node = p_node->next;
+               }
+       }
+       pthread_mutex_unlock(&(p_list->q_mutex));
+
+//    THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return p_node;
+}
+
+list_s *create_list(void)
+{
+       // THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       list_s *list = (list_s *) OICMalloc(sizeof(list_s));
+       if (list == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.");
+               return NULL;
+       }
+
+       list->size = 0;
+       list->head = NULL;
+       list->tail = NULL;
+
+       list->begin = &begin;
+       list->pop = &pop;
+       list->end = &end;
+       list->list_size = &list_size;
+       list->front = &front;
+       list->insert = &insert;
+       list->erase_by_key = &erase_by_key;
+       list->clear = &clear;
+       list->find_by_key = &find_by_key;
+
+       pthread_mutex_init(&(list->q_mutex), NULL);
+
+       // THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+       return list;
+}
+
+void terminate_list(list_s *list)
+{
+       if (list == NULL) {
+               return;
+       }
+
+       list->clear(list);
+       pthread_mutex_destroy(&(list->q_mutex));
+       OICFree(list);
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_network.c b/framework/src/st_things/things_stack/src/common/utils/things_network.c
new file mode 100644 (file)
index 0000000..099de19
--- /dev/null
@@ -0,0 +1,309 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_api.h"
+#include "inc/things_network.h"
+
+#include "resource_handler.h"
+#include "cloud_manager.h"
+#include "easysetup_manager.h"
+#include "things_ping.h"
+
+#define TAG "[things_network]"
+
+static things_get_ap_search_list_func_type gGetAPSearchList = NULL;
+static things_set_ap_connection_func_type gSetAPConnection = NULL;
+
+static int app_state = -1;
+static char *app_ap_name = NULL;
+static char *app_ip_addr = NULL;
+volatile static bool is_connected_target_ap = false;
+
+#define IP_NULL_VAL     "0.0.0.0"
+
+/*******************************************************************
+ *
+ * state : 0 --> disconnect
+ *           1 --> connected
+ *
+ *******************************************************************/
+static int check_cb_skip(int state, char *ap_name, char *ip_addr)
+{
+       int ret = 0;
+
+       if (state != 0 && state != 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "invalid state value.(%d)", state);
+               return 0;
+       }
+
+       if (app_state == -1) {
+               app_state = 0;
+               app_ap_name = (char *)things_malloc(sizeof(char) * 1);
+               app_ap_name[0] = 0;
+               app_ip_addr = (char *)things_malloc(sizeof(char) * 1);
+               app_ip_addr[0] = 0;
+       }
+       // Process skip checking.
+       if ((state == 1 && ((ap_name == NULL || strlen(ap_name) == 0) || (ip_addr == NULL || strlen(ip_addr) == 0 || strncmp(ip_addr, IP_NULL_VAL, strlen(IP_NULL_VAL)) == 0))) || (state != 1 && state != 0)) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "invalid value.(state=%d, AP_SSID=%s, IP=%s)", state, ap_name, ip_addr);
+               return 0;
+       }
+
+       if (app_state != state) {
+               ret = 1;
+       } else if (state == 1 && (strncmp(ap_name, app_ap_name, strlen(app_ap_name)) != 0 || strncmp(ip_addr, app_ip_addr, strlen(app_ip_addr)) != 0)) {
+               ret = 1;
+       }
+
+       if (ret == 1) {
+               // Update contents
+               app_state = state;
+               if (ap_name) {
+                       things_free(app_ap_name);
+                       app_ap_name = strdup(ap_name);
+               }
+
+               if (ip_addr) {
+                       things_free(app_ip_addr);
+                       app_ip_addr = strdup(ip_addr);
+               }
+       }
+
+       return ret;
+}
+
+void things_wifi_state_changed_cb_init(void)   // when Soft-AP on, Not called Disconnected Call-Back Func. So, it's alternate.
+{
+       if (app_state == -1) {
+               app_state = 0;
+               app_ap_name = (char *)things_malloc(sizeof(char) * 1);
+               app_ap_name[0] = 0;
+               app_ip_addr = (char *)things_malloc(sizeof(char) * 1);
+               app_ip_addr[0] = 0;
+       } else {
+               app_ap_name[0] = 0;
+               app_ip_addr[0] = 0;
+       }
+
+       is_connected_target_ap = false;
+       ci_retry_stop_by_wifi_cb(false);
+}
+
+/*****************************************************************************
+ *
+ * It's called from st_things Application when WiFi state changed.
+ *
+ * state : 1 -> Connected to WiFi AP.
+ *         0 -> Disconnected from WiFi AP.
+ * ap_name : AP SSID.
+ * ip_addr : IP address.
+ *
+ *****************************************************************************/
+int things_wifi_state_changed_cb(int state, char *ap_name, char *ip_addr)
+{
+       bool Retry1Stop0 = false;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "state=%d, ap_name=%s, ip_name=%s", state, ap_name, ip_addr);
+
+       if (things_is_net_initialize() == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "gGetSoftAPState is NULL.");
+               return 0;
+       }
+
+       if (check_cb_skip(state, ap_name, ip_addr) != 1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Call-back process skiped.");
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "app_state=%d, app_ap_name=%s, app_ip_addr=%s", app_state, app_ap_name, app_ip_addr);
+
+       // Process.
+       if (state == 1) {                       // [Info] Always, when Soft-AP enabling, Call-Back State maintain disconnected. So, Soft-AP Check is not need.
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "AP CONNECTED.");
+               is_connected_target_ap = true;
+
+               set_ssid_in_wifi_resource(app_ap_name);
+               Retry1Stop0 = true;             // Re-Try with Last failed Access info.
+               esm_wifi_prov_check_cb(state, app_ap_name, app_ip_addr);
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "AP DISCONNECTED.");
+               is_connected_target_ap = false;
+               set_ssid_in_wifi_resource(NULL);
+       }
+
+       // Call Retry or forceStop Connection
+       ci_retry_stop_by_wifi_cb(Retry1Stop0);
+
+       return 1;
+}
+
+/*****************************************************************************
+ *
+ * It's called from Iotivity Framework when Adaptor state changed.
+ *
+ * adapter : Adapter Type.
+ * enabled  : true -> connected.
+ *            false-> disconnected.
+ *
+ *****************************************************************************/
+void things_adapter_state_cb(CATransportAdapter_t adapter, bool enabled)
+{
+       (void)adapter;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IN");
+
+       if (enabled) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CONNECTED but Not Guarantee to be Communication-Available");
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "AP DISCONNECTED.");
+               is_connected_target_ap = false;
+               set_ssid_in_wifi_resource(NULL);
+               ci_retry_stop_by_wifi_cb(false);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "OUT");
+}
+
+/*****************************************************************************
+ *
+ * It's called from Iotivity Framework when TCP session state changed.
+ *
+ * info : information about remote-peer.
+ * connected  : true -> connected
+ *              false-> disconnected
+ *
+ *****************************************************************************/
+void things_tcp_session_state_cb(const CAEndpoint_t *info, bool connected)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       if (info == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[IoTivity Error] invalid call-back parameter.(info is null.)");
+               return;
+       }
+
+       if (info->adapter != CA_ADAPTER_TCP) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Don't support adapter type.(%d)", info->adapter);
+               return;
+       }
+
+       if (strlen(info->addr) == 0 || info->port == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[IoTivity Error] invalid call-back parameter.(addrIP=%s, port=%d)", info->addr, info->port);
+               return;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IP = %s, port = %d", info->addr, info->port);
+
+       if (connected == true) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "CONNECTED");
+               oic_ping_set_mask(info->addr, info->port, PING_ST_TCPCONNECT);
+               return;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "DISCONNECTED");
+       oic_ping_unset_mask(info->addr, PING_ST_SIGNIN | PING_ST_TCPCONNECT);
+
+       if (ci_retry_stop_by_tcp_cb(info->addr, info->port) == -1) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] System Error.");
+               return;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+}
+
+int things_set_ap_connection(access_point_info_s *APinfo)
+{
+       if (things_is_net_initialize() == 0 || APinfo == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not yet Initialized or APinfo(0x%X) is NULL.", APinfo);
+               return 0;
+       }
+
+       return gSetAPConnection(APinfo, "0");
+}
+
+int things_get_ap_list(access_point_info_s ***p_info, int *p_count)
+{
+       if (things_is_net_initialize() == 0 || p_info == NULL || p_count == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Can't Call GetAPSearchList(p_info=0x%X, p_count=0x%X).", p_info, p_count);
+               return 0;
+       }
+
+       return gGetAPSearchList(p_info, p_count);
+}
+
+/*******************************************************************
+ *
+ * st_things API Function register
+ *
+ *******************************************************************/
+void things_register_set_ap_conn_func(things_set_ap_connection_func_type func)
+{
+       gSetAPConnection = func;
+}
+
+void things_register_get_ap_list_func(things_get_ap_search_list_func_type func)
+{
+       gGetAPSearchList = func;
+}
+
+/*****************************************************************************
+ *
+ * Ready Check All of Network APIs.
+ *
+ * return : 0 --> Not Ready.
+ *          1 --> Initialize Success.
+ *         -1 --> Initialize Failed.
+ *
+ *****************************************************************************/
+int things_is_net_initialize(void)
+{
+       if (gSetAPConnection == NULL || gGetAPSearchList == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] Not Initialized Network API.");
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] gSetAPConnection = 0x%X, gGetAPSearchList = 0x%X", gSetAPConnection, gGetAPSearchList);
+               return 0;
+       }
+
+       return 1;
+}
+
+bool things_is_connected_ap(void)
+{
+       return is_connected_target_ap;
+}
+
+/*
+ * If Easy-Setup is Reseted, then need to recover about Current Connected-AP info.
+ * This Function serve to recover Connected-AP info with Customized-method.
+ */
+void things_apply_current_ap(void)
+{
+       if (app_state == 1) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Connected AP.(AP_name=%s) Update AP info.", app_ap_name);
+               set_ssid_in_wifi_resource(app_ap_name);
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "DisConnected AP. So, Clear rested-AP info.");
+               set_ssid_in_wifi_resource(NULL);
+       }
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_ping.c b/framework/src/st_things/things_stack/src/common/utils/things_ping.c
new file mode 100644 (file)
index 0000000..f0b0ef6
--- /dev/null
@@ -0,0 +1,1255 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define OICPING_ENABLE      1
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <pthread.h>
+#include "ocpayload.h"
+#include "octypes.h"
+#include "es_common.h"
+#include "things_malloc.h"
+#include "things_logger.h"
+#include "things_list.h"
+#include "things_ping.h"
+
+#ifdef __ST_THINGS_RTOS__
+#include "things_rtos_util.h"
+#endif
+
+#ifdef OICPING_ENABLE
+#include "oickeepalive.h"
+#endif
+#include "resource_handler.h"
+#include "cloud_manager.h"
+
+#include "things_thread.h"
+
+#define TAG "[things_ping]"
+
+#define DEFAULT_CONTEXT_VALUE   0x99
+#define PING_UNIT           60 // 60 seconds is minimum value of ping.
+#define NET_TROUBLE_DELAY   5  // 5 seconds
+#define MAX_INTERVAL_EA     4  // Cloud Support 4 EA Interval class.
+
+#define KEEPALIVE_RESOURCE_URI "/oic/ping"
+
+typedef void *(*pthread_func_type)(void *);
+typedef struct things_ping_s {
+       pthread_mutex_t mutex_state;    // mutex for State variable.
+       ping_state_e bit_mask_state;    // State of Ping
+
+       pthread_mutex_t mutex_thread;   // mutex for handle_thread variable.
+       pthread_t handle_thread;        // Ping-Thread Handler
+       bool continue_thread;           // Continue Ping-Thread Flag.
+       char *addr;                                     // IP address of remote
+       uint16_t port;                          // Port number for remote
+
+       pthread_mutex_t mutex_int;      // mutex for interval variable.
+       int64_t interval[MAX_INTERVAL_EA];      // Interval EA  (unit : minute , max : 60)
+       int int_seq;                            // sequence of interval
+} things_ping_s;
+
+static list_s *list = NULL;
+static const char INTERVAL_ARRAY[] = "inarray";
+static const char INTERVAL[] = "in";
+things_ping_s *pPing = NULL;   //SKKIM for ping command
+
+static void *thd_ping_loop(things_ping_s *ping);
+static OCStackApplicationResult discover_ping_resource_handler(void *ctx, OCDoHandle handle, OCClientResponse *client_response);
+static OCStackApplicationResult ping_request_handler(void *ctx, OCDoHandle handle, OCClientResponse *client_response);
+static OCStackApplicationResult ping_update_request_handler(void *ctx, OCDoHandle handle, OCClientResponse *client_response);
+
+static things_ping_s *create_things_ping_s(const char *remoteAddr, const uint16_t port);
+static void terminate_things_ping_s(things_ping_s *ping);
+//static int is_state_key_equal(things_ping_s *ping, const ping_state_e value);
+static int is_ip_key_equal(things_ping_s *ping, const char *targetIP);
+static void check_ping_thread(things_ping_s *ping);
+static void set_mask(things_ping_s *ping, ping_state_e state);
+static bool get_mask(things_ping_s *ping, ping_state_e state);
+static bool cas_mask(things_ping_s *ping, ping_state_e preState, bool preStateThen, ping_state_e postState);
+static void unset_mask(things_ping_s *ping, ping_state_e state);
+static int find_resource_oic_ping(things_ping_s *ping);
+static int send_things_ping_request(things_ping_s *ping);
+static bool set_interval_send_update(things_ping_s *ping, int64_t *intervals, int intEA);
+static bool set_interval(things_ping_s *ping, int64_t *intervals, int intEA, ping_state_e confirmState);
+static bool set_def_interval(things_ping_s *ping);
+static bool things_ping_create_thread(things_ping_s *ping);
+static bool things_ping_destroy_thread(things_ping_s *ping);
+static void things_rep_payload_value_print(OCRepPayloadValue *value);
+static char *make_host_addr(const char *ip, const uint16_t port);
+static OCStackResult send_keep_alive_update_request(const char *host, int64_t *intervals, int intEA, OCCallbackData *cb);
+
+#ifdef OICPING_ENABLE
+bool oic_ping_init(void)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       bool res = false;
+
+       if (list == NULL) {
+               if ((list = create_list()) == NULL) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.");
+                       return res;
+               }
+
+               res = true;
+       } else {
+               res = true;
+       }
+
+       pPing = NULL;
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return res;
+}
+
+bool oic_ping_terminate(void)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       things_ping_s *ping = NULL;
+
+       if (list) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "things_ping_s terminate.");
+               while ((ping = (things_ping_s *) list->pop(list)) != NULL) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Terminate ping.(%s)", ping->addr);
+                       if (cas_mask(ping, PING_ST_STARTTHREAD, true, PING_ST_INIT) == true) {
+                               things_ping_destroy_thread(ping);
+                       }
+                       terminate_things_ping_s(ping);
+               }
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Terminate ping-list.");
+               terminate_list(list);
+               list = NULL;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return true;
+}
+
+bool oic_ping_set_mask(const char *remoteAddr, uint16_t port, ping_state_e state)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       things_node_s *node = NULL;
+       things_ping_s *ping = NULL;
+
+       if (remoteAddr == NULL || strlen(remoteAddr) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(remoteAddr=%s, state=%d)", remoteAddr, state);
+               return false;
+       }
+
+       if (list == NULL) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "OICPing Module is not initialized.");
+               return false;
+       }
+
+       node = list->find_by_key(list, (key_compare) is_ip_key_equal, remoteAddr);
+       if (node == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Found things_node_s for remote(%s). So, Create Node.", remoteAddr);
+               if ((ping = create_things_ping_s(remoteAddr, port)) == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.");
+                       return false;
+               }
+               list->insert(list, (void *)ping);
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Found things_node_s for remote(%s).", remoteAddr);
+               ping = node->item;
+       }
+
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not exist things_ping_s in remoteAddr_Node.(%s)", remoteAddr);
+               return false;
+       }
+
+       if (port != 0) {
+               ping->port = port;
+       }
+
+       set_mask(ping, state);
+       check_ping_thread(ping);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return true;
+}
+
+bool oic_ping_unset_mask(const char *remoteAddr, ping_state_e state)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+       things_node_s *node = NULL;
+       things_ping_s *ping = NULL;
+
+       if (remoteAddr == NULL || strlen(remoteAddr) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(remoteAddr=%s, state=%d)", remoteAddr, state);
+               return false;
+       }
+
+       if (list == NULL) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "OICPing Module is not initialized.");
+               return false;
+       }
+
+       node = list->find_by_key(list, (key_compare) is_ip_key_equal, remoteAddr);
+       if (node == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Found things_node_s for remote(%s).", remoteAddr);
+               return false;
+
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Found things_node_s for remote(%s).", remoteAddr);
+               ping = node->item;
+       }
+
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Not exist things_ping_s in remoteAddr_Node.(%s)", remoteAddr);
+               return false;
+       }
+
+       unset_mask(ping, state);
+
+       check_ping_thread(ping);
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return true;
+}
+
+#else
+bool oic_ping_init(void)
+{
+       return true;
+}
+
+bool oic_ping_terminate(void)
+{
+       return true;
+}
+
+bool oic_ping_set_mask(const char *remoteAddr, uint16_t port, ping_state_e state)
+{
+       return true;
+}
+
+bool oic_ping_unset_mask(const char *remoteAddr, ping_state_e state)
+{
+       return true;
+}
+
+#endif
+
+/***************************************************************************************
+ *
+ * Interval Ping-Thread Definition Function.
+ *
+ ***************************************************************************************/
+static void *__attribute__((optimize("O0"))) thd_ping_loop(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int sleepMinute = 0;
+
+       if (ping == NULL || ping->addr == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error]: Invalid arguments.(pint=0x%X)", ping);
+               return NULL;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "IP=%s, handle=0x%X, State=0x%X", ping->addr, ping->handle_thread, ping->bit_mask_state);
+
+       pthread_mutex_lock(&ping->mutex_int);
+       for (int i = 0; i < MAX_INTERVAL_EA; i++) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Interval[%d]=%lld", i, ping->interval[i]);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Intseq= %d", ping->int_seq);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "ContinuThread= %d", ping->continue_thread);
+
+       if (ping->interval[0] == (int64_t) 0 || ping->continue_thread == true) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error]: Invalid Interval-Time or Already Run-Thread for this ping.(interval[0]=%lld, continueFlag=%d)", ping->interval[0], ping->continue_thread);
+               pthread_mutex_unlock(&ping->mutex_int);
+               return NULL;
+       }
+       pthread_mutex_unlock(&ping->mutex_int);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Start FindResource for /oic/ping to Cloud(%s)", ping->addr);
+       do {                                            // /oic/ping Resource Finding Start
+               int sleepTime = 1;
+               sleepTime = find_resource_oic_ping(ping);
+               sleep(sleepTime);
+       } while (!ping->continue_thread);
+
+       pPing = ping;
+       int sleepDelay = 10;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Start common-Ping request for /oic/ping to Cloud(%s)", ping->addr);
+       while (ping->continue_thread) { // common-ping request Sending Start
+
+               if (sleepMinute == 0) {
+                       sleepMinute = send_things_ping_request(ping);
+               }
+
+               if (sleepMinute) {
+#ifdef __ST_THINGS_RTOS__
+                       int sleepCount = PING_UNIT - NET_TROUBLE_DELAY - sleepDelay;
+                       sleepDelay = 0;
+                       int cCount = 0;
+                       while (1) {
+                               if (cCount > sleepCount) {
+                                       break;
+                               }
+
+                               sleep(1);
+
+                               if (ping->continue_thread == false) {
+                                       sleepMinute = 0;
+                                       break;
+                               }
+                               cCount++;
+                       }
+#else
+                       sleep(PING_UNIT - NET_TROUBLE_DELAY);
+#endif
+
+                       sleepMinute--;
+               } else {
+                       sleep(1);
+               }
+
+               if (get_mask(ping, PING_ST_INTUPDATED) == true) {
+                       sleepMinute = 0;
+                       unset_mask(ping, PING_ST_INTUPDATED);
+               }
+       }
+
+       unset_mask(ping, PING_ST_STARTTHREAD | PING_ST_DISCOVERY | PING_ST_REQUEST | PING_ST_INTUPDATE | PING_ST_TIMEOUT);
+       ping->continue_thread = false;
+       set_def_interval(ping);
+       pPing = NULL;
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return (void *)1;
+}
+
+//void CommandPing()                //SKKIM for ping command
+//{
+//  if (pPing != NULL) {
+//      send_things_ping_request(pPing);
+//  }
+//}
+
+static OCStackApplicationResult discover_ping_resource_handler(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int64_t *interval = NULL;
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
+       things_ping_s *ping = (things_ping_s *) ctx;
+
+       if (ctx == (void *)DEFAULT_CONTEXT_VALUE || ctx == NULL || ping->addr == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "content value is invalid.(ctx=0x%X)", ctx);
+               return OC_STACK_DELETE_TRANSACTION;
+       }
+
+       if (client_response) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "ctx=0x%X", ctx);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Device =============> Discovered @ %s:%d", client_response->devAddr.addr, client_response->devAddr.port);
+
+               if (strncmp(ping->addr, client_response->devAddr.addr, strlen(client_response->devAddr.addr)) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error]: Mismatching address.(ping->addr=%s, recvAddr=%s)", ping->addr, client_response->devAddr.addr);
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+               // Parsing payload.
+               if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+                       OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+                       while (val != NULL) {
+                               things_rep_payload_value_print(val);
+                               val = val->next;
+                       }
+
+                       OCRepPayloadGetIntArray(((const OCRepPayload *)client_response->payload), INTERVAL_ARRAY, &interval, dimensions);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "dimension=[%d, %d, %d]", dimensions[0], dimensions[1], dimensions[2]);
+                       for (int i = 0; i < dimensions[0]; i++) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "interval[%d]=%d", i, interval[i]);
+                       }
+               }
+               // Result processing.
+               switch (client_response->result) {
+               case OC_STACK_OK:
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Discovery Success.");
+                       if (interval == NULL || interval[0] == 0 || dimensions[0] == 0) {
+                               THINGS_LOG_D(THINGS_INFO, TAG, "Invalid received remote interval or dimensions.");
+                               return OC_STACK_DELETE_TRANSACTION;
+                       }
+
+                       if (set_interval(ping, interval, dimensions[0], PING_ST_DISCOVERY) == true) {
+                               ping->continue_thread = true;
+                       }
+                       break;
+               case OC_STACK_TIMEOUT:
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Occurred Time-Out Event.");
+                       set_mask(ping, PING_ST_TIMEOUT);
+                       break;
+               default:
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+                       break;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_INFO, TAG, "discover_ping_resource_handler received Null client_response");
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (NULL != interval) {
+               things_free(interval);
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult ping_request_handler(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       things_ping_s *ping = (things_ping_s *) ctx;
+
+       if (ctx == (void *)DEFAULT_CONTEXT_VALUE || ctx == NULL || ping->addr == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "content value is invalid.(ctx=0x%X)", ctx);
+               return OC_STACK_DELETE_TRANSACTION;
+       }
+
+       if (client_response) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "ctx=0x%X", ctx);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Device =============> Discovered @ %s:%d", client_response->devAddr.addr, client_response->devAddr.port);
+
+               if (strncmp(ping->addr, client_response->devAddr.addr, strlen(client_response->devAddr.addr)) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error]: Mismatching address.(ping->addr=%s, recvAddr=%s)", ping->addr, client_response->devAddr.addr);
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+               // Parsing payload.
+               if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+                       OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+                       while (val != NULL) {
+                               things_rep_payload_value_print(val);
+                               val = val->next;
+                       }
+               }
+               // Result processing.
+               switch (client_response->result) {
+               case OC_STACK_OK:
+                       THINGS_LOG_D(THINGS_INFO, TAG, "common-ping request Success.");
+                       if (get_mask(ping, PING_ST_REQUEST) == true && get_mask(ping, PING_ST_TIMEOUT) == false) {
+                               unset_mask(ping, PING_ST_REQUEST);
+                       }
+                       break;
+               case OC_STACK_TIMEOUT:
+                       THINGS_LOG_D(THINGS_WARNING, TAG, "Occurred Time-Out Event.");
+                       set_mask(ping, PING_ST_TIMEOUT);
+                       break;
+               default:
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Not Support StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+                       break;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_WARNING, TAG, "ping_request_handler received Null client_response");
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult ping_update_request_handler(void *ctx, OCDoHandle handle, OCClientResponse *client_response)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int64_t *interval = NULL;
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
+       things_ping_s *ping = (things_ping_s *) ctx;
+       (void *)handle;
+
+       if (ctx == (void *)DEFAULT_CONTEXT_VALUE || ctx == NULL || ping->addr == NULL) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "content value is invalid.(ctx=0x%X)", ctx);
+               return OC_STACK_DELETE_TRANSACTION;
+       }
+
+       if (client_response) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "ctx=0x%X", ctx);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Device =============> Discovered @ %s:%d", client_response->devAddr.addr, client_response->devAddr.port);
+
+               if (strncmp(ping->addr, client_response->devAddr.addr, strlen(client_response->devAddr.addr)) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error]: Mismatching address.(ping->addr=%s, recvAddr=%s)", ping->addr, client_response->devAddr.addr);
+                       return OC_STACK_DELETE_TRANSACTION;
+               }
+               // Parsing payload.
+               if (client_response->payload != NULL && client_response->payload->type == PAYLOAD_TYPE_REPRESENTATION) {
+                       OCRepPayloadValue *val = ((OCRepPayload *) client_response->payload)->values;
+                       while (val != NULL) {
+                               things_rep_payload_value_print(val);
+                               val = val->next;
+                       }
+
+                       OCRepPayloadGetIntArray(((const OCRepPayload *)client_response->payload), INTERVAL_ARRAY, &interval, dimensions);
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "dimension=[%d, %d, %d]", dimensions[0], dimensions[1], dimensions[2]);
+                       for (int i = 0; i < dimensions[0]; i++) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "interval[%d]=%d", i, interval[i]);
+                       }
+               }
+               // Result processing.
+               switch (client_response->result) {
+               case OC_STACK_RESOURCE_CHANGED:
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "update-Ping request Success.");
+                       if (set_interval(ping, interval, dimensions[0], PING_ST_INTUPDATE) == true) {
+                               THINGS_LOG_D(THINGS_DEBUG, TAG, "Success Apply Interval.");
+                       }
+                       break;
+               case OC_STACK_TIMEOUT:
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Occurred Time-Out Event.");
+                       set_mask(ping, PING_ST_TIMEOUT);
+                       break;
+               default:
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Not Support StackResult: %s(%d)", get_result(client_response->result), client_response->result);
+                       break;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_INFO, TAG, "ping_update_request_handler received Null client_response");
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (NULL != interval) {
+               OICFree(interval);
+       }
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return OC_STACK_DELETE_TRANSACTION;
+}
+
+/***************************************************************************************
+ *
+ * Interval Function Definition Collection.
+ *
+ ***************************************************************************************/
+static things_ping_s *create_things_ping_s(const char *remoteAddr, const uint16_t port)
+{
+       things_ping_s *ping = NULL;
+
+       if (remoteAddr == NULL || strlen(remoteAddr) == 0) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "remote addr is NULL.");
+               return NULL;
+       }
+
+       ping = (things_ping_s *) things_malloc(sizeof(things_ping_s));
+       if (ping == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.");
+               return NULL;
+       }
+
+       ping->addr = strdup(remoteAddr);
+       ping->port = port;
+       ping->continue_thread = false;
+       pthread_mutex_init(&ping->mutex_int, NULL);
+       pthread_mutex_init(&ping->mutex_state, NULL);
+       pthread_mutex_init(&ping->mutex_thread, NULL);
+
+       pthread_mutex_lock(&ping->mutex_thread);
+       ping->handle_thread = 0;
+       pthread_mutex_unlock(&ping->mutex_thread);
+
+       set_def_interval(ping);
+
+       set_mask(ping, PING_ST_INIT);
+       return ping;
+}
+
+static void terminate_things_ping_s(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       if (ping == NULL) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "ping is NULL.");
+               return;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "ping thread destroy check.");
+       if (get_mask(ping, PING_ST_TCPCONNECT) == false && get_mask(ping, PING_ST_STARTTHREAD) == true) {       // need to destroy ping-thread.
+               things_ping_destroy_thread(ping);
+       }
+
+       set_mask(ping, PING_ST_INIT);
+
+       pthread_mutex_destroy(&ping->mutex_int);
+       pthread_mutex_destroy(&ping->mutex_state);
+       pthread_mutex_destroy(&ping->mutex_thread);
+
+       if (ping->addr) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "ping->addr memory free.");
+               things_free(ping->addr);
+               ping->addr = NULL;
+       }
+
+       things_free(ping);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+}
+
+//static int is_state_key_equal(things_ping_s *ping, const ping_state_e value)
+//{
+//  int res = 0;
+//  if (ping == NULL || ping->addr == NULL) {
+//      THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(ping=0x%X, targetIP=%s)", ping);
+//      return res;
+//  }
+//
+//  if (get_mask(ping, value) == true) {
+//      THINGS_LOG_D(THINGS_DEBUG, TAG, "Found ping-struct(%s) for State(%d)", ping->addr, value);
+//      res = 1;
+//  }
+//
+//  return res;
+//}
+
+static int is_ip_key_equal(things_ping_s *ping, const char *targetIP)
+{
+       int res = 0;
+       if (ping == NULL || ping->addr == NULL || targetIP == NULL || strlen(targetIP) == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(ping=0x%X, targetIP=%s)", ping, targetIP);
+               return res;
+       }
+
+       if (strncmp(ping->addr, targetIP, strlen(targetIP)) == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Found ping-struct(%s) for targetIP(%s)", ping->addr, targetIP);
+               res = 1;
+       }
+
+       return res;
+}
+
+static void check_ping_thread(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       if (ping == NULL || ping->addr == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(ping=0x%X)", ping);
+               return;
+       }
+
+       if (list == NULL) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "OICPing Module is not initialized.");
+               return;
+       }
+
+       if (get_mask(ping, PING_ST_TCPCONNECT) == true && get_mask(ping, PING_ST_STARTTHREAD) == false) {       // need to create ping-thread.
+               if (get_mask(ping, PING_ST_ISCLOUD) == false || (get_mask(ping, PING_ST_ISCLOUD) == true && get_mask(ping, PING_ST_SIGNIN) == true)) {  // create thread
+                       things_ping_create_thread(ping);
+               }
+       }
+
+       if (get_mask(ping, PING_ST_TCPCONNECT) == false && get_mask(ping, PING_ST_STARTTHREAD) == true) {       // need to destroy ping-thread.
+               things_ping_destroy_thread(ping);
+       }
+
+       if (get_mask(ping, PING_ST_ISCLOUD | PING_ST_SIGNIN | PING_ST_TCPCONNECT) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Not need things_ping_s, So, Terminate things_ping_s.(IP=%s)", ping->addr);
+               if ((ping = list->erase_by_key(list, is_ip_key_equal, ping->addr)) != NULL) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Erase node-element Success in List.");
+                       terminate_things_ping_s(ping);
+               }
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+}
+
+static void set_mask(things_ping_s *ping, ping_state_e state)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+       if (ping == NULL) {
+               return;
+       }
+
+       pthread_mutex_lock(&ping->mutex_state);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "(B) bit_mask_state = 0x%X", ping->bit_mask_state);
+       if (state != PING_ST_INIT) {
+               ping->bit_mask_state |= state;
+       } else {
+               ping->bit_mask_state = state;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "(A) bit_mask_state = 0x%X", ping->bit_mask_state);
+       pthread_mutex_unlock(&ping->mutex_state);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+}
+
+static bool get_mask(things_ping_s *ping, ping_state_e state)
+{
+       bool res = true;
+
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ping is NULL.");
+               return false;
+       }
+
+       pthread_mutex_lock(&ping->mutex_state);
+       res = (ping->bit_mask_state & state) != 0 ? true : false;
+       pthread_mutex_unlock(&ping->mutex_state);
+
+       return res;
+}
+
+static bool cas_mask(things_ping_s *ping, ping_state_e preState, bool preStateThen, ping_state_e postState)
+{
+       bool res = false;
+
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ping is NULL.");
+               return false;
+       }
+
+       pthread_mutex_lock(&ping->mutex_state);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "(B) bit_mask_state = 0x%X", ping->bit_mask_state);
+       bool state = (ping->bit_mask_state & preState) != 0 ? true : false;
+       if (state == preStateThen) {
+               if (postState != PING_ST_INIT) {
+                       ping->bit_mask_state |= postState;
+               } else {
+                       ping->bit_mask_state = postState;
+               }
+               res = true;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "(A) bit_mask_state = 0x%X", ping->bit_mask_state);
+       pthread_mutex_unlock(&ping->mutex_state);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "result = %d", res);
+       return res;
+}
+
+static void unset_mask(things_ping_s *ping, ping_state_e state)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+       if (ping == NULL) {
+               return;
+       }
+
+       pthread_mutex_lock(&ping->mutex_state);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "(B) bit_mask_state = 0x%X", ping->bit_mask_state);
+       if (state != PING_ST_INIT) {
+               ping->bit_mask_state &= (~state);
+       } else {
+               ping->bit_mask_state = state;
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "(A) bit_mask_state = 0x%X", ping->bit_mask_state);
+       pthread_mutex_unlock(&ping->mutex_state);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+}
+
+#ifdef OICPING_ENABLE
+static int find_resource_oic_ping(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int sleepTime = 1;                      // seconds
+       OCDoHandle g_req_handle = NULL;
+       OCCallbackData cb;
+       char *hostAddr = NULL;
+
+       cb.cb = discover_ping_resource_handler;
+       cb.cd = NULL;
+       cb.context = (void *)ping;
+
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ping struct is NULL.");
+               return sleepTime;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cb.context=0x%X", cb.context);
+
+       if ((hostAddr = make_host_addr(ping->addr, ping->port)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Memory Allocation is failed.");
+               return sleepTime;
+       }
+
+       while (cas_mask(ping, PING_ST_REQUEST | PING_ST_INTUPDATE | PING_ST_TIMEOUT, false, PING_ST_DISCOVERY) == false) {
+               sleep(1);                               // sleep 1 second
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Send OCFindKeepAliveResouce request to %s.", hostAddr);
+       if (OCFindKeepAliveResource(&g_req_handle, hostAddr, &cb) == OC_STACK_OK) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Waiting for /oic/ping Cloud-response.(%s)", ping->addr);
+               sleepTime = 5;
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "[Error]: Ping Resource Discovery-request is failed.");
+               unset_mask(ping, PING_ST_DISCOVERY);
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (hostAddr) {
+               things_free(hostAddr);
+       }
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.(sleepTime=%d)", sleepTime);
+       return sleepTime;
+}
+
+static int send_things_ping_request(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int sleepTime = 0;                      // minute
+       OCDoHandle g_req_handle = NULL;
+       OCStackResult result = OC_STACK_ERROR;
+       OCCallbackData cb;
+       int64_t interval = 0;
+       char *hostAddr = NULL;
+       OCRepPayload *payload = NULL;
+
+       cb.cb = ping_request_handler;
+       cb.cd = NULL;
+       cb.context = (void *)ping;
+
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ping struct is NULL.");
+               return sleepTime;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "cb.context=0x%X", cb.context);
+
+       if ((hostAddr = make_host_addr(ping->addr, ping->port)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "hostAddr Memory Allocation is failed.");
+               return sleepTime;
+       }
+
+       payload = OCRepPayloadCreate();
+       if (!payload) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "payload Memory Allocation is failed.");
+               /*! Added by st_things for memory Leak fix
+                */
+               if (hostAddr) {
+                       things_free(hostAddr);
+               }
+               return sleepTime;
+       }
+
+       while (cas_mask(ping, PING_ST_DISCOVERY | PING_ST_INTUPDATE | PING_ST_TIMEOUT, false, PING_ST_REQUEST) == false) {
+               sleep(1);                               // sleep 1 second
+       }
+
+       pthread_mutex_lock(&ping->mutex_int);
+       interval = ping->interval[ping->int_seq];
+       // period send request to Cloud for interval hand-shaking /oic/ping resource.
+       OCRepPayloadSetPropInt(payload, INTERVAL, interval);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "interval = %lld", interval);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Send OCSendKeepAliveRequest request to %s.", hostAddr);
+       if ((result = OCSendKeepAliveRequest(&g_req_handle, hostAddr, payload, &cb)) == OC_STACK_OK)
+//    if( (result= SendKeepAliveRequest(hostAddr, interval, &cb)) == OC_STACK_OK )
+       {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Sending Success about common-Ping request.");
+               do {
+                       ping->int_seq = (ping->int_seq + 1) % MAX_INTERVAL_EA;
+               } while (ping->interval[ping->int_seq] == 0);
+
+               sleepTime = interval;
+       }
+       unset_mask(ping, PING_ST_INTUPDATED);
+       pthread_mutex_unlock(&ping->mutex_int);
+
+       if (result != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "[Error]: Sending about common-Ping request is failed.");
+               unset_mask(ping, PING_ST_REQUEST);
+               OCRepPayloadDestroy(payload);
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (hostAddr) {
+               things_free(hostAddr);
+       }
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return sleepTime;
+}
+
+static bool set_interval_send_update(things_ping_s *ping, int64_t *intervals, int intEA)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+//    int i = 0;
+       bool res = false;
+       OCStackResult result = OC_STACK_ERROR;
+       OCCallbackData cb;
+       char *hostAddr = NULL;
+
+       cb.cb = ping_update_request_handler;
+       cb.cd = NULL;
+       cb.context = (void *)ping;
+
+       if (ping == NULL || intervals == NULL || intEA == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid arguments.(ping=%0x%X, intervals=0x%X, intEA=%d)", ping, intervals, intEA);
+               return false;
+       }
+
+       if (get_mask(ping, PING_ST_ISCLOUD) == false) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Interval Update & Sending update-Ping request is Support only for Cloud.");
+               return false;
+       }
+
+       if (intEA > MAX_INTERVAL_EA) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "intEA is over %d. So, fix to %d", MAX_INTERVAL_EA, MAX_INTERVAL_EA);
+               intEA = MAX_INTERVAL_EA;
+       }
+
+       if (get_mask(ping, PING_ST_STARTTHREAD) == false || ping->continue_thread == false) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Ping-Thread is not ready.");
+               return false;
+       }
+
+       if ((hostAddr = make_host_addr(ping->addr, ping->port)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Memory Allocation is failed.");
+               return false;
+       }
+
+       while (cas_mask(ping, PING_ST_DISCOVERY | PING_ST_REQUEST | PING_ST_TIMEOUT, false, PING_ST_INTUPDATE) == false) {
+               sleep(1);                               // sleep 1 second
+       }
+
+//    pthread_mutex_lock( &ping->mutex_int );
+       result = send_keep_alive_update_request(hostAddr, intervals, intEA, &cb);
+//    if( (result = send_keep_alive_update_request(host, intervals, intEA, &cb)) == OC_STACK_OK )     // send interval-update request to Cloud. & set State.
+//    {
+//        memset(ping->interval, 0, sizeof(int64_t)*MAX_INTERVAL_EA);
+//        for(i=0; i < intEA; i++)
+//        {
+//            ping->interval[i] = intervals[i];
+//        }
+//        ping->int_seq = 0;
+//        res = true;
+//    }
+//    pthread_mutex_unlock( &ping->mutex_int );
+
+       if (result != OC_STACK_OK) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "[Error]: Sending about update-Ping request is failed.");
+               unset_mask(ping, PING_ST_INTUPDATE);
+       } else {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Success Sending update-Ping request.");
+               res = true;
+       }
+       /*! Added by st_things for memory Leak fix
+        */
+       if (hostAddr) {
+               things_free(hostAddr);
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return res;
+}
+#else
+static int find_resource_oic_ping(things_ping_s *ping)
+{
+       return 1;
+}
+
+static int send_things_ping_request(things_ping_s *ping)
+{
+       return 1;
+}
+
+static bool set_interval_send_update(things_ping_s *ping, int64_t *intervals, int intEA)
+{
+       return true;
+}
+#endif
+
+static bool set_interval(things_ping_s *ping, int64_t *intervals, int intEA, ping_state_e confirmState)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int i = 0;
+       bool res = false;
+
+       if (ping == NULL || intervals == NULL || intEA == 0) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Invalid arguments.(ping=%0x%X, intervals=0x%X, intEA=%d)", ping, intervals, intEA);
+               return false;
+       }
+
+       if (intEA > MAX_INTERVAL_EA) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "intEA is over %d. So, fix to %d", MAX_INTERVAL_EA, MAX_INTERVAL_EA);
+               intEA = MAX_INTERVAL_EA;
+       }
+
+       if (confirmState == PING_ST_INIT) {
+               confirmState = PING_ALL_FLAG;
+       }
+
+       pthread_mutex_lock(&ping->mutex_int);
+       if (get_mask(ping, confirmState) == true && get_mask(ping, PING_ST_TIMEOUT) == false) {
+               memset(ping->interval, 0, sizeof(int64_t) * MAX_INTERVAL_EA);
+               for (i = 0; i < intEA; i++) {
+                       ping->interval[i] = intervals[i];
+               }
+               ping->int_seq = 0;
+               res = true;
+
+               if (confirmState != PING_ALL_FLAG) {
+                       unset_mask(ping, confirmState);
+               }
+
+               if (confirmState == PING_ST_INTUPDATE) {
+                       set_mask(ping, PING_ST_INTUPDATED);
+               }
+       }
+       pthread_mutex_unlock(&ping->mutex_int);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return res;
+}
+
+static bool set_def_interval(things_ping_s *ping)
+{
+       if (ping == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "ping is NULL.");
+               return false;
+       }
+
+       pthread_mutex_lock(&ping->mutex_int);
+       memset(ping->interval, 0, sizeof(int64_t) * MAX_INTERVAL_EA);
+       ping->interval[0] = (int64_t) 1;
+       ping->interval[1] = (int64_t) 2;
+       ping->interval[2] = (int64_t) 4;
+       ping->interval[3] = (int64_t) 8;
+       ping->int_seq = 0;
+       pthread_mutex_unlock(&ping->mutex_int);
+
+       return true;
+}
+
+static bool things_ping_create_thread(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       bool res = false;
+
+       if (ping == NULL || ping->addr == NULL || ping->port == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(ping=0x%X)", ping);
+               if (ping) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(addr=%s, port=%d)", ping->addr, ping->port);
+               }
+               return res;
+       }
+
+       pthread_mutex_lock(&ping->mutex_thread);
+       if (ping->handle_thread == 0) {
+#ifdef __ST_THINGS_RTOS__
+               if (pthread_create_rtos(&ping->handle_thread, NULL, (pthread_func_type) thd_ping_loop, ping, THINGS_STACK_PING_THREAD) != 0)
+#else
+               if (things_thread_create(&ping->handle_thread, NULL, (pthread_func_type) thd_ping_loop, ping) != 0)
+#endif
+               {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Create thd_ping_loop thread is failed.");
+                       ping->handle_thread = 0;
+                       goto GOTO_OUT;
+               }
+
+               set_mask(ping, PING_ST_STARTTHREAD);
+               res = true;
+       }
+GOTO_OUT:
+       pthread_mutex_unlock(&ping->mutex_thread);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.(result=%d)", res);
+       return res;
+}
+
+static bool things_ping_destroy_thread(things_ping_s *ping)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       bool res = false;
+
+       if (ping == NULL || ping->addr == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.(ping=0x%X)", ping);
+               return res;
+       }
+
+       pthread_mutex_lock(&ping->mutex_thread);
+       if (ping->handle_thread) {
+#ifdef __ST_THINGS_RTOS__
+               ping->continue_thread = false;
+               sleep(2);                               /* wait till thread exit */
+               pthread_detach(ping->handle_thread);
+#else                                                  /* there is problem in artik during thread_cancel hence avoiding it */
+               pthread_cancel(ping->handle_thread);
+               pthread_detach(ping->handle_thread);
+#endif
+               ping->handle_thread = 0;
+               ping->continue_thread = false;
+               set_def_interval(ping);
+
+               unset_mask(ping, PING_ST_STARTTHREAD | PING_ST_DISCOVERY | PING_ST_REQUEST | PING_ST_INTUPDATE | PING_ST_TIMEOUT);
+               res = true;
+       }
+       pthread_mutex_unlock(&ping->mutex_thread);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.(result=%d)", res);
+       return res;
+}
+
+static void things_rep_payload_value_print(OCRepPayloadValue *value)
+{
+       switch (value->type) {
+       case OCREP_PROP_INT:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %lld, int", value->name, value->i);
+               break;
+       case OCREP_PROP_DOUBLE:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %f, double", value->name, value->d);
+               break;
+       case OCREP_PROP_STRING:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %s, string", value->name, value->str);
+               break;
+       case OCREP_PROP_BOOL:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Key: %s, Value: %d, bool", value->name, value->b);
+               break;
+       case OCREP_PROP_BYTE_STRING:
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(binary) size : %d", value->name, value->ocByteStr.len);
+               //OCPrintByteValue( value->ocByteStr.bytes, value->ocByteStr.len );
+               break;
+       case OCREP_PROP_OBJECT:
+               // Note: Only prints the URI (if available), to print further, you'll
+               // need to dig into the object better!
+               THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(OCRep):%s", value->name, value->obj->uri);
+               break;
+       case OCREP_PROP_ARRAY:
+               switch (value->arr.type) {
+               case OCREP_PROP_INT:
+                       THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(int array):%zu x %zu x %zu", value->name, value->arr.dimensions[0], value->arr.dimensions[1], value->arr.dimensions[2]);
+                       for (size_t iter = 0; iter < value->arr.dimensions[0]; iter++) {
+                               THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: \t(int):%d", value->arr.iArray[iter]);
+                       }
+                       break;
+               case OCREP_PROP_DOUBLE:
+                       THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(double array):%zu x %zu x %zu", value->name, value->arr.dimensions[0], value->arr.dimensions[1], value->arr.dimensions[2]);
+                       for (size_t iter = 0; iter < value->arr.dimensions[0]; iter++) {
+                               THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: \t(double):%f", value->arr.dArray[iter]);
+                       }
+                       break;
+               case OCREP_PROP_BOOL:
+                       THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(bool array):%zu x %zu x %zu", value->name, value->arr.dimensions[0], value->arr.dimensions[1], value->arr.dimensions[2]);
+                       for (size_t iter = 0; iter < value->arr.dimensions[0]; iter++) {
+                               THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: \t(bool):%s", value->arr.bArray[iter] ? "true" : "false");
+                       }
+                       break;
+               case OCREP_PROP_STRING:
+                       THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(string array):%zu x %zu x %zu", value->name, value->arr.dimensions[0], value->arr.dimensions[1], value->arr.dimensions[2]);
+                       for (size_t iter = 0; iter < value->arr.dimensions[0]; iter++) {
+                               THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: \t(string):%s", value->arr.strArray[iter]);
+                       }
+                       break;
+               case OCREP_PROP_BYTE_STRING:
+                       THINGS_LOG_V(THINGS_DEBUG, TAG, "Key: %s(byte array):%zu x %zu x %zu", value->name, value->arr.dimensions[0], value->arr.dimensions[1], value->arr.dimensions[2]);
+                       break;
+               default:
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Key: %s <-- Unknown/unsupported array type!", value->name);
+                       break;
+               }
+               break;
+       default:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Un supported val Type.(0x%d)", value->type);
+               break;
+       }
+}
+
+#include "cloud_manager.h"
+
+static char *make_host_addr(const char *ip, const uint16_t port)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       char *host = NULL;
+       int length = 0;
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "ip=%s, port=%d", ip, port);
+       if (ip == NULL || strlen(ip) == 0 || port == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Invalid arguments.");
+               return NULL;
+       }
+
+       length = strlen(ip) + 7 + strlen(DEFAULT_COAP_TCP_HOST);
+       if ((host = (char *)things_malloc(sizeof(char) * length)) == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "memory allocation is failed.");
+               return NULL;
+       }
+       // Update Cloud Address.
+       memset(host, 0, length);
+       if (snprintf(host, length, "%s%s:%d", DEFAULT_COAP_TCP_HOST, ip, port) >= length) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "[Error] host buffer is overflowed.");
+               things_free(host);
+               host = NULL;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "host = %s", host);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return host;
+}
+
+static OCStackResult send_keep_alive_update_request(const char *host, int64_t *intervals, int intEA, OCCallbackData *cb)
+{
+       OCDoHandle g_req_handle = NULL;
+       OCStackResult result = OC_STACK_ERROR;
+       char targetUri[MAX_URI_LENGTH * 2] = { 0, };
+       OCRepPayload *payload = NULL;
+       size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
+
+       if (host == NULL || strlen(host) == 0 || intervals == NULL || intEA == 0) {
+               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid event_data.(host=%s, intervals=0x%X, intEA=%d)", host, intervals, intEA);
+               result = OC_STACK_NO_MEMORY;
+               goto no_memory;
+       }
+
+       snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, KEEPALIVE_RESOURCE_URI);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "oicping Update Request to : %s", targetUri);
+
+       payload = OCRepPayloadCreate();
+       if (!payload) {
+               result = OC_STACK_NO_MEMORY;
+               goto no_memory;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "intEA=%d", intEA);
+       for (int i = 0; i < intEA; i++) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "intervals[%d]=%d", i, intervals[i]);
+       }
+
+       dimensions[0] = (size_t) intEA;
+       OCRepPayloadSetIntArray(payload, INTERVAL_ARRAY, intervals, dimensions);
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "key     : %s", INTERVAL_ARRAY);
+
+//#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
+//    CASelectCipherSuite(0x35, (1 << 4));
+//#endif
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Send OCSendKeepAliveRequest request to %s.", host);
+       result = OCSendKeepAliveRequest(&g_req_handle, host, payload, cb);
+//    result = OCDoResource(&g_req_handle, OC_REST_POST, targetUri,
+//                          NULL, (OCPayload *) payload, CT_ADAPTER_TCP,
+//                          OC_HIGH_QOS, cb, NULL, 0);
+
+       if (result != OC_STACK_OK) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "oicping Update Request Sending is failed.(URI: %s)", targetUri);
+               OCRepPayloadDestroy(payload);
+       }
+
+no_memory:
+       return result;
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_queue.c b/framework/src/st_things/things_stack/src/common/utils/things_queue.c
new file mode 100644 (file)
index 0000000..97b6c88
--- /dev/null
@@ -0,0 +1,122 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "things_queue.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+
+//#include "oicrequest.h"
+
+#define TAG "[things_queue]"
+
+/**
+ * Push an item into queue, if this is the first item,
+ * both queue->head and queue->tail will point to it,
+ * otherwise the oldtail->next and tail will point to it.
+ */
+void enQueue(queue_s *queue, void *item, int req)
+{
+
+       if (queue == NULL || item == NULL) {
+               return;
+       }
+
+       pthread_mutex_lock(&(queue->q_mutex));
+       // Create a new node
+       things_node_s *n = (things_node_s *) things_malloc(sizeof(things_node_s));
+       if (NULL == n) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, THINGS_MEMORY_ERROR);
+               return;
+       }
+       n->item = item;
+       n->req = req;
+       n->next = NULL;
+
+       if (queue->head == NULL) {      // no head
+               queue->head = n;
+       } else {
+               queue->tail->next = n;
+       }
+       queue->tail = n;
+       queue->size++;
+
+       pthread_mutex_unlock(&(queue->q_mutex));
+}
+
+/**
+ * Return and remove the first item.
+ */
+void *deQueue(queue_s *queue, int *req)
+{
+
+       if (queue == NULL || queue->head == NULL) {
+               return NULL;
+       }
+
+       pthread_mutex_lock(&(queue->q_mutex));
+
+       // get the first item
+       things_node_s *head = queue->head;
+
+       void *item = head->item;
+       *req = head->req;
+       // move head pointer to next node, decrease size
+       queue->head = head->next;
+       queue->size--;
+       // free the memory of original head
+       things_free(head);
+
+       pthread_mutex_unlock(&(queue->q_mutex));
+
+       return item;
+}
+
+/**
+ * Return but not remove the first item.
+ */
+void *peek(queue_s *queue, int *req)
+{
+
+       pthread_mutex_lock(&(queue->q_mutex));
+
+       things_node_s *head = queue->head;
+       *req = head->req;
+
+       pthread_mutex_unlock(&(queue->q_mutex));
+
+       return head->item;
+}
+
+/**
+ * Return but not remove the first item.
+ */
+int getLength(queue_s *queue)
+{
+
+       pthread_mutex_lock(&(queue->q_mutex));
+
+       int length = queue->size;
+
+       pthread_mutex_unlock(&(queue->q_mutex));
+
+       return length;
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_rtos_util.c b/framework/src/st_things/things_stack/src/common/utils/things_rtos_util.c
new file mode 100644 (file)
index 0000000..730632a
--- /dev/null
@@ -0,0 +1,103 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+
+#include <pthread.h>
+#include <sched.h>
+
+#include "things_rtos_util.h"
+
+#define TAG "[things_rtos_util]"
+
+static char thingsStackthreadName[THINGS_STACK_MAX_INDEX][40] = { {"THINGS_STACK_PING"},       /*THINGS_STACK_PING_THREAD */
+       {"THINGS_STACK_WAITHANDLER"},   /*THINGS_STACK_WAITHANDLER_THREAD */
+       {"THINGS_STACK_RESETLOOP"},             /*THINGS_STACK_RESETLOOP_THREAD */
+       {"THINGS_STACK_CICONN_INIT"},   /*THINGS_STACK_CICONNETION_INIT_THREAD */
+       {"THINGS_STACK_CICONN_WAIT"},   /*THINGS_STACK_CICONNETION_WAIT_THREAD */
+       {"THINGS_STACK_WIFIPROV_SET"},  /*THINGS_STACK_WIFI_PROV_SET_THREAD */
+       {"THINGS_STACK_CLOUD_REFRESH"}, /*THINGS_STACK_CLOUD_REFRESH_THREAD */
+       {"THINGS_STACK_MSG_HANDLING"},  /*THINGS_STACK_MESSAGE_HANDLING_THREAD */
+       {"THINGS_STACK_PRESENCE_NOTI"}, /*THINGS_STACK_PRESENCE_NOTI_THREAD */
+       {"THINGS_STACK_SERVEREXCE_LOOP"},       /*THINGS_STACK_SERVEREXCETUE_LOOP_THREAD */
+       {"THINGS_STACK_BASE_TIME_OUT"}, /*THINGS_STACK_BASE_TIME_OUT_THREAD */
+       {"THINGS_STACK_OICABORT"},
+       {"THINGS_STACK_MAX_INDEX"}              /*THINGS_STACK_MAX_INDEX */
+};
+
+/**
+ *
+ * @param ethreadName
+ * @param pstThread
+ * @return
+ */
+char *GetPthreadAttrDetails(things_stack_thread_name ethreadName, pthread_attr_t *pstThread)
+{
+       if (ethreadName >= THINGS_STACK_MAX_INDEX) {
+               ethreadName = THINGS_STACK_MAX_INDEX;
+       }
+
+       if (pstThread != NULL) {
+               pthread_attr_init(pstThread);
+               struct sched_param sparam;
+               pthread_attr_init(pstThread);
+               pthread_attr_setschedpolicy(pstThread, SCHED_RR);
+               sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY;
+               pthread_attr_setschedparam(pstThread, &sparam);
+
+               pthread_attr_setstacksize(pstThread, 8193);     /**Default Stack Size**/
+               switch (ethreadName) {
+               case THINGS_STACK_RESETLOOP_THREAD:
+               case THINGS_STACK_PING_THREAD:
+               case THINGS_STACK_CICONNETION_INIT_THREAD:
+               case THINGS_STACK_CLOUD_REFRESH_THREAD:
+               case THINGS_STACK_PRESENCE_NOTI_THREAD:
+               case THINGS_STACK_WAITHANDLER_THREAD:
+                       pthread_attr_setstacksize(pstThread, 4 * 1024);
+                       break;
+
+               case THINGS_STACK_CICONNETION_WAIT_THREAD:
+                       pthread_attr_setstacksize(pstThread, 6 * 1024);
+                       break;
+               case THINGS_STACK_SERVEREXCETUE_LOOP_THREAD:
+               case THINGS_STACK_MESSAGE_HANDLING_THREAD:
+                       pthread_attr_setstacksize(pstThread, 6 * 1024);
+                       /* its the main process thread for all request */
+                       break;
+
+               default:
+                       pthread_attr_setstacksize(pstThread, 8193);
+                       break;
+               }
+       }
+
+       return thingsStackthreadName[ethreadName];
+
+}
+
+int pthread_create_rtos(FAR pthread_t *thread, FAR const pthread_attr_t *attr, pthread_startroutine_t start_routine, pthread_addr_t arg, things_stack_thread_name eThreadname)
+{
+       pthread_attr_t stPtr;
+       char *pchTname = GetPthreadAttrDetails(eThreadname, &stPtr);
+       int ret = pthread_create(thread, &stPtr, start_routine, (void *)arg);
+       if (ret == 0) {
+               pthread_setname_np(*thread, pchTname);
+               pthread_detach(*thread);
+       }
+       return ret;
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_string_util.c b/framework/src/st_things/things_stack/src/common/utils/things_string_util.c
new file mode 100644 (file)
index 0000000..d792dae
--- /dev/null
@@ -0,0 +1,175 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <string.h>
+
+#include "things_string_util.h"
+#include "things_malloc.h"
+#include "things_logger.h"
+
+#define TAG "[things_string_util]"
+
+int compare_strings(const char *src, const char *dst)
+{
+       if ((NULL == src) || (NULL == dst)) {
+               return -1;
+       }
+
+       int srcLen = strlen(src);
+       int dstLen = strlen(dst);
+
+       if (srcLen != dstLen) {
+               return -1;
+       }
+
+       return strncmp(src, dst, dstLen);
+}
+
+int duplicate_string(const char *src, char **dst)
+{
+       if (NULL == src) {
+               return 0;
+       } else {
+               int len = strlen(src);
+               *dst = (char *)things_malloc(len + 1);
+               if (NULL == *dst) {
+                       printf("memory allocation failed!\n");
+                       return 0;
+               }
+
+               memset(*dst, 0, len + 1);
+               things_strncpy(*dst, src, len);
+       }
+       return 1;
+}
+
+// Memory Leakage Should be check
+void concat_string(char **target, char *attach)
+{
+       char buf[MAX_BUF_LEN] = { 0 };
+
+       if (attach == NULL) {
+               return;
+       }
+
+       if (*target != NULL) {
+               things_strncpy(buf, *target, strlen(*target) + 1);
+               things_free(*target);
+               *target = NULL;
+       }
+
+       if (MAX_BUF_LEN >= (strlen(buf) + strlen(attach))) {
+               strncat(buf, attach, MAX_BUF_LEN);
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Something went wrong");
+               return;
+       }
+
+       *target = (char *)things_malloc(strlen(buf) + 1);
+       if (NULL == *target) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, THINGS_MEMORY_ERROR);
+               return;
+       }
+       things_strncpy(*target, buf, strlen(buf) + 1);
+}
+
+int hex_string_to_int(const char *hex, int *num)
+{
+       return sscanf(hex, "%x", num);
+}
+
+int get_id_value_from_query(char idvalue[], char *inputQuery, int size)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Input query => %s", inputQuery);
+
+       char seperators[] = "?;#&";
+
+       if (NULL == inputQuery) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Input query is NULL");
+               return 0;
+       }
+
+       if (size > MAX_INPUT_QUERY_LEN) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Input size bigger than maximum query size(%d)", MAX_INPUT_QUERY_LEN);
+               return 0;
+       }
+
+       /*[Jaehong] (Need to consider trim to remove space in query) */
+       // Remove empty space
+       char queries[MAX_INPUT_QUERY_LEN + 1] = { 0, };
+       int index = 0;
+       for (int i = 0; i < strlen(inputQuery); i++) {
+               if (*(inputQuery + i) == ' ') {
+                       continue;
+               }
+               queries[index] = *(inputQuery + i);
+               index++;
+       }
+
+       // Get Query start with "id="
+       char *idQuery = strstr(queries, "id=");
+       if (NULL == idQuery) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "There is no \"id=\" in input query");
+               return 0;
+       }
+       // Seperate idQuery with seperators [?, ;, #]
+       for (int i = 0; i < strlen(idQuery); i++) {
+               if (*(idQuery + i) == '?' || *(idQuery + i) == ';' || *(idQuery + i) == '#' || *(idQuery + i) == '&') {
+                       strtok(idQuery, seperators);
+                       break;
+               }
+       }
+
+       // Get id data after "id=" and validation check.
+       for (int i = 3, k = 0; i < strlen(idQuery); i++) {
+               if (idQuery[i] >= '0' && idQuery[i] <= '9') {
+                       idvalue[k++] = idQuery[i];
+               } else {
+                       idvalue[0] = '\0';
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+char *things_strcat(char *dest, size_t destSize, const char *src)
+{
+       if (dest == NULL || src == NULL || destSize == 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "dest(0x%X) or src(0x%X) or dest_size=%d is NULL.", dest, src, destSize);
+               return NULL;
+       }
+
+       if (strlen(src) >= (destSize - strlen(dest))) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Source Size(%d) is over than Dest-FreeSize(%d).", strlen(src), destSize - strlen(dest) - 1);
+               return NULL;
+       }
+
+       return strncat(dest, src, strlen(src));
+}
+
+char *things_strncpy(char *destination, const char *source, size_t num)
+{
+       if (NULL == source) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Input String is NULL");
+               return NULL;
+       }
+
+       return strncpy(destination, source, num);
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_thread.c b/framework/src/st_things/things_stack/src/common/utils/things_thread.c
new file mode 100644 (file)
index 0000000..d34d6c7
--- /dev/null
@@ -0,0 +1,70 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <stdlib.h>
+
+#include "things_logger.h"
+#include "things_malloc.h"
+
+#include "things_thread.h"
+
+#define TAG "[things_thread]"
+
+int things_thread_create(pthread_t *__newthread, pthread_attr_t *__attr, void *(*__start_routine)(void *), void *__arg)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+       int ret = 0;
+#ifndef __ST_THINGS_RTOS__
+       int ret = -1;
+       pthread_attr_t attr;
+       pthread_attr_t *pAttr;
+
+       if (__newthread == NULL || __start_routine == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Input invalied.(mandatory var: __newthread=0x%X, __start_routine=0x%X", __newthread, __start_routine);
+               return ret;
+       }
+
+       pAttr = __attr;
+
+       if (__attr == NULL) {
+               if (pthread_attr_init(&attr) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "pthread_attr_init() is failed.");
+                       return ret;
+               }
+
+               if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "pthread_attr_setdetachstate() is failed.");
+                       return ret;
+               }
+
+               pAttr = &attr;
+       }
+
+       ret = pthread_create(__newthread, pAttr, __start_routine, __arg);
+
+       if (__attr == NULL) {
+               if (pthread_attr_destroy(&attr) != 0) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "pthread_attr_destroy() is failed.");
+               }
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+#endif
+       return ret;
+}
diff --git a/framework/src/st_things/things_stack/src/common/utils/things_wait_handler.c b/framework/src/st_things/things_stack/src/common/utils/things_wait_handler.c
new file mode 100644 (file)
index 0000000..8a16bdb
--- /dev/null
@@ -0,0 +1,248 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#include <stdbool.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "things_malloc.h"
+#include "things_logger.h"
+#include "things_wait_handler.h"
+
+#include "things_thread.h"
+#ifdef __ST_THINGS_RTOS__
+#include "things_rtos_util.h"
+#endif
+
+#define TAG "[waithandler]"
+
+#define MAX_RANDOM_NUM      2999
+
+#define MAX_SENDHANDLES     25
+
+typedef void *(*PthreadFunc)(void *param);
+
+typedef struct TimeOutManager_s {
+       timeout_s timeout;
+       pthread_t gthreadId;
+       OCDoHandle handleVal;
+       check_time_out_call_func funcName;
+} TimeOutManager_s;
+
+static int iSendHandle = 0;
+static OCDoHandle gSendHandle[MAX_SENDHANDLES] = { NULL, };
+
+static pthread_mutex_t gREQmutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gTimeOutmutex = PTHREAD_MUTEX_INITIALIZER;
+
+OCDoHandle get_request_handle(void)
+{
+       int i = 0;
+       OCDoHandle result = NULL;
+
+       pthread_mutex_lock(&gREQmutex);
+       for (i = iSendHandle - 1; i >= 0; i--) {        // latest gSendHandle Value return.
+               if (gSendHandle[i] != NULL) {
+                       result = gSendHandle[i];
+                       break;
+               }
+       }
+       pthread_mutex_unlock(&gREQmutex);
+
+       return result;
+}
+
+int cas_request_handle(OCDoHandle EqualVal, OCDoHandle writeHandleVal)
+{
+       int i = 0;
+       int res = 0;
+
+       pthread_mutex_lock(&gREQmutex);
+       for (i = iSendHandle - 1; i >= 0; i--) {        // latest gSendHandle Value check.
+               if (gSendHandle[i] == EqualVal) {
+                       THINGS_LOG_D(THINGS_DEBUG, TAG, "Found request handler.(%d th : 0x%X)", i, gSendHandle[i]);
+                       gSendHandle[i] = writeHandleVal;
+                       res = 1;
+                       break;
+               }
+       }
+       pthread_mutex_unlock(&gREQmutex);
+
+       return res;
+}
+
+bool is_empty_request_handle(void)
+{
+       bool isEmpty = false;
+
+       pthread_mutex_lock(&gREQmutex);
+       if (iSendHandle < MAX_SENDHANDLES) {
+               isEmpty = true;
+       }
+       pthread_mutex_unlock(&gREQmutex);
+
+       return isEmpty;
+}
+
+OCDoHandle add_request_handle(OCDoHandle HandleVal)
+{
+       OCDoHandle result = NULL;
+
+       pthread_mutex_lock(&gREQmutex);
+       if (iSendHandle >= MAX_SENDHANDLES) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "gSendHandle array is Full.");
+       } else {
+               gSendHandle[iSendHandle] = HandleVal;
+               result = gSendHandle[iSendHandle];
+               iSendHandle++;
+       }
+       pthread_mutex_unlock(&gREQmutex);
+
+       return result;
+}
+
+void del_all_request_handle(void)
+{
+       int i = 0;
+
+       pthread_mutex_lock(&gREQmutex);
+       for (i = 0; i < iSendHandle; i++) {
+               gSendHandle[i] = NULL;
+       }
+       iSendHandle = 0;
+       pthread_mutex_unlock(&gREQmutex);
+}
+
+/************************************************************
+ *
+ * Thread for Time-Out Process for Handle base
+ *
+ * Time-Out : DEFAULT_TIMEOUT sec.
+ *
+ ************************************************************/
+static void *HandleBaseTimeOutLoop(TimeOutManager_s *pTimeOutManager)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter.");
+
+       static int cntTimeOutThread = 0;
+
+       pthread_mutex_lock(&gTimeOutmutex);
+       cntTimeOutThread++;
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[HD Start] Count of Time-Out thread is %d.", cntTimeOutThread);
+       pthread_mutex_unlock(&gTimeOutmutex);
+
+       sleep(1);
+
+       if (pTimeOutManager == NULL || pTimeOutManager->gthreadId < 0 || pTimeOutManager->funcName == NULL || pTimeOutManager->timeout.cur_counter <= 0) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Parameter is invalid.");
+               if (pTimeOutManager) {
+                       things_free(pTimeOutManager);
+               }
+
+               return 0;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "handleVal=0x%X, timeCounter=%d, funcName=0x%X", pTimeOutManager->handleVal, pTimeOutManager->timeout.cur_counter, pTimeOutManager->funcName);
+
+       while (get_request_handle() != NULL && pTimeOutManager->handleVal == get_request_handle()) {    // get_request_handle() != NULL will guarantee for Connecting to AP.
+               sleep(1);
+
+               if (--pTimeOutManager->timeout.cur_counter == 0) {
+                       if (cas_request_handle(pTimeOutManager->handleVal, NULL) == 1) {        // cas_request_handle(handle, NULL) == 1 will guarantee that AP is connected and handle is latest important request.
+                               pTimeOutManager->funcName(&pTimeOutManager->timeout);
+                       }
+                       pTimeOutManager->handleVal = (void *)(-1);
+               }
+       }
+
+       things_free(pTimeOutManager);
+       pthread_mutex_lock(&gTimeOutmutex);
+       cntTimeOutThread--;
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "[HD End] Count of Time-Out thread is %d.", cntTimeOutThread);
+       pthread_mutex_unlock(&gTimeOutmutex);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Exit.");
+
+       return 0;
+}
+
+long long next_time_out(const long long ori_num, const long long cur_num)
+{
+       long long x = 0;
+       long long nextT = -1;
+
+       if (ori_num <= 0 || cur_num <= 0) {
+               THINGS_LOG_V(THINGS_INFO, TAG, "Not Enabled PDF re-try.");
+               return nextT;
+       }
+
+       while (cur_num >= nextT) {
+               x = (long long)rand() * (long long)(MAX_RANDOM_NUM + 1);
+// pkes        x = x / (long long)((unsigned int)MAX_RAND+(unsigned int)1);
+               x = x / (long long)((unsigned int)RAND_MAX + (unsigned int)1);
+               x = x + 500;
+
+               if (x < 500 || x > MAX_RANDOM_NUM + 500) {
+                       THINGS_LOG_V(THINGS_INFO, TAG, "X value invalid.");
+                       break;
+               }
+
+               nextT = ((long long)ori_num * ((long long)10000000000000 + x * x * x * x)) / (long long)10000000000000;
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Gaussian next Time-Out Number: nextT = %lld", nextT);
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "next Time-Out: %lld", nextT);
+       return nextT;
+}
+
+unsigned long int create_time_out_process(OCDoHandle hadler, check_time_out_call_func CallFunc, timeout_s *timeOut)
+{
+       TimeOutManager_s *pTimeOutManager = NULL;
+
+       if ((pTimeOutManager = (TimeOutManager_s *) things_malloc(sizeof(TimeOutManager_s))) == NULL || CallFunc == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Memory allocation is failed.");
+               return 0;
+       }
+
+       pTimeOutManager->gthreadId = NULL;
+       pTimeOutManager->handleVal = hadler;
+       pTimeOutManager->funcName = CallFunc;
+       if (timeOut == NULL) {
+               pTimeOutManager->timeout.cur_counter = DEFAULT_TIMEOUT; // default second.
+               pTimeOutManager->timeout.ori_num = DEFAULT_TIMEOUT;     // default second.
+               pTimeOutManager->timeout.cur_num = DEFAULT_TIMEOUT;     // default second.
+       } else {
+               pTimeOutManager->timeout.cur_counter = timeOut->cur_counter;
+               pTimeOutManager->timeout.ori_num = timeOut->ori_num;
+               pTimeOutManager->timeout.cur_num = timeOut->cur_num;
+       }
+
+#ifdef __ST_THINGS_RTOS__
+       if (pthread_create_rtos(&pTimeOutManager->gthreadId, NULL, (PthreadFunc) HandleBaseTimeOutLoop, (void *)pTimeOutManager, THINGS_STACK_WAITHANDLER_THREAD) != 0)
+#else
+       if (things_thread_create(&pTimeOutManager->gthreadId, NULL, (PthreadFunc) HandleBaseTimeOutLoop, (void *)pTimeOutManager) != 0)
+#endif
+       {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Create thread is failed.");
+               things_free(pTimeOutManager);
+               return 0;
+       }
+
+       return pTimeOutManager->gthreadId;
+}
diff --git a/framework/src/st_things/things_stack/src/stack/Make.defs b/framework/src/st_things/things_stack/src/stack/Make.defs
new file mode 100644 (file)
index 0000000..b6eae96
--- /dev/null
@@ -0,0 +1,22 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += things_rtos_apis.c things_stack.c
+
+DEPPATH += --dep-path src/st_things/things_stack/src/stack
+VPATH += :src/st_things/things_stack/src/stack
\ No newline at end of file
diff --git a/framework/src/st_things/things_stack/src/stack/things_rtos_apis.c b/framework/src/st_things/things_stack/src/stack/things_rtos_apis.c
new file mode 100644 (file)
index 0000000..5dbba59
--- /dev/null
@@ -0,0 +1,38 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 <pthread.h>
+
+#include "things_api.h"
+#include "things_def.h"
+#include "things_logger.h"
+#include "things_req_handler.h"
+#include "octypes.h"
+#include "ocpayload.h"
+#include "things_malloc.h"
+#include "oic_string.h"
+#include "things_server_builder.h"
+
+#ifdef __ST_THINGS_RTOS__
+
+#define TAG "[thingsstacknew]"
+
+extern things_request_handler_s *g_req_handler;
+extern things_server_builder_s *g_server_builder;
+
+#endif
diff --git a/framework/src/st_things/things_stack/src/stack/things_stack.c b/framework/src/st_things/things_stack/src/stack/things_stack.c
new file mode 100644 (file)
index 0000000..70d1c98
--- /dev/null
@@ -0,0 +1,1086 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+#define _POSIX_C_SOURCE 200809L
+#define _BSD_SOURCE                            // for the usleep
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include "ocpayload.h"
+#include "octypes.h"
+#include "ocstack.h"
+#include "things_api.h"
+#include "things_types.h"
+#include "things_def.h"
+#include "things_common.h"
+#include "things_logger.h"
+#include "things_malloc.h"
+#include "things_string_util.h"
+
+#include "things_resource.h"
+#include "things_server_builder.h"
+#include "things_security_manager.h"
+#include "things_req_handler.h"
+
+#include "things_data_manager.h"
+
+#include "../common/utils/inc/things_network.h"
+#include "easysetup_manager.h"
+#include "cloud_manager.h"
+#include "cloud_evtpend.h"
+
+#include <wifi_manager/wifi_manager.h>
+
+#include "things_thread.h"
+#ifdef __ST_THINGS_RTOS__
+#include "things_rtos_util.h"
+#endif
+
+#define TAG "[things_stack]"
+
+typedef void *(*pthread_func_type)(void *);
+
+volatile static int g_quit_flag = 0;
+volatile static int is_things_module_inited = 0;
+
+typedef struct s_abort_s {
+       pthread_t *h_thread;
+       things_es_enrollee_abort_e level;
+} s_abort_s;
+
+typedef struct reset_args_s {
+       things_resource_s *remote_owner;
+       things_es_enrollee_reset_e resetType;
+} reset_args_s;
+
+things_abort_easysetup_func_type g_abort_easysetup = NULL;
+
+things_server_builder_s *g_server_builder = NULL;
+things_request_handler_s *g_req_handler = NULL;
+
+things_reset_confirm_func_type g_confirm_reset_start = NULL;
+things_sec_otm_state_func_type g_otm_event_handler = NULL;
+
+static pthread_mutex_t g_app_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t g_things_stop_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t g_wifi_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t g_wifi_cond;
+static wifi_manager_scan_info_s *g_wifi_scan_info;
+static int g_wifi_scan_count;
+
+#define WIFI_SCAN_SIGNAL                       \
+do {                                                                           \
+       pthread_mutex_lock(&g_wifi_mutex);              \
+       pthread_cond_signal(&g_wifi_cond);              \
+       pthread_mutex_unlock(&g_wifi_mutex);            \
+} while (0)
+
+#define WIFI_SCAN_WAIT                                         \
+do {                                                                           \
+       pthread_mutex_lock(&g_wifi_mutex);                      \
+       pthread_cond_wait(&g_wifi_cond, &g_wifi_mutex); \
+       pthread_mutex_unlock(&g_wifi_mutex);                    \
+} while (0)
+
+static bool b_reset_continue_flag = false;
+static bool b_thread_things_reset = false;
+static pthread_t h_thread_things_reset = NULL;
+static pthread_t h_thread_things_wifi_join = NULL;
+static pthread_mutex_t m_thread_oic_reset = PTHREAD_MUTEX_INITIALIZER;
+static volatile rst_state_e m_reset_bit_mask = RST_COMPLETE;
+
+static void *t_things_reset_loop(reset_args_s *args);
+static void *t_things_abort_loop(s_abort_s *contents);
+
+const char *things_get_sw_version()
+{
+       return OIC_STACK_FIRMWARE_VERSION;
+}
+
+const char *things_get_device_id_string()
+{
+       return OCGetServerInstanceIDString();
+}
+
+int things_set_device_name(int dev_num, char *name)
+{
+       int res = 0;
+       if (!is_things_module_inited) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Stack not initialized");
+       } else {
+               if (dev_num > 0) {
+                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Dev Num %d Not Supported Yet", dev_num);
+               } else {
+                       if (NULL != name && strlen(name) > 0) {
+                               OCStackResult result = OCSetPropertyValue(PAYLOAD_TYPE_DEVICE,
+                                                                          OC_RSRVD_DEVICE_NAME,
+                                                                          name);
+                               if (result == OC_STACK_OK) {
+                                       res = 1;
+                               } else {
+                                       THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Set Device Name Failed : %d ", result);
+                               }
+                       } else {
+                               THINGS_LOG_D_ERROR(THINGS_ERROR, TAG, "Invalid Device Name : %s ", name);
+                       }
+               }
+       }
+
+       return res;
+}
+
+// This logic will be refactored later to reflact whole easy-setup states..
+int things_get_easysetup_state(void)
+{
+       bool isOwned = false;
+       // 1. check the owned state
+       if (OC_STACK_OK != OCGetDeviceOwnedState(&isOwned)) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Failed to get device owned state, Informing as UNOWNED~!!!!");
+               isOwned = false;
+       }
+       // 2. check the resource publish state if necessary..
+
+       // 3. anything else to check???
+
+       return (isOwned == true);
+}
+
+int things_register_easysetup_state_func(things_get_easysetup_state_func_type func)
+{
+       int res = 0;
+
+       if (func != NULL) {
+               es_register_notify_easysetup_state((void *)func);
+               res = 1;
+       }
+
+       return res;
+}
+
+static void *__attribute__((optimize("O0"))) t_things_wifi_join_loop(void *args)
+{
+       wifi_manager_info_s wifi_info;
+       wifi_manager_get_info(&wifi_info);
+
+       char cur_device_ip_address[18 + 1];
+       wifi_net_ip4_addr_to_ip4_str(wifi_info.ip4_address, cur_device_ip_address);
+
+       things_wifi_changed_call_func(1, wifi_info.ssid, cur_device_ip_address);
+}
+
+void things_wifi_sta_connected(void)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "T%d --> %s", getpid(), __FUNCTION__);
+
+       pthread_create_rtos(&h_thread_things_wifi_join, NULL, (pthread_func_type) t_things_wifi_join_loop, NULL, THINGS_STACK_WIFI_JOIN);
+       pthread_detach(h_thread_things_wifi_join);
+}
+
+void things_wifi_sta_disconnected(void)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "T%d --> %s", getpid(), __FUNCTION__);
+}
+
+void things_wifi_soft_ap_sta_joined(void)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "T%d --> %s", getpid(), __FUNCTION__);
+
+}
+
+void things_wifi_soft_ap_sta_left(void)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "T%d --> %s", getpid(), __FUNCTION__);
+}
+
+void things_wifi_scan_done(wifi_manager_scan_info_s **scan_result, int res)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "T%d --> %s", getpid(), __FUNCTION__);
+       /* Make sure you copy the scan results onto a local data structure.
+        * It will be deleted soon eventually as you exit this function.
+        */
+//TO DO
+}
+
+static const wifi_manager_cb_s wifi_callbacks = {
+       things_wifi_sta_connected,
+       things_wifi_sta_disconnected,
+       things_wifi_soft_ap_sta_joined,
+       things_wifi_soft_ap_sta_left,
+       things_wifi_scan_done,
+};
+
+typedef int8_t INT8;
+
+bool try_connect_home_ap(wifi_manager_ap_config_s *connect_config)
+{
+       wifi_manager_result_e result = WIFI_MANAGER_SUCCESS;
+
+       int retry_count = 0;
+
+       for (; retry_count < 3; retry_count++) {
+               result = wifi_manager_connect_ap(connect_config);
+
+               if (result == WIFI_MANAGER_SUCCESS) {
+                       break;
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to connect WiFi");
+               }
+       }
+
+       if (retry_count == 3) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to connect WiFi 3 times");
+               return false;
+       }
+
+       return true;
+}
+
+bool try_turn_on_soft_ap()
+{
+       wifi_manager_info_s info;
+       wifi_manager_get_info(&info);
+
+       if (info.mode != SOFTAP_MODE) {
+               wifi_manager_softap_config_s *ap_config = dm_get_softap_wifi_config();
+               if (wifi_manager_set_mode(SOFTAP_MODE, ap_config) != WIFI_MANAGER_SUCCESS) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to change to SOFTAP mode");
+                       return false;
+               }
+       }
+       THINGS_LOG(THINGS_INFO, TAG, "In SOFTAP mode");
+       return true;
+}
+
+bool things_handle_stop_soft_ap(wifi_manager_ap_config_s *connect_config)
+{
+       wifi_manager_result_e result = WIFI_MANAGER_SUCCESS;
+       wifi_manager_info_s info;
+       wifi_manager_get_info(&info);
+
+       if (info.mode == SOFTAP_MODE) {
+               if (wifi_manager_set_mode(STA_MODE, NULL) != WIFI_MANAGER_SUCCESS) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to change to STA mode)");
+                       return false;
+               }
+               usleep(100000);
+       }
+
+       int retry_count = 0;
+
+       for (; retry_count < 3; retry_count++) {
+               result = wifi_manager_connect_ap(connect_config);
+
+               if (result == WIFI_MANAGER_SUCCESS) {
+                       break;
+               } else {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to connect WiFi");
+               }
+       }
+
+       if (retry_count == 3) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to connect WiFi 3 times");
+               return false;
+       }
+
+       if (connect_config != NULL) {
+               save_acces_point_info(connect_config);
+       }
+
+       return true;
+}
+
+INT8 things_wifi_connection_cb(access_point_info_s *p_info, char *p_cmd_id)
+{
+       THINGS_LOG_D(THINGS_INFO, TAG, "T%d --> %s", getpid(), __FUNCTION__);
+
+       if (p_info == NULL) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "Invalid params");
+               return -1;
+       }
+
+       wifi_manager_ap_config_s connect_config;
+
+       strncpy(connect_config.ssid, p_info->e_ssid, sizeof(connect_config.ssid));
+       connect_config.ssid_length = strlen(connect_config.ssid);
+       strncpy(connect_config.passphrase, p_info->security_key, sizeof(connect_config.passphrase));
+
+       connect_config.passphrase_length = strlen(connect_config.passphrase);
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "[%s] ssid : %s", __FUNCTION__, connect_config.ssid);
+       THINGS_LOG_D(THINGS_INFO, TAG, "[%s] passphrase : %s", __FUNCTION__, connect_config.passphrase);
+
+       // set auth type
+       if (strncmp(p_info->auth_type, "WEP", strlen("WEP")) == 0) {
+               connect_config.ap_auth_type = WIFI_MANAGER_AUTH_WEP_SHARED;
+       } else if (strncmp(p_info->auth_type, "WPA-PSK", strlen("WPA-PSK")) == 0) {
+               connect_config.ap_auth_type = WIFI_MANAGER_AUTH_WPA_PSK;
+       } else if (strncmp(p_info->auth_type, "WPA2-PSK", strlen("WPA2-PSK")) == 0) {
+               connect_config.ap_auth_type = WIFI_MANAGER_AUTH_WPA2_PSK;
+       }
+       // set encryption crypto type
+       if (strncmp(p_info->enc_type, "WEP-64", strlen("WEP-64")) == 0) {
+               connect_config.ap_crypto_type = WIFI_MANAGER_CRYPTO_WEP_64;
+       } else if (strncmp(p_info->enc_type, "WEP-128", strlen("WEP-128")) == 0) {
+               connect_config.ap_crypto_type = WIFI_MANAGER_CRYPTO_WEP_128;
+       } else if (strncmp(p_info->enc_type, "TKIP", strlen("TKIP")) == 0) {
+               connect_config.ap_crypto_type = WIFI_MANAGER_CRYPTO_TKIP;
+       } else if (strncmp(p_info->enc_type, "AES", strlen("AES")) == 0) {
+               connect_config.ap_crypto_type = WIFI_MANAGER_CRYPTO_AES;
+       } else if (strncmp(p_info->enc_type, "TKIP_AES", strlen("TKIP_AES")) == 0) {
+               connect_config.ap_crypto_type = WIFI_MANAGER_CRYPTO_TKIP_AND_AES;
+       }
+
+       int ret = things_handle_stop_soft_ap(&connect_config);
+       if (ret != 1) {
+               return -1;
+       }
+
+       return 1;
+}
+
+access_point_info_s *create_access_info()
+{
+       access_point_info_s *info = (access_point_info_s *) things_malloc(sizeof(access_point_info_s));
+       memset(info->e_ssid, 0, MAX_ESSID);
+       memset(info->security_key, 0, MAX_SECUIRTYKEY);
+       memset(info->auth_type, 0, MAX_TYPE_AUTH);
+       memset(info->enc_type, 0, MAX_TYPE_ENC);
+       memset(info->channel, 0, MAX_CHANNEL);
+       memset(info->signal_level, 0, MAX_LEVEL_SIGNAL);
+       memset(info->bss_id, 0, MAX_BSSID);
+       return info;
+}
+
+int things_wifi_search_cb(access_point_info_s *** p_info, int *p_count)
+{
+       THINGS_LOG_V(THINGS_INFO, TAG, THINGS_FUNC_ENTRY);
+//TO DO
+       (*p_count) = 0;
+
+       return 1;
+
+}
+
+static void otm_event_cb(const char *addr, uint16_t port, const char *uuid, int event)
+{
+       switch (event) {
+       case OIC_OTM_READY:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OIC_OTM_READY");
+               break;
+       case OIC_OTM_STARTED:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OIC_OTM_STARTED");
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "[%s:%d][%s]", addr, port, uuid);
+               break;
+       case OIC_OTM_DONE:
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "OIC_OTM_DONE");
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "[%s:%d][%s]", addr, port, uuid);
+               break;
+       case OIC_OTM_ERROR:
+               THINGS_LOG_D(THINGS_ERROR, TAG, "OIC_OTM_ERROR");
+               break;
+       default:
+               THINGS_LOG_D(THINGS_ERROR, TAG, "Unknown");
+               break;
+       }
+       if (g_otm_event_handler) {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Call the registered funcation...");
+               g_otm_event_handler(addr, port, uuid, event);
+       }
+}
+
+int things_initialize_stack(const char *json_path, bool *easysetup_completed)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (is_things_module_inited) {
+               THINGS_LOG(THINGS_ERROR, TAG, "Stack already initialized");
+               return 0;
+       }
+
+       things_log_init();
+       things_log_set_version(OIC_STACK_FIRMWARE_VERSION);
+
+       if (!dm_init_module(json_path)) {
+               THINGS_LOG(THINGS_ERROR, TAG, "dm_init_module() failed");
+               return 0;
+       }
+       is_things_module_inited = 1;
+
+       *easysetup_completed = dm_is_there_things_cloud();
+
+       return 1;
+}
+
+int things_send_push_message(const char *push_uri, void *payload)
+{
+       if (payload == NULL) {
+               THINGS_LOG(THINGS_ERROR, TAG, "payload is NULL");
+               return 0;
+       }
+       if (!push_notification_to_cloud(push_uri, (OCRepPayload *) payload)) {
+               THINGS_LOG_D(THINGS_ERROR, TAG, "push_notification_to_cloud() failed");
+               return 0;
+       }
+       return 1;
+}
+
+int things_deinitialize_stack()
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       dm_termiate_module();
+
+       is_things_module_inited = 0;
+
+       return 1;
+}
+
+int things_start_stack()
+{
+       things_register_set_ap_connection_func(things_wifi_connection_cb);
+       things_register_get_ap_list_func(things_wifi_search_cb);
+
+       if (wifi_manager_init(&wifi_callbacks) != WIFI_MANAGER_SUCCESS) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize WiFi manager");
+               return 0;
+       }
+       THINGS_LOG_D(THINGS_INFO, TAG, "THINGS_STACK version : %s", OIC_STACK_FIRMWARE_VERSION);
+
+       if (dm_get_easysetup_connectivity_type() == es_conn_type_softap) {
+               if (dm_is_there_things_cloud() == false) {
+                       if (!try_turn_on_soft_ap()) {
+                               return 0;
+                       }
+               } else {                                // Alread Owned.
+                       wifi_manager_ap_config_s *ap_config = dm_get_homeap_wifi_config();
+                       try_connect_home_ap(ap_config);
+               }
+       } else if (dm_get_easysetup_connectivity_type() == es_conn_type_ble) {
+               //TO DO
+       } else {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "es_conn_type_Unknown");
+               return 0;
+       }
+
+       // 2. Enable Security Features
+#ifdef __SECURED__
+       int auty_type = AUTH_UNKNOW;
+       switch (dm_get_ownership_transfer_method()) {
+       case 1:                                 // PIN
+               auty_type = AUTH_RANDOM_PIN;
+               break;
+       case 2:                                 // USER_CONFIRM
+               auty_type = AUTH_CERTIFICATE_CONFIRM;
+               break;
+       case 3:                                 // BOTH
+               auty_type = AUTH_RANDOM_PIN + AUTH_CERTIFICATE_CONFIRM;
+               break;
+       }
+
+       if (0 != sm_init_things_security(auty_type, dm_get_svrdb_file_path())) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize OICSecurity features");
+               things_stop();
+               return 0;
+       }
+       sm_set_otm_event_handler(otm_event_cb);
+#endif
+       g_req_handler = get_handler_instance();
+       if (NULL == g_req_handler) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize Request Handler");
+               things_stop();
+               return 0;
+       }
+       // Will be refactored to received callbacks for GET/PUT/POST/DELETE/OBSERVE ..
+       g_req_handler->init_module();
+
+       // 4. Initiate Server Builder
+       g_server_builder = get_builder_instance();
+       if (NULL == g_server_builder) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize Resource Server");
+               things_stop();
+               return 0;
+       }
+
+       g_server_builder->init_module(g_server_builder, g_req_handler->entity_handler);
+
+#ifdef __SECURED__
+       //5. Generate MAC based device UUID
+       if (0 != sm_generate_mac_based_device_id(false)) {
+               THINGS_LOG(THINGS_WARNING, TAG, "Failed to generate MAC based device_id");
+               things_stop();
+               return 0;
+       }
+#endif
+
+       // 6. Register Device-ID & Resources
+       if (dm_register_device_id() == false) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to register Device ID");
+               things_stop();
+               return 0;
+       }
+
+       if (!dm_register_resource(g_server_builder)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to register Resource");
+               things_stop();
+               return 0;
+       }
+       // 7. Initiate Easy-Setup & Login to Cloud
+       if (ESM_OK != esm_init_easysetup(0, g_server_builder)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize Easy-Setup Module");
+               things_stop();
+               return 0;
+       }
+       // Register Callback
+       esm_register_cloud_cb(cloud_data_cb_esm);
+
+       if (es_cloud_init(g_server_builder) == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize Cloud");
+               things_stop();
+               return 0;
+       }
+
+       is_things_module_inited = 1;
+
+       g_quit_flag = 0;
+
+       THINGS_LOG_D(THINGS_INFO, TAG, "Stack Initialization Success");
+       return 1;
+}
+
+int things_reset(void *remote_owner, things_es_enrollee_reset_e resetType)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+
+       if (resetType == RST_AUTO_RESET) {
+               try_turn_on_soft_ap();
+       }
+
+       int res = -1;
+
+       if (b_thread_things_reset) {
+               return 0;
+       }
+
+       if (resetType >= RST_ENUM_EOF || resetType < RST_NEED_CONFIRM) {
+               THINGS_LOG_D(THINGS_INFO, TAG, "Not support things_es_enrollee_reset_e value(%d). So, Set value with RST_NEED_CONFIRM", resetType);
+               resetType = RST_NEED_CONFIRM;
+       }
+
+       if (g_confirm_reset_start == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Reset-Start confirmation Function is not registered. It's mandatory");
+               return res;
+       }
+
+       pthread_mutex_lock(&m_thread_oic_reset);
+       if (b_thread_things_reset == false) {
+               b_thread_things_reset = true;
+               reset_args_s *args = (reset_args_s *) things_malloc(sizeof(reset_args_s));
+               if (args == NULL) {
+                       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to allocate reset_args_s memory");
+                       b_thread_things_reset = false;
+                       res = -1;
+                       goto GOTO_OUT;
+               }
+               args->remote_owner = (things_resource_s *) remote_owner;
+               args->resetType = resetType;
+
+               b_reset_continue_flag = true;
+#ifdef __ST_THINGS_RTOS__
+               if (pthread_create_rtos(&h_thread_things_reset, NULL, (pthread_func_type) t_things_reset_loop, args, THINGS_STACK_RESETLOOP_THREAD) != 0)
+#else
+               if (things_thread_create(&h_thread_things_reset, NULL, (pthread_func_type) t_things_reset_loop, args) != 0)
+#endif
+               {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Failed to create thread");
+                       h_thread_things_reset = 0;
+                       things_free(args);
+                       args = NULL;
+                       b_thread_things_reset = false;
+                       res = -1;
+                       goto GOTO_OUT;
+               }
+               pthread_detach(h_thread_things_reset);
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Reset Thread handler = 0x%X", h_thread_things_reset);
+               res = 1;
+       } else {
+               THINGS_LOG(THINGS_INFO, TAG, "Already run Reset-Process.");
+               res = 0;
+       }
+
+GOTO_OUT:
+       pthread_mutex_unlock(&m_thread_oic_reset);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       return res;
+}
+
+int things_stop(void)
+{
+       pthread_mutex_lock(&g_things_stop_mutex);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       g_quit_flag = 1;
+       is_things_module_inited = 0;
+
+       pthread_mutex_lock(&m_thread_oic_reset);
+       if (b_thread_things_reset == true) {
+               b_reset_continue_flag = false;
+               h_thread_things_reset = 0;
+               b_thread_things_reset = false;
+       }
+       pthread_mutex_unlock(&m_thread_oic_reset);
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Terminate Cloud Session Managing");
+       es_cloud_terminate();
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Terminate EasySetup");
+       esm_terminate_easysetup();
+
+       if (g_server_builder != NULL) {
+               g_server_builder->deinit_module(g_server_builder);
+               release_builder_instance(g_server_builder);
+               g_server_builder = NULL;
+       }
+       if (g_req_handler != NULL) {
+               g_req_handler->deinit_module();
+               release_handler_instance(g_req_handler);
+               g_req_handler = NULL;
+       }
+       // Need to add memory release for the Queue..
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_EXIT);
+
+       pthread_mutex_unlock(&g_things_stop_mutex);
+       return 1;
+}
+
+int things_register_confirm_reset_start_func(things_reset_confirm_func_type func)
+{
+       if (func != NULL) {
+               g_confirm_reset_start = func;
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int things_notify_observers(const char *uri)
+{
+       if (g_req_handler == NULL) {
+               THINGS_LOG(THINGS_ERROR, TAG, "g_req_handler is NULL");
+               return 0;
+       }
+       return g_req_handler->notify_things_observers(uri);
+}
+
+int things_register_update_dev_prov_data_func(things_update_dev_prov_data_func_type func)
+{
+       if (func != NULL) {
+               esm_register_update_dev_prov_data_func(func);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int things_register_set_ap_connection_func(things_set_ap_connection_func_type func)
+{
+       // Stack (Easy-setup) can request device to access specific AP
+       // with this registered callback
+       if (func != NULL) {
+               things_register_set_ap_conn_func(func);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int things_wifi_changed_call_func(int state, char *ap_name, char *ip_addr)
+{
+       int ret = 0;
+
+       if (is_things_module_inited == 0) {
+               return ret;
+       }
+
+       pthread_mutex_lock(&g_app_cb_mutex);
+#ifdef __ST_THINGS_RTOS__
+       pthread_mutex_lock(&m_thread_oic_reset);
+       ret = things_wifi_state_changed_cb(state, ap_name, ip_addr);
+       pthread_mutex_unlock(&m_thread_oic_reset);
+#else
+       ret = things_wifi_state_changed_cb(state, ap_name, ip_addr);
+#endif
+       pthread_mutex_unlock(&g_app_cb_mutex);
+
+       return ret;
+}
+
+int things_register_stop_soft_ap_func(things_stop_soft_ap_func_type func)
+{
+       if (NULL != func) {
+               return register_stop_softap_cb(func);
+       } else {
+               return 0;
+       }
+}
+
+int things_register_pin_generated_func(things_pin_generated_func_type func)
+{
+       if (NULL != func) {
+#ifdef __SECURED__
+               return esm_register_pin_generated_cb(func);
+#else
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Stack is in UNSECURED Mode");
+               return 0;
+#endif
+       } else {
+               return 0;
+       }
+}
+
+int things_register_pin_display_close_func(things_pin_display_close_func_type func)
+{
+       if (NULL != func) {
+#ifdef __SECURED__
+               return esm_register_pin_close_cb(func);
+#else
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Stack is in UNSECURED Mode");
+               return 0;
+#endif
+       } else {
+               return 0;
+       }
+}
+
+int things_register_user_confirm_func(things_get_user_confirm_func_type func)
+{
+       if (NULL != func) {
+#ifdef __SECURED__
+               return esm_register_user_confirm_cb(func);
+#else
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Stack is in UNSECURED Mode");
+               return 0;
+#endif
+       } else {
+               return 0;
+       }
+}
+
+int things_register_handle_request_func(things_handle_request_func_type get_func, things_handle_request_func_type set_func)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+       if ((NULL == get_func) || (NULL == set_func)) {
+               THINGS_LOG(THINGS_ERROR, TAG, "Callback is NULL");
+               return 0;
+       }
+       register_handle_request_func(get_func, set_func);
+       return 1;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Functions Definition for Security feature
+//////////////////////////////////////////////////////////////////////////
+int things_register_otm_event_handler(things_sec_otm_state_func_type otmEventCallback)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, THINGS_FUNC_ENTRY);
+#ifdef __SECURED__
+       if (otmEventCallback == NULL) {
+               THINGS_LOG(THINGS_ERROR, TAG, "otmEventCallback is NULL");
+               return 0;
+       }
+       g_otm_event_handler = otmEventCallback;
+#else
+       THINGS_LOG(THINGS_ERROR, TAG, "Stack is in UNSECURED Mode");
+       return 0;
+#endif
+       return 1;
+}
+
+int things_save_acl(const char *uuid, const char *resourceUri, const char *resourceType, const char *interfaceName, uint16_t permission)
+{
+       int ret = -1;
+       THINGS_LOG(THINGS_DEBUG, TAG, "In things_save_acl");
+#ifdef __SECURED__
+       ret = sm_save_acl(uuid, resourceUri, resourceType, interfaceName, permission);
+#else
+       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Stack is in UNSECURED Mode");
+#endif
+       THINGS_LOG(THINGS_DEBUG, TAG, "Out things_save_acl");
+       return ret;
+}
+
+int things_set_mot_status(bool enable)
+{
+       int ret = -1;
+       THINGS_LOG(THINGS_DEBUG, TAG, "In things_set_mot_status");
+#ifdef __SECURED__
+       ret = sm_set_mot_status(enable);
+#else
+       THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Stack is in UNSECURED Mode");
+#endif
+       THINGS_LOG(THINGS_DEBUG, TAG, "Out things_set_mot_status");
+       return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Functions Definition for Reset Handling.
+//////////////////////////////////////////////////////////////////////////
+static void things_set_reset_mask(rst_state_e value)
+{
+       if (value != RST_COMPLETE) {
+               m_reset_bit_mask |= value;
+       } else {
+               m_reset_bit_mask = value;
+       }
+}
+
+bool things_get_reset_mask(rst_state_e value)
+{
+       return (int)(m_reset_bit_mask & value) != 0 ? true : false;
+}
+
+void things_control_queue_empty(void)
+{
+       if (things_get_reset_mask(RST_CONTROL_MODULE_DISABLE) == true) {
+               things_set_reset_mask(RST_CONTROL_QUEUE_EMPTY);
+       }
+}
+
+int things_return_user_opinion_for_reset(int b_reset_start)    // b_reset_start : User opinion.
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       int result = 0;
+
+       if (b_reset_start == true && b_reset_continue_flag == true) {   // User allow Reset-Starting.
+               things_set_reset_mask(RST_USER_CONFIRM_COMPLETED);
+               result = 1;
+       } else {                                        // User not allow Reset.
+               b_reset_continue_flag = false;
+       }
+
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "User Opinion : %d", result);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return result;
+}
+
+static void *__attribute__((optimize("O0"))) t_things_reset_loop(reset_args_s *args)
+{
+       THINGS_LOG_D(THINGS_DEBUG, TAG, "Enter. Handler=0x%X", h_thread_things_reset);
+
+       int result = 0;
+       things_reset_result_func_type things_cb_func_for_reset_result = NULL;
+
+       if (args == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "args is NULL. It's mandatory.");
+               goto GOTO_OUT;
+       }
+
+       if (g_confirm_reset_start == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Reset-Start confirmation Function is not registered. It's mandatory.");
+               goto GOTO_OUT;
+       }
+
+       things_set_reset_mask(RST_COMPLETE);
+       THINGS_LOG(THINGS_DEBUG, TAG, "Start Reset Processing.");
+
+       // 0. Trigger User-Confirm GUI and Wait for getting User-Opinion with regard to Reset.
+       THINGS_LOG(THINGS_DEBUG, TAG, "Trigger Reset-GUI.");
+       if (g_confirm_reset_start(&things_cb_func_for_reset_result, args->resetType) == 0) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "User don't want to reset. So reset canceled.");
+               goto GOTO_OUT;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Waiting User-Opinion for Reset-Start.");
+       while (b_reset_continue_flag == true && things_get_reset_mask(RST_USER_CONFIRM_COMPLETED) == false) {   // It's Blocking until receive user-opinion.
+               usleep(300000);                 // 0.3 seconds wait.
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Break-Stop Check.");
+       if (b_reset_continue_flag == false) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Called Reset break-STOP.");
+               goto GOTO_OUT;
+       }
+       // 1. Easy Setup : Provisioning Disable.
+       // 2. Controlling Module : Disable pushing request to Queue.
+       THINGS_LOG(THINGS_DEBUG, TAG, "Disable Modules.(EasySetup/Controlling Module)");
+       things_set_reset_mask(RST_EASY_SETUP_DISABLE | RST_CONTROL_MODULE_DISABLE);
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Break-Stop Check.");
+       if (b_reset_continue_flag == false) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "Called Reset break-STOP.");
+               goto GOTO_OUT;
+       }
+       // 3. Notification Push Disable.
+       THINGS_LOG(THINGS_DEBUG, TAG, "Disable Notification Module.");
+       things_set_reset_mask(RST_NOTI_MODULE_DISABLE);
+
+       OCClearObserverlist();          // delete All Observer. (for remote Client)
+
+       // 4. Cloud Manager : Terminate
+       THINGS_LOG(THINGS_DEBUG, TAG, "Terminate Cloud Module.");
+       es_cloud_terminate();
+
+       // 5. Easy Setup : Terminate
+       THINGS_LOG(THINGS_DEBUG, TAG, "Terminate Easy-Setup Module.");
+       if (esm_terminate_easysetup() != ESM_MODULE_TERMINATED) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Easy-Setup Module termination failed");
+               goto GOTO_OUT;
+       }
+       // 6. Delete Cloud data in "provisioning.json"
+       THINGS_LOG(THINGS_DEBUG, TAG, "Delete Cloud-Data in provisioning.json file.");
+       if (dm_del_things_cloud_data() == 0) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "It's failed to delete information about Cloud-Data in \"ocf_infoX.json\" file.");
+               goto GOTO_OUT;
+       }
+       THINGS_LOG(THINGS_INFO, TAG, "Reset done: cloud provisioning data");
+
+       OCClearCallBackList();          // delete All Client Call-Back List. (for SET Self-Request)
+
+       // 7. Security Reset.
+#ifdef __SECURED__
+       if (0 != sm_reset_svrdb()) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Failed to initialize OICSecurity features.");
+               goto GOTO_OUT;
+       }
+       THINGS_LOG(THINGS_INFO, TAG, "Reset done: security resources");
+
+       if (0 != sm_generate_mac_based_device_id(true)) {
+               THINGS_LOG(THINGS_WARNING, TAG, "Failed to generate MAC based device_id.");
+               goto GOTO_OUT;
+       }
+#else
+       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "NOT SECURED MODE!!!!! ");
+#endif
+
+       // 8. Easy Setup : Initialization.
+       THINGS_LOG(THINGS_DEBUG, TAG, "Initial Easy-Setup Module.");
+       if (ESM_OK != esm_init_easysetup(0, g_server_builder)) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Easy-Setup Module initialization failed");
+               goto GOTO_OUT;
+       }
+       esm_register_cloud_cb(cloud_data_cb_esm);
+
+       // 9. Cloud Manager : Initialization.
+       THINGS_LOG(THINGS_DEBUG, TAG, "Initial Cloud Module.");
+       if (es_cloud_init(g_server_builder) == NULL) {
+               THINGS_LOG(THINGS_DEBUG, TAG, "It's failed Cloud_Module initialization.");
+               goto GOTO_OUT;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Reset Success.");
+       result = 1;
+
+GOTO_OUT:
+       // 10. All Module Enable.
+       things_set_reset_mask(RST_COMPLETE);
+
+       /*SVACE warning fix */
+       if (args) {
+               // 11. If reset-processing is triggered by remote-owner, then Notify result of Reset.
+               THINGS_LOG(THINGS_DEBUG, TAG, "Notify result of reset to remote-client.(mobile)");
+               notify_result_of_reset(args->remote_owner, result);
+       }
+       // 12. If there is Reset Result Call-Back Function, then Notify result of Reset to st_things-Application.
+       if (things_cb_func_for_reset_result) {  // Notify result of reset to st_things.
+               THINGS_LOG(THINGS_DEBUG, TAG, "Notify result of reset to st_things.");
+               things_cb_func_for_reset_result(result);
+       }
+
+       if (args) {
+               things_free(args);
+               args = NULL;
+       }
+       pthread_mutex_lock(&m_thread_oic_reset);
+       h_thread_things_reset = 0;
+       b_thread_things_reset = false;
+       pthread_mutex_unlock(&m_thread_oic_reset);
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return NULL;
+}
+
+OCEntityHandlerResult things_abort(pthread_t *h_thread_abort, things_es_enrollee_abort_e level)
+{
+       s_abort_s *ARGs = NULL;
+       OCEntityHandlerResult eh_result = OC_EH_ERROR;
+
+       if (h_thread_abort == NULL) {
+               THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "h_thread_abort is NULL.");
+               return eh_result;
+       }
+
+       if ((*h_thread_abort) == 0) {
+               if ((ARGs = (s_abort_s *) things_malloc(sizeof(s_abort_s))) == NULL) {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Memory Allocation is failed.(for abort Thread)");
+                       return OC_EH_ERROR;
+               }
+
+               ARGs->h_thread = h_thread_abort;
+               ARGs->level = level;
+
+               eh_result = OC_EH_OK;
+#ifdef __ST_THINGS_RTOS__
+               if (pthread_create_rtos(h_thread_abort, NULL, (pthread_func_type) t_things_abort_loop, ARGs, THINGS_STACK_OICABORT_THREAD) != 0)
+#else
+               if (things_thread_create(h_thread_abort, NULL, (pthread_func_type) t_things_abort_loop, ARGs) != 0)
+#endif
+
+               {
+                       THINGS_LOG_V_ERROR(THINGS_ERROR, TAG, "Create thread is failed.(for abort Thread)");
+                       *h_thread_abort = 0;
+                       eh_result = OC_EH_ERROR;
+               }
+       } else {
+               THINGS_LOG_D(THINGS_DEBUG, TAG, "Already called Thread. So, OC_EH_NOT_ACCEPTABLE");
+               eh_result = OC_EH_NOT_ACCEPTABLE;
+       }
+
+       pthread_detach(h_thread_abort);
+       return eh_result;
+}
+
+static void *__attribute__((optimize("O0"))) t_things_abort_loop(s_abort_s *contents)
+{
+       THINGS_LOG(THINGS_DEBUG, TAG, "Enter.");
+
+       if (contents == NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "contents is NULL.");
+               goto GOTO_OUT;
+       }
+
+       if (g_abort_easysetup != NULL) {
+               THINGS_LOG_ERROR(THINGS_ERROR, TAG, "Registered Abort Function. So, Call Function st_things API.");
+               g_abort_easysetup(contents->level);
+       }
+
+GOTO_OUT:
+       if (contents) {
+               *(contents->h_thread) = 0;
+               things_free(contents);
+               contents = NULL;
+       }
+
+       THINGS_LOG(THINGS_DEBUG, TAG, "Exit.");
+       return NULL;
+}