Add tethering ext test application 36/320836/12
authorvenkat-iyer <venkat.iyer@samsung.com>
Mon, 10 Mar 2025 05:01:13 +0000 (14:01 +0900)
committervenkat-iyer <venkat.iyer@samsung.com>
Tue, 8 Apr 2025 04:39:31 +0000 (13:39 +0900)
Change-Id: I94b12b5e064474706b691b37909a09a7183722af
Signed-off-by: venkat-iyer <venkat.iyer@samsung.com>
17 files changed:
CMakeLists.txt
include/tethering_ext.h
include/tethering_ext_common.h
include/tethering_ext_dbus.h
include/tethering_ext_internal.h
packaging/capi-network-tethering.spec
src/tethering_ext.c
src/tethering_ext_dbus.c
src/tethering_ext_internal.c
test_application/CMakeLists.txt [new file with mode: 0755]
test_application/tethering_ext_test.c [new file with mode: 0644]
test_application/tethering_ext_test.h [new file with mode: 0644]
test_application/tethering_ext_test_main.c [new file with mode: 0755]
test_application/tethering_ext_test_scenario.c [new file with mode: 0644]
test_application/tethering_ext_test_scenario.h [new file with mode: 0644]
test_application/tethering_ext_test_util.c [new file with mode: 0644]
test_application/tethering_ext_test_util.h [new file with mode: 0644]

index fd850bd2940407bda75cab2d9095218b7cad1fcd..2584ff90fea08a982bed9d91bc56f0cc37b9b806 100755 (executable)
@@ -67,6 +67,7 @@ CONFIGURE_FILE(
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
 ADD_SUBDIRECTORY(tools)
+ADD_SUBDIRECTORY(test_application)
 IF(BUILD_UNITTEST)
        ADD_SUBDIRECTORY(tests)
 ENDIF(BUILD_UNITTEST)
index af6e08bc3a7e179b8ec63c6d3f5c9539155ecc1c..7e1b3f647c720c256413a411b503e37829ad6768 100644 (file)
@@ -17,7 +17,6 @@
 #define __TIZEN_NETWORK_TETHERING_EXT_H
 
 #include <tethering_ext_common.h>
-#include <tethering_ext_internal.h>
 
 #define RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(arg) \
        do { \
        } while (0)
 
 
-int tethering_ext_initialize(tethering_ext_h *th_context);
-int tethering_ext_deinitialize(tethering_ext_h th_context);
-int tethering_ext_activate(tethering_ext_h th_context);
-int tethering_ext_deactivate(tethering_ext_h th_context);
-int tethering_ext_is_enabled(tethering_ext_h th_context, bool *is_enabled);
-int tethering_ext_set_configuration(tethering_ext_h th_context, tethering_ext_config_h *src_config, int config_flags);
-int tethering_ext_set_ssid(tethering_ext_h th_context, const char *ssid);
-int tethering_ext_set_passphrase(tethering_ext_h th_context, const char *passphrase);
-int tethering_ext_set_channel(tethering_ext_h th_context, int channel);
-int tethering_ext_get_tethering_info(tethering_ext_h th_context, void **tethering_info);
-int tethering_ext_get_channel(tethering_ext_h th_context, int *channel);
-int tethering_ext_get_security(tethering_ext_h th_context, int *security);
-int tethering_ext_get_visibility(tethering_ext_h th_context, int *visibility);
-int tethering_ext_get_sharing(tethering_ext_h th_context, bool *sharing);
+int tethering_ext_initialize(tethering_ext_h *tethering_context);
+int tethering_ext_deinitialize(tethering_ext_h tethering_context);
+int tethering_ext_set_enabled_cb(tethering_ext_h tethering_context, tethering_ext_enabled_cb callback, void *user_data);
+int tethering_ext_unset_enabled_cb(tethering_ext_h tethering_context);
+int tethering_ext_set_disabled_cb(tethering_ext_h tethering_context, tethering_ext_disabled_cb callback, void *user_data);
+int tethering_ext_unset_disabled_cb(tethering_ext_h tethering_context);
+int tethering_ext_set_connection_state_changed_cb(tethering_ext_h tethering_context, tethering_ext_connection_state_changed_cb callback, void *user_data);
+int tethering_ext_unset_connection_state_changed_cb(tethering_ext_h tethering_context);
+int tethering_ext_activate(tethering_ext_h tethering_context);
+int tethering_ext_deactivate(tethering_ext_h tethering_context);
+int tethering_ext_is_enabled(tethering_ext_h tethering_context, bool *is_enabled);
+int tethering_ext_set_ssid(tethering_ext_h tethering_context, const char *ssid);
+int tethering_ext_set_passphrase(tethering_ext_h tethering_context, const char *passphrase);
+int tethering_ext_set_channel(tethering_ext_h tethering_context, int channel);
+int tethering_ext_get_tethering_info(tethering_ext_h tethering_context, void *tethering_info);
+int tethering_ext_get_channel(tethering_ext_h tethering_context, int *channel);
+int tethering_ext_get_security(tethering_ext_h tethering_context, int *security);
+int tethering_ext_get_visibility(tethering_ext_h tethering_context, int *visibility);
+int tethering_ext_get_sharing(tethering_ext_h tethering_context, bool *sharing);
+int tethering_ext_client_clone(tethering_ext_client_h *dest, tethering_ext_client_h origin);
+int tethering_ext_client_get_name(tethering_ext_client_h client, char **name);
+int tethering_ext_client_get_ip_address(tethering_ext_client_h client, char **ip_address);
+int tethering_ext_client_get_mac_address(tethering_ext_client_h client, char **mac_address);
+int tethering_ext_client_destroy(tethering_ext_client_h client);
+
 
 #endif /* __TIZEN_NETWORK_TETHERING_EXT_H */
index 43e880a1fbd6d1b5cecfef173cacf93ba6edae16..eaa70f60d1093271211ff8450aa87356540ccfd6 100644 (file)
 #define __TIZEN_NETWORK_TETHERING_EXT_COMMON_H
 #include <tizen.h>
 #include <tethering.h>
+#include <dlog.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define TETHERING_EXT_WIFI_SSID_MIN_LEN 1
 #define TETHERING_EXT_WIFI_SSID_MAX_LEN 32
+#define TETHERING_EXT_WIFI_KEY_MIN_LEN 8
 #define TETHERING_EXT_WIFI_KEY_MAX_LEN 64
 #define TETHERING_EXT_IPV4_ADDRESS_MAX_LEN 15
 
+#define TETHERING_EXT_LOG_TAG "TetheringExtension"
+
+#ifndef TETHERING_EXT_ERR
+#define TETHERING_EXT_ERR(fmt, args...) dlog_print(DLOG_ERROR, TETHERING_EXT_LOG_TAG, fmt, ##args)
+#endif
+
+#ifndef TETHERING_EXT_DBG
+#define TETHERING_EXT_DBG(fmt, args...) dlog_print(DLOG_DEBUG, TETHERING_EXT_LOG_TAG, fmt, ##args)
+#endif
+
+#ifndef TETHERING_EXT_INFO
+#define TETHERING_EXT_INFO(fmt, args...) dlog_print(DLOG_INFO, TETHERING_EXT_LOG_TAG, fmt, ##args)
+#endif
+
 typedef void *tethering_ext_h;
 
 typedef enum {
@@ -39,6 +56,18 @@ typedef enum {
     TETHERING_EXT_ALL = 63
 } tethering_ext_config_e;
 
+// Maps in value to tethering_disabled_cause_e
+typedef enum {
+    TETHERING_EXT_DISABLED_BY_FLIGHT_MODE = 1,  /**< Disabled due to flight mode */
+    TETHERING_EXT_DISABLED_BY_LOW_BATTERY,  /**< Disabled due to low battery */
+    TETHERING_EXT_DISABLED_BY_NETWORK_CLOSE,  /**< Disabled due to pdp network close */
+    TETHERING_EXT_DISABLED_BY_TIMEOUT,  /**< Disabled due to timeout */
+    TETHERING_EXT_DISABLED_BY_OTHERS,  /**< Disabled by other apps */
+    TETHERING_EXT_DISABLED_BY_REQUEST,  /**< Disabled by your request */
+    TETHERING_EXT_DISABLED_BY_WIFI_ON,  /**< Disabled due to Wi-Fi on */
+} tethering_ext_disabled_cause_e;
+
+
 typedef struct {
     char ssid[TETHERING_EXT_WIFI_SSID_MAX_LEN + 1];
     char passphrase[TETHERING_EXT_WIFI_KEY_MAX_LEN + 1];
@@ -51,6 +80,11 @@ typedef struct {
     char ipaddr[TETHERING_EXT_IPV4_ADDRESS_MAX_LEN + 1];
 } tethering_ext_config_h;
 
+typedef void *tethering_ext_client_h;
+typedef void (*tethering_ext_enabled_cb) (tethering_error_e result, bool is_requested, void *user_data);
+typedef void (*tethering_ext_disabled_cb) (tethering_error_e result, tethering_ext_disabled_cause_e cause, void *user_data);
+typedef void (*tethering_ext_connection_state_changed_cb) (tethering_ext_client_h client, bool opened, void *user_data);
+
 #ifdef __cplusplus
 }
 #endif
index ebd5d5feb31d536e38bf4322b301c9ae5d18440e..6ddd57711c33b63eb210e654855cfd54502d4242 100644 (file)
@@ -27,8 +27,8 @@ extern "C" {
 #endif
 
 /* tethering-service */
-#define TETHERING_EXT_BUS_NAME                          "net.wifitethering"
-#define TETHERING_EXT_OBJECT_PATH                       "/net/wifitethering"
+#define TETHERING_EXT_BUS_NAME                          "net.wifitetheringExt"
+#define TETHERING_EXT_OBJECT_PATH                       "/net/wifitetheringExt"
 #define TETHERING_EXT_INTERFACE_NAME                    TETHERING_EXT_BUS_NAME ".interface"
 
 #define TETHERING_EXT_METHOD_SET_MODE                   "SetWiFiTetheringMode"
index a25b793f3cddfb85ea48a02b46cbdfd7e6107f28..bd69f33d6cf31cb3f511ffe54f9d377187af4ec4 100644 (file)
@@ -38,17 +38,6 @@ typedef enum {
     TETHERING_EXT_POWER_IND = 0
 } _tethering_ext_event_e;
 
-// Maps in value to tethering_disabled_cause_e
-typedef enum {
-    TETHERING_EXT_DISABLED_BY_FLIGHT_MODE = 1,  /**< Disabled due to flight mode */
-    TETHERING_EXT_DISABLED_BY_LOW_BATTERY,  /**< Disabled due to low battery */
-    TETHERING_EXT_DISABLED_BY_NETWORK_CLOSE,  /**< Disabled due to pdp network close */
-    TETHERING_EXT_DISABLED_BY_TIMEOUT,  /**< Disabled due to timeout */
-    TETHERING_EXT_DISABLED_BY_OTHERS,  /**< Disabled by other apps */
-    TETHERING_EXT_DISABLED_BY_REQUEST,  /**< Disabled by your request */
-    TETHERING_EXT_DISABLED_BY_WIFI_ON,  /**< Disabled due to Wi-Fi on */
-} _tethering_ext_disabled_cause_e;
-
 typedef enum {
        TETHERING_EXT_ERR_NONE = 0x00,                                                  /** No error */
 
@@ -84,6 +73,11 @@ typedef struct {
        void *Data;
 } _tethering_ext_event_info_h;
 
+typedef struct {
+       int DataLength;
+       const char *Data;
+} _tethering_ext_data_h;
+
 typedef struct {
        char *tethering_ssid;
        char *tethering_password;
@@ -96,22 +90,24 @@ typedef struct {
        time_t tm;
 } _tethering_ext_client_info_h;
 
-
-typedef void *_tethering_ext_client_h;
-typedef void (*_tethering_ext_enabled_cb) (tethering_error_e result, bool is_requested, void *user_data);
-typedef void (*_tethering_ext_disabled_cb) (tethering_error_e result, _tethering_ext_disabled_cause_e cause, void *user_data);
-typedef void (*_tethering_ext_connection_state_changed_cb) (_tethering_ext_client_h client, bool opened, void *user_data);
-
 // Tethering state callbacks
 typedef void(*_tethering_ext_state_changed_cb)(_tethering_ext_state_e state, void *user_data);
 typedef void (*_tethering_ext_event_cb) (const _tethering_ext_event_info_h *tethering_ext_event, void *user_data);
 
+typedef enum {
+       TETHERING_EXT_CALLBACK_VALID_START = 0,
+       TETHERING_EXT_ENABLED_CALLBACK,
+       TETHERING_EXT_DISABLED_CALLBACK,
+       TETHERING_EXT_CONNECTION_STATE_CHANGED_CALLBACK,
+       TETHERING_EXT_CALLBACK_VALID_STOP
+} _tethering_ext_callback_e;
+
 typedef struct {
-    _tethering_ext_enabled_cb enabled_cb;
+    tethering_ext_enabled_cb enabled_cb;
     void *enabled_user_data;
-    _tethering_ext_disabled_cb disabled_cb;
+    tethering_ext_disabled_cb disabled_cb;
     void *disabled_user_data;
-    _tethering_ext_connection_state_changed_cb changed_cb;
+    tethering_ext_connection_state_changed_cb changed_cb;
     void *changed_user_data;
 } _tethering_ext_callback_h;
 
@@ -140,12 +136,8 @@ int _tethering_ext_set_wifi_tethering_mode_with_params(tethering_ext_h tethering
 int _tethering_ext_get_wifi_tethering_mode(tethering_ext_h tethering_context, bool *is_enabled);
 int _tethering_ext_set_config(tethering_ext_h tethering_context, void *src_config, int type);
 int _tethering_ext_get_config(tethering_ext_h tethering_context, void *target_config, int type);
-int _tethering_ext_client_clone(_tethering_ext_client_h *dest, _tethering_ext_client_h origin);
-int _tethering_ext_client_get_name(_tethering_ext_client_h client, char **name);
-int _tethering_ext_client_get_ip_address(_tethering_ext_client_h client, char **ip_address);
-int _tethering_ext_client_get_mac_address(_tethering_ext_client_h client, char **mac_address);
-int _tethering_ext_client_destroy(_tethering_ext_client_h client);
-void _tethering_ext_register_callbacks(tethering_ext_h tethering_context, _tethering_ext_callback_h callbacks);
+int _tethering_ext_register_callback(tethering_ext_h tethering_context, _tethering_ext_callback_e cb_type, void *callback, void *data);
+int _tethering_ext_unregister_callback(tethering_ext_h tethering_context, _tethering_ext_callback_e cb_type);
 #ifdef __cplusplus
 }
 #endif
index b5924ddd21adb3f7361f874076e80c10723c98df..2b721a1ce584e6837dabe700ab7a9783cecb6715 100644 (file)
@@ -39,6 +39,11 @@ Summary:     Test application for Tethering
 %description tool
 Test application for Tethering
 
+%package test_application
+Summary:       Test application for Tethering Ext
+%description test_application
+Test application for Tethering Ext
+
 %if 0%{?gcov:1}
 %package gcov
 Summary:  Tethering Library(gcov)
@@ -85,6 +90,7 @@ builddir=$(basename $PWD)
 gcno_obj_dir=%{buildroot}%{_datadir}/gcov/obj/%{name}/"$builddir"
 mkdir -p "$gcno_obj_dir"
 find . -name '*.gcno' ! -path '*/tools/*' -exec cp --parents '{}' "$gcno_obj_dir" ';'
+find . -name '*.gcno' ! -path '*/test_application/*' -exec cp --parents '{}' "$gcno_obj_dir" ';'
 %endif
 
 %if 0%{?asan} != 1
@@ -143,6 +149,9 @@ genhtml %{name}.info -o out --legend --show-details
 %files tool
 %{_bindir}/tethering_test
 
+%files test_application
+%{_bindir}/tethering_ext_test
+
 %if 0%{?gcov:1}
 %files gcov
 %{_datadir}/gcov/obj/*
index 6556745e509761d126ca980fe5cfc7c381e7c7fe..9435638afdb4306fabc164a0bbbb373f8ac5e555 100644 (file)
  */
 #include <stdlib.h>
 #include <tethering_ext.h>
-#include <dlog.h>
+#include <tethering_ext_internal.h>
+
 
 #define DISABLE_REASON_TEXT_LEN 64
 #define TETHERING_GET_CONFIG(context, value, config, retval)\
 do {\
        if (!context  || !value) {\
-               LOGE("Invalid paramater, exiting");\
+               TETHERING_EXT_ERR("Invalid paramater, exiting");\
                retval = TETHERING_ERROR_INVALID_PARAMETER;\
        } else {\
-               int rv = _tethering_ext_get_config(th_context, (void *) (value), config);\
+               int rv = _tethering_ext_get_config(context, (void *) (value), config);\
                if (rv != TETHERING_EXT_ERR_NONE) {\
-                       LOGE("%s failed with error code %d", __FUNCTION__, rv);\
+                       TETHERING_EXT_ERR("%s failed with error code %d", __FUNCTION__, rv);\
                        retval = TETHERING_ERROR_OPERATION_FAILED;\
                } else  {\
                        retval = TETHERING_ERROR_NONE;\
@@ -34,127 +35,39 @@ do {\
        }\
 } while (0);
 
-/* Tethering callbacks */
-static void __enabled_cb(tethering_error_e result, bool is_requested, void *user_data)
-{
-       if (result != TETHERING_ERROR_NONE) {
-               if (!is_requested)
-                       return;
-
-               g_print("P2P Tethering is not enabled. error code[0x%X]\n", result);
-               return;
-       }
-
-       if (is_requested)
-               g_print("P2P Tethering is enabled successfully\n");
-       else
-               g_print("P2P Tethering is enabled by other app\n");
-
-       return;
-}
-
-static const char *__convert_disabled_code_to_str(const _tethering_ext_disabled_cause_e code)
-{
-       static char str_buf[DISABLE_REASON_TEXT_LEN] = {0, };
-
-       switch (code) {
-       case TETHERING_EXT_DISABLED_BY_FLIGHT_MODE:
-               strncpy(str_buf, "disabled due to flight mode on", sizeof(str_buf));
-               break;
-
-       case TETHERING_EXT_DISABLED_BY_LOW_BATTERY:
-               strncpy(str_buf, "disabled due to low battery", sizeof(str_buf));
-               break;
-
-       case TETHERING_EXT_DISABLED_BY_NETWORK_CLOSE:
-               strncpy(str_buf, "disabled due to pdp network close", sizeof(str_buf));
-               break;
-
-       case TETHERING_EXT_DISABLED_BY_TIMEOUT:
-               strncpy(str_buf, "disabled due to timeout", sizeof(str_buf));
+static tethering_error_e convert_tethering_ext_err(_tethering_ext_err_e error) {
+       tethering_error_e tethering_error = TETHERING_ERROR_NONE;
+       switch (error) {
+               case TETHERING_EXT_ERR_INVALID_OPERATION:
+                       tethering_error = TETHERING_ERROR_INVALID_OPERATION;
                break;
 
-       case TETHERING_EXT_DISABLED_BY_OTHERS:
-               strncpy(str_buf, "disabled by other apps", sizeof(str_buf));
+               case TETHERING_EXT_ERR_INVALID_PARAM:
+                       tethering_error = TETHERING_ERROR_INVALID_PARAMETER;
                break;
 
-       case TETHERING_EXT_DISABLED_BY_REQUEST:
-               strncpy(str_buf, "disabled by my request", sizeof(str_buf));
+               case TETHERING_EXT_ERR_OUT_OF_MEMORY:
+                       tethering_error = TETHERING_ERROR_OUT_OF_MEMORY;
                break;
 
-       case TETHERING_EXT_DISABLED_BY_WIFI_ON:
-               strncpy(str_buf, "disabled by Wi-Fi station on", sizeof(str_buf));
+               case TETHERING_EXT_ERR_NOT_SUPPORTED:
+                       tethering_error = TETHERING_ERROR_NOT_SUPPORT_API;
                break;
 
-       default:
-               strncpy(str_buf, "disabled by unknown reason", sizeof(str_buf));
+               default:
+                       tethering_error = TETHERING_ERROR_OPERATION_FAILED;
                break;
        }
-
-       return str_buf;
-}
-
-static void __disabled_cb(tethering_error_e result, _tethering_ext_disabled_cause_e cause, void *user_data)
-{
-       if (result != TETHERING_ERROR_NONE) {
-               if (cause != TETHERING_EXT_DISABLED_BY_REQUEST)
-                       return;
-
-               g_print("P2P Tethering is not disabled. error code[0x%X]\n", result);
-               return;
-       }
-
-       g_print("P2P Tethering is %s\n", __convert_disabled_code_to_str(cause));
-
-       return;
-}
-
-static void __connection_state_changed_cb(_tethering_ext_client_h client, bool open, void *user_data)
-{
-       _tethering_ext_client_h clone = NULL;
-       // tethering_type_e type;
-       char *ip_address = NULL;
-       char *mac_address = NULL;
-       char *hostname = NULL;
-
-       _tethering_ext_client_clone(&clone, client);
-       if (clone == NULL) {
-               g_print("tetheirng_client_clone is failed\n");
-               return;
-       }
-
-       _tethering_ext_client_get_ip_address(clone, &ip_address);
-       _tethering_ext_client_get_mac_address(clone, &mac_address);
-       _tethering_ext_client_get_name(clone, &hostname);
-
-       if (open) {
-               g_print("## New station Type [P2P Tethering], IP [%s], MAC [%s], hostname [%s]\n",
-                               ip_address, mac_address, hostname);
-       } else {
-               g_print("## Disconnected station Type [P2P Tethering], IP [%s], MAC [%s], hostname [%s]\n",
-                               ip_address, mac_address, hostname);
-       }
-
-       if (ip_address)
-               free(ip_address);
-       if (mac_address)
-               free(mac_address);
-       if (hostname)
-               free(hostname);
-
-       _tethering_ext_client_destroy(clone);
-
-       return;
+       return tethering_error;
 }
 
-
 API int tethering_ext_initialize(tethering_ext_h *tethering_context) {
        // __TETHERING_EXT_CAPI_FUNC_ENTER__;
 
        int rv;
 
        if (tethering_context == NULL) {
-               LOGE("Invalid Parameter");
+               TETHERING_EXT_ERR("Invalid Parameter");
                // __TETHERING_EXT_CAPI_FUNC_EXIT__;
                return TETHERING_ERROR_INVALID_PARAMETER;
        }
@@ -162,7 +75,7 @@ API int tethering_ext_initialize(tethering_ext_h *tethering_context) {
        // TETHERING_EXT_LOCK;
 
        if (_tethering_ext_check_context(*tethering_context)) {
-               LOGE("Already initialized");
+               TETHERING_EXT_ERR("Already initialized");
                // TETHERING_EXT_UNLOCK;
                // __TETHERING_EXT_CAPI_FUNC_EXIT__;
                return TETHERING_ERROR_NONE;
@@ -170,7 +83,7 @@ API int tethering_ext_initialize(tethering_ext_h *tethering_context) {
 
        rv = _tethering_ext_create_context(tethering_context);
        if (rv != TETHERING_EXT_ERR_NONE) {
-               LOGE("Init failed[%d]", rv);
+               TETHERING_EXT_ERR("Init failed[%d]", rv);
                // TETHERING_EXT_UNLOCK;
                // __TETHERING_EXT_CAPI_FUNC_EXIT__;
                return TETHERING_ERROR_OUT_OF_MEMORY;
@@ -178,19 +91,19 @@ API int tethering_ext_initialize(tethering_ext_h *tethering_context) {
 
        rv = _tethering_ext_register_dbus(*tethering_context);
        if (rv != TETHERING_EXT_ERR_NONE && rv != TETHERING_EXT_ERR_APP_ALREADY_REGISTERED) {
-               LOGE("dbus register failed[%d]", rv);
+               TETHERING_EXT_ERR("dbus register failed[%d]", rv);
                _tethering_ext_destroy_context(*tethering_context);
                // TETHERING_EXT_UNLOCK;
                // __TETHERING_EXT_CAPI_FUNC_EXIT__;
                return TETHERING_ERROR_OPERATION_FAILED;
        }
 
-       _tethering_ext_callback_h callbacks = {__enabled_cb, NULL, __disabled_cb, NULL, __connection_state_changed_cb, NULL};
-       _tethering_ext_register_callbacks(tethering_context, callbacks);
+       // _tethering_ext_callback_h callbacks = {__enabled_cb, NULL, __disabled_cb, NULL, __connection_state_changed_cb, NULL};
+       // _tethering_ext_register_callbacks(tethering_context, callbacks);
 
        _tethering_ext_add_context(tethering_context);
 
-       LOGD("Tethering context successfully initialized");
+       TETHERING_EXT_DBG("Tethering context successfully initialized");
 
        // TETHERING_EXT_UNLOCK;
        // __TETHERING_EXT_CAPI_FUNC_EXIT__;
@@ -204,7 +117,7 @@ API int tethering_ext_deinitialize(tethering_ext_h tethering_context) {
 
        RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
 
-       LOGD("Destroy Tethering context : %p", tethering_context);
+       TETHERING_EXT_DBG("Destroy Tethering context : %p", tethering_context);
 
        _tethering_ext_remove_context(tethering_context);
        _tethering_ext_unregister_dbus(tethering_context);
@@ -213,21 +126,88 @@ API int tethering_ext_deinitialize(tethering_ext_h tethering_context) {
     return TETHERING_ERROR_NONE;
 }
 
+API int tethering_ext_set_enabled_cb(tethering_ext_h tethering_context, tethering_ext_enabled_cb callback, void *user_data) {
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
+       int rv = _tethering_ext_register_callback(tethering_context, TETHERING_EXT_ENABLED_CALLBACK, (void *) callback, user_data);
+       if (rv != TETHERING_EXT_ERR_NONE) {
+                tethering_error_e err = convert_tethering_ext_err(rv);
+                TETHERING_EXT_ERR("tethering_ext_set_enabled_cb: error value %d", err);
+                return err;
+       }
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_unset_enabled_cb(tethering_ext_h tethering_context) {
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
+       int rv = _tethering_ext_unregister_callback(tethering_context, TETHERING_EXT_ENABLED_CALLBACK);
+       if (rv != TETHERING_EXT_ERR_NONE) {
+                tethering_error_e err = convert_tethering_ext_err(rv);
+                TETHERING_EXT_ERR("tethering_ext_set_enabled_cb: error value %d", err);
+                return err;
+       }
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_set_disabled_cb(tethering_ext_h tethering_context, tethering_ext_disabled_cb callback, void *user_data) {
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
+       int rv = _tethering_ext_register_callback(tethering_context, TETHERING_EXT_DISABLED_CALLBACK, (void *) callback, user_data);
+       if (rv != TETHERING_EXT_ERR_NONE) {
+                tethering_error_e err = convert_tethering_ext_err(rv);
+                TETHERING_EXT_ERR("tethering_ext_set_disabled_cb: error value %d", err);
+                return err;
+       }
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_unset_disabled_cb(tethering_ext_h tethering_context) {
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
+       int rv = _tethering_ext_unregister_callback(tethering_context, TETHERING_EXT_DISABLED_CALLBACK);
+       if (rv != TETHERING_EXT_ERR_NONE) {
+                tethering_error_e err = convert_tethering_ext_err(rv);
+                TETHERING_EXT_ERR("tethering_ext_set_enabled_cb: error value %d", err);
+                return err;
+       }
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_set_connection_state_changed_cb(tethering_ext_h tethering_context, tethering_ext_connection_state_changed_cb callback, void *user_data) {
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
+       int rv = _tethering_ext_register_callback(tethering_context, TETHERING_EXT_CONNECTION_STATE_CHANGED_CALLBACK, (void *) callback, user_data);
+       if (rv != TETHERING_EXT_ERR_NONE) {
+                tethering_error_e err = convert_tethering_ext_err(rv);
+                TETHERING_EXT_ERR("tethering_ext_set_connection_state_changed_cb: error value %d", err);
+                return err;
+       }
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_unset_connection_state_changed_cb(tethering_ext_h tethering_context) {
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
+       int rv = _tethering_ext_unregister_callback(tethering_context, TETHERING_EXT_CONNECTION_STATE_CHANGED_CALLBACK);
+       if (rv != TETHERING_EXT_ERR_NONE) {
+                tethering_error_e err = convert_tethering_ext_err(rv);
+                TETHERING_EXT_ERR("tethering_ext_set_enabled_cb: error value %d", err);
+                return err;
+       }
+       return TETHERING_ERROR_NONE;
+}
+
+
+
 API int tethering_ext_activate(tethering_ext_h tethering_context) {
     // __TETHERING_EXT_CAPI_FUNC_ENTER__;
 
        int rv = 0;
 
        RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
-
        rv = _tethering_ext_set_wifi_tethering_mode_with_params(tethering_context, true);
        if (rv == TETHERING_EXT_ERR_ACCESS_DENIED) {
-               LOGE("Access denied");
+               TETHERING_EXT_ERR("Access denied");
                return TETHERING_ERROR_PERMISSION_DENIED;
        } else if (rv == TETHERING_EXT_ERR_INVALID_OPERATION) {
                return TETHERING_ERROR_INVALID_OPERATION;
        } else if (rv != TETHERING_EXT_ERR_NONE)  {
-               LOGE("Failed to set tethering mode");
+               TETHERING_EXT_ERR("Failed to set tethering mode");
                return TETHERING_ERROR_OPERATION_FAILED;
        }
 
@@ -241,14 +221,14 @@ API int tethering_ext_deactivate(tethering_ext_h tethering_context) {
 
        RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
 
-       rv = _tethering_ext_set_wifi_tethering_mode_with_params(tethering_context, false);
+       rv = _tethering_ext_set_wifi_tethering_mode(tethering_context, false);
        if (rv == TETHERING_EXT_ERR_ACCESS_DENIED) {
-               LOGE("Access denied");
+               TETHERING_EXT_ERR("Access denied");
                return TETHERING_ERROR_PERMISSION_DENIED;
        } else if (rv == TETHERING_EXT_ERR_INVALID_OPERATION) {
                return TETHERING_ERROR_INVALID_OPERATION;
        } else if (rv != TETHERING_EXT_ERR_NONE)  {
-               LOGE("Failed to set tethering mode");
+               TETHERING_EXT_ERR("Failed to set tethering mode");
                return TETHERING_ERROR_OPERATION_FAILED;
        }
 
@@ -263,7 +243,7 @@ API int tethering_ext_is_enabled(tethering_ext_h tethering_context, bool *is_ena
        RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(tethering_context);
 
        if (!is_enabled) {
-               LOGE("Invalid parameter");
+               TETHERING_EXT_ERR("Invalid parameter");
                // __TETHERING_EXT_CAPI_FUNC_EXIT__;
                return TETHERING_ERROR_INVALID_PARAMETER;
        }
@@ -275,53 +255,180 @@ API int tethering_ext_is_enabled(tethering_ext_h tethering_context, bool *is_ena
        return rv;
 }
 
-API int tethering_ext_set_ssid(tethering_ext_h th_context, const char *ssid) {
+API int tethering_ext_set_ssid(tethering_ext_h tethering_context, const char *ssid) {
        size_t length = strlen(ssid);
        if (length > TETHERING_EXT_WIFI_SSID_MAX_LEN) {
                return TETHERING_ERROR_INVALID_PARAMETER;
        }
-       return _tethering_ext_set_config(th_context, (void *) ssid, TETHERING_EXT_SSID);
-       return TETHERING_ERROR_NONE;
+       _tethering_ext_data_h ssid_data = {length, ssid};
+       return _tethering_ext_set_config(tethering_context, (void *) &ssid_data, TETHERING_EXT_SSID);
 }
 
-API int tethering_ext_set_passphrase(tethering_ext_h th_context, const char *passphrase) {
+API int tethering_ext_set_passphrase(tethering_ext_h tethering_context, const char *passphrase) {
        size_t length = strlen(passphrase);
        if (length > TETHERING_EXT_WIFI_KEY_MAX_LEN) {
                return TETHERING_ERROR_INVALID_PARAMETER;
        }
-       return _tethering_ext_set_config(th_context, (void *) passphrase, TETHERING_EXT_PASSPHRASE);
+       _tethering_ext_data_h passphrase_data = {length, passphrase};
+       return _tethering_ext_set_config(tethering_context, (void *) &passphrase_data, TETHERING_EXT_PASSPHRASE);
 }
 
-API int tethering_ext_set_channel(tethering_ext_h th_context, int channel) {
-       return _tethering_ext_set_config(th_context, (void *) &channel, TETHERING_EXT_CHANNEL);
+API int tethering_ext_set_channel(tethering_ext_h tethering_context, int channel) {
+       return _tethering_ext_set_config(tethering_context, (void *) &channel, TETHERING_EXT_CHANNEL);
 }
 
-API int tethering_ext_get_tethering_info(tethering_ext_h th_context, void **tethering_info) {
+API int tethering_ext_get_tethering_info(tethering_ext_h tethering_context, void *tethering_info) {
        int ret;
-       TETHERING_GET_CONFIG(th_context, *tethering_info, TETHERING_EXT_SSID | TETHERING_EXT_PASSPHRASE, ret);
+       TETHERING_GET_CONFIG(tethering_context, tethering_info, TETHERING_EXT_SSID | TETHERING_EXT_PASSPHRASE, ret);
        return ret;
 }
 
-API int tethering_ext_get_channel(tethering_ext_h th_context, int *channel) {
+API int tethering_ext_get_channel(tethering_ext_h tethering_context, int *channel) {
        int ret;
-       TETHERING_GET_CONFIG(th_context, channel, TETHERING_EXT_CHANNEL, ret);
+       TETHERING_GET_CONFIG(tethering_context, channel, TETHERING_EXT_CHANNEL, ret);
        return ret;
 }
 
-API int tethering_ext_get_security(tethering_ext_h th_context, int *security) {
+API int tethering_ext_get_security(tethering_ext_h tethering_context, int *security) {
        int ret;
-       TETHERING_GET_CONFIG(th_context, security, TETHERING_EXT_SECURITY_TYPE, ret);
+       TETHERING_GET_CONFIG(tethering_context, security, TETHERING_EXT_SECURITY_TYPE, ret);
        return ret;
 }
 
-API int tethering_ext_get_visibility(tethering_ext_h th_context, int *visibility) {
+API int tethering_ext_get_visibility(tethering_ext_h tethering_context, int *visibility) {
        int ret;
-       TETHERING_GET_CONFIG(th_context, visibility, TETHERING_EXT_VISIBLE, ret);
+       TETHERING_GET_CONFIG(tethering_context, visibility, TETHERING_EXT_VISIBLE, ret);
        return ret;
 }
 
-API int tethering_ext_get_sharing(tethering_ext_h th_context, bool *sharing) {
+API int tethering_ext_get_sharing(tethering_ext_h tethering_context, bool *sharing) {
        int ret;
-       TETHERING_GET_CONFIG(th_context, sharing, TETHERING_EXT_SHARED, ret);
+       TETHERING_GET_CONFIG(tethering_context, sharing, TETHERING_EXT_SHARED, ret);
        return ret;
 }
+
+API int tethering_ext_client_clone(tethering_ext_client_h *dest, tethering_ext_client_h origin) {
+    // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
+
+       if (dest == NULL) {
+        TETHERING_EXT_ERR("Parameter(dest) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+
+    if (origin == NULL) {
+        TETHERING_EXT_ERR("Parameter(origin) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+       _tethering_ext_client_info_h *si = NULL;
+       _tethering_ext_client_info_h *source = NULL;
+
+       source = (_tethering_ext_client_info_h *)origin;
+
+       si = malloc(sizeof(_tethering_ext_client_info_h));
+       if (si == NULL) {
+               TETHERING_EXT_ERR("malloc is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       memcpy(si, source, sizeof(_tethering_ext_client_info_h));
+       si->hostname = g_strdup(source->hostname);
+       if (si->hostname == NULL) {
+               TETHERING_EXT_ERR("malloc is failed\n");
+               free(si);
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       *dest = (tethering_ext_client_h)si;
+
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_client_get_name(tethering_ext_client_h client, char **name)
+{
+       if(client == NULL) {
+        TETHERING_EXT_ERR("Parameter(client) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+       if(name == NULL) {
+        TETHERING_EXT_ERR("Parameter(name) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+
+       _tethering_ext_client_info_h *si = (_tethering_ext_client_info_h *)client;
+
+       *name = strdup(si->hostname);
+       if (*name == NULL) {
+               TETHERING_EXT_ERR("strdup is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_client_get_ip_address(tethering_ext_client_h client, char **ip_address)
+{
+       // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
+
+       if(client == NULL) {
+        TETHERING_EXT_ERR("Parameter(client) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+       if(ip_address == NULL) {
+        TETHERING_EXT_ERR("Parameter(ip_address) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+
+       _tethering_ext_client_info_h *si = (_tethering_ext_client_info_h *)client;
+
+       *ip_address = strdup(si->ip);
+       if (*ip_address == NULL) {
+               TETHERING_EXT_ERR("strdup is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_client_get_mac_address(tethering_ext_client_h client, char **mac_address)
+{
+       // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
+
+       if(client == NULL) {
+        TETHERING_EXT_ERR("Parameter(client) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+       if(mac_address == NULL) {
+        TETHERING_EXT_ERR("Parameter(mac_address) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+
+       _tethering_ext_client_info_h *si = (_tethering_ext_client_info_h *)client;
+
+       *mac_address = strdup(si->mac);
+       if (*mac_address == NULL) {
+               TETHERING_EXT_ERR("strdup is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+API int tethering_ext_client_destroy(tethering_ext_client_h client)
+{
+       // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
+
+       if(client == NULL){
+        TETHERING_EXT_ERR("Parameter(client) is NULL\n");
+        return TETHERING_ERROR_INVALID_PARAMETER;
+    }
+
+       _tethering_ext_client_info_h *si = NULL;
+
+       si = (_tethering_ext_client_info_h *)client;
+
+       g_free(si->hostname);
+
+       free(client);
+
+       return TETHERING_ERROR_NONE;
+}
index f2e1765e194f70f5c07f44c1057b9ecbf203f202..9fd3c43432c06b85ccd49396200efebc6bee67ad 100644 (file)
@@ -8,7 +8,7 @@
 
 static int __tethering_ext_error_string_to_enum(const char *error)
 {
-    LOGD("Passed error string [%s]", error);
+    TETHERING_EXT_DBG("Passed error string [%s]", error);
 
     if (strstr(error, "NoReply"))
                return TETHERING_EXT_ERR_TIME_OUT;
@@ -69,7 +69,7 @@ GVariant *_invoke_dbus_method(_tethering_ext_h *tethering_ctx, const char *dest,
 
     if (!connection) {
         if (error) {
-            LOGE("Failed to connect to the D-BUS daemon [%s]", error->message);
+            TETHERING_EXT_ERR("Failed to connect to the D-BUS daemon [%s]", error->message);
             g_error_free(error);
         }
         return NULL;
@@ -89,11 +89,11 @@ GVariant *_invoke_dbus_method(_tethering_ext_h *tethering_ctx, const char *dest,
 
     if (!message) {
         if (error) {
-            LOGE("g_dbus_connection_call_sync() failed error [%d]: %s", error->code, error->message);
+            TETHERING_EXT_ERR("g_dbus_connection_call_sync() failed error [%d]: %s", error->code, error->message);
             *dbus_error = __tethering_ext_error_string_to_enum(error->message);
             g_error_free(error);
         } else {
-            LOGE("g_dbus_connection_call_sync() failed");
+            TETHERING_EXT_ERR("g_dbus_connection_call_sync() failed");
             *dbus_error = TETHERING_EXT_ERR_UNKNOWN;
         }
 
@@ -119,7 +119,7 @@ int _tethering_ext_dbus_set_wifi_tethering_mode(_tethering_ext_h *tethering_ctx,
     GVariant *params = NULL;
     _tethering_ext_err_e Error = TETHERING_EXT_ERR_NONE;
 
-    LOGD("_tethering_ext_dbus_set_wifi_tethering_mode() called : %s", enable ? "Enable" : "Disable");
+    TETHERING_EXT_DBG("_tethering_ext_dbus_set_wifi_tethering_mode() called : %s", enable ? "Enable" : "Disable");
 
     params = g_variant_new("(b)", enable);
 
@@ -127,7 +127,7 @@ int _tethering_ext_dbus_set_wifi_tethering_mode(_tethering_ext_h *tethering_ctx,
         TETHERING_EXT_INTERFACE_NAME, TETHERING_EXT_METHOD_SET_MODE, params, &Error);
 
     if (message == NULL) {
-        LOGE("Failed to set tethering %s", enable ? "Enable" : "Disable");
+        TETHERING_EXT_ERR("Failed to set tethering %s", enable ? "Enable" : "Disable");
         //__TETHERING_WIFI_EXT_CAPI_FUNC_EXIT__;
         return Error;
     }
@@ -146,7 +146,7 @@ int _tethering_ext_dbus_set_wifi_tethering_mode_with_params(_tethering_ext_h *te
     GVariant *params = NULL;
     _tethering_ext_err_e Error = TETHERING_EXT_ERR_NONE;
 
-    LOGD("_tethering_ext_dbus_set_wifi_tethering_mode() called : %s", enable ? "Enable" : "Disable");
+    TETHERING_EXT_DBG("_tethering_ext_dbus_set_wifi_tethering_mode() called : %s", enable ? "Enable" : "Disable");
     char *ssid = tethering_ctx->tethering_ext_config.ssid;
     char *password = tethering_ctx->tethering_ext_config.passphrase;
     int channel = tethering_ctx->tethering_ext_config.channel;
@@ -161,7 +161,7 @@ int _tethering_ext_dbus_set_wifi_tethering_mode_with_params(_tethering_ext_h *te
     }
 
     if (message == NULL) {
-        LOGE("Failed to set tethering %s", enable ? "Enable" : "Disable");
+        TETHERING_EXT_ERR("Failed to set tethering %s", enable ? "Enable" : "Disable");
         //__TETHERING_WIFI_EXT_CAPI_FUNC_EXIT__;
         return Error;
     }
@@ -180,13 +180,13 @@ int _tethering_ext_dbus_get_wifi_tethering_state(_tethering_ext_h *tethering_ctx
     _tethering_ext_err_e Error = TETHERING_EXT_ERR_NONE;
     gboolean state = 0;
 
-    LOGD("_tethering_ext_dbus_get_wifi_tethering_state() called");
+    TETHERING_EXT_DBG("_tethering_ext_dbus_get_wifi_tethering_state() called");
 
     message = _invoke_dbus_method(tethering_ctx, TETHERING_EXT_BUS_NAME, TETHERING_EXT_OBJECT_PATH,
         TETHERING_EXT_INTERFACE_NAME, TETHERING_EXT_METHOD_GET_MODE, NULL, &Error);
 
     if (message == NULL) {
-        LOGE("Failed to get tethering state");
+        TETHERING_EXT_ERR("Failed to get tethering state");
         //__TETHERING_WIFI_EXT_CAPI_FUNC_EXIT__;
         return Error;
     }
@@ -198,7 +198,7 @@ int _tethering_ext_dbus_get_wifi_tethering_state(_tethering_ext_h *tethering_ctx
     else
         *tethering_state = TETHERING_EXT_STATE_DISABLED;
 
-    LOGD("Tethering mode state : %d", *tethering_state);
+    TETHERING_EXT_DBG("Tethering mode state : %d", *tethering_state);
 
     g_variant_unref(message);
 
@@ -213,20 +213,20 @@ int _tethering_ext_dbus_get_wifi_tethering_info(_tethering_ext_h *tethering_ctx,
     GVariant *message = NULL;
     _tethering_ext_err_e Error = TETHERING_EXT_ERR_NONE;
 
-    LOGD("_tethering_ext_dbus_get_wifi_tethering_info() called");
+    TETHERING_EXT_DBG("_tethering_ext_dbus_get_wifi_tethering_info() called");
 
     message = _invoke_dbus_method(tethering_ctx, TETHERING_EXT_BUS_NAME, TETHERING_EXT_OBJECT_PATH,
         TETHERING_EXT_INTERFACE_NAME, TETHERING_EXT_METHOD_GET_INFO, NULL, &Error);
 
     if (message == NULL) {
-        LOGE("Failed to get tethering info");
+        TETHERING_EXT_ERR("Failed to get tethering info");
         //__TETHERING_WIFI_EXT_CAPI_FUNC_EXIT__;
         return Error;
     }
 
     g_variant_get(message, "(ss)", &tethering_info->tethering_ssid, &tethering_info->tethering_password);
 
-    LOGD("Tethering info : ssid[%s] password[%s]", tethering_info->tethering_ssid, tethering_info->tethering_password);
+    TETHERING_EXT_DBG("Tethering info : ssid[%s] password[%s]", tethering_info->tethering_ssid, tethering_info->tethering_password);
 
     g_variant_unref(message);
 
index fa9eecdba1e73f29495aa1bbdeb647d03e1dad29..1eaf3b521b9c36b24ab0c40fc4577f21420450e2 100644 (file)
@@ -26,13 +26,15 @@ int _tethering_ext_create_context(tethering_ext_h *tethering_context)
 {
     _tethering_ext_h *tethering_ctx = g_try_malloc0(sizeof(_tethering_ext_h));
     if (!tethering_ctx) {
-        LOGE("Failed to create tethering_ctx  : %d", TETHERING_ERROR_OUT_OF_MEMORY);
+        TETHERING_EXT_ERR("Failed to create tethering_ctx  : %d", TETHERING_ERROR_OUT_OF_MEMORY);
         return TETHERING_ERROR_OUT_OF_MEMORY;
     }
     tethering_ctx->tethering_ext_callbacks = g_try_malloc0(sizeof(_tethering_ext_callback_h));
+    memset(tethering_ctx->tethering_ext_config.ssid, 0, TETHERING_EXT_WIFI_SSID_MAX_LEN + 1);
+    memset(tethering_ctx->tethering_ext_config.passphrase, 0, TETHERING_EXT_WIFI_KEY_MAX_LEN + 1);
     *tethering_context = tethering_ctx;
 
-    LOGD("New tethering_ctx create[%p]", *tethering_context);
+    TETHERING_EXT_DBG("New tethering_ctx create[%p]", *tethering_context);
 
     return TETHERING_EXT_ERR_NONE;
 }
@@ -86,17 +88,17 @@ static void __wifi_tethering_mode_on_off_cb(_tethering_ext_h *tethering_ctx,
     if (event_cb->Error == TETHERING_EXT_ERR_NONE &&
         event_cb->Datalength == sizeof(_tethering_ext_state_e)) {
         if (*tethering_state == TETHERING_EXT_STATE_ENABLED) {
-            LOGD("Tethering mode is enabled");
+            TETHERING_EXT_DBG("Tethering mode is enabled");
             state = TETHERING_EXT_STATE_ENABLED;
         } else if (*tethering_state == TETHERING_EXT_STATE_DISABLED) {
-            LOGD("Tethering mode is disabled");
+            TETHERING_EXT_DBG("Tethering mode is disabled");
             state = TETHERING_EXT_STATE_DISABLED;
         } else {
-            LOGE("Error Tethering state %d", *tethering_state);
+            TETHERING_EXT_ERR("Error Tethering state %d", *tethering_state);
             error_code = TETHERING_ERROR_OPERATION_FAILED;
         }
     } else {
-        LOGE("Tethering power request failed(%d)", event_cb->Error);
+        TETHERING_EXT_ERR("Tethering power request failed(%d)", event_cb->Error);
         error_code = TETHERING_ERROR_OPERATION_FAILED;
         state = TETHERING_EXT_STATE_DISABLED;
     }
@@ -113,7 +115,7 @@ static void __tethering_ext_evt_cb(_tethering_ext_event_info_h *event_cb, void *
     _tethering_ext_h *tethering_ctx = (_tethering_ext_h *)user_data;
 
     if (!_tethering_ext_check_context(tethering_ctx)) {
-        LOGE("WiFi Extension context is not initialized");
+        TETHERING_EXT_ERR("WiFi Extension context is not initialized");
         // TETHERING_EXT_UNLOCK;
         return;
     }
@@ -144,7 +146,7 @@ static int __tethering_ext_mode_changed(_tethering_ext_h *tethering_ctx, GVarian
         return TETHERING_EXT_ERR_OUT_OF_MEMORY;
     }
 
-    LOGD("Tethering mode changed to %s", value ? "enabled" : "disabled");
+    TETHERING_EXT_DBG("Tethering mode changed to %s", value ? "enabled" : "disabled");
 
     event_data->Event = TETHERING_EXT_POWER_IND;
     event_data->Error = TETHERING_EXT_ERR_NONE;
@@ -163,7 +165,7 @@ static int __tethering_ext_mode_changed(_tethering_ext_h *tethering_ctx, GVarian
 
 static int __tethering_ext_enabled_callback(_tethering_ext_h *tethering_ctx, GVariant *param) {
     gboolean is_enabled = FALSE;
-    g_variant_get(param, "(bi)", &is_enabled);
+    g_variant_get(param, "(b)", &is_enabled);
 
     if (! is_enabled) {
         return TETHERING_EXT_ERR_INVALID_PARAM;
@@ -208,12 +210,12 @@ static int __tethering_ext_connection_state_callback(_tethering_ext_h *tethering
        } else if (!g_strcmp0(buf, "DhcpLeaseDeleted")) {
                opened = false;
        } else {
-               LOGE("Unknown event [%s]\n", buf);
+               TETHERING_EXT_ERR("Unknown event [%s]\n", buf);
         ret = TETHERING_ERROR_INVALID_PARAMETER;
                goto DONE;
        }
 
-    LOGI("P2P tethering type %s, ip %s, mac %s, name %s, timestamp %d",
+    TETHERING_EXT_INFO("P2P tethering type %s, ip %s, mac %s, name %s, timestamp %d",
         buf, ip, mac, name, timestamp);
     g_strlcpy(client.ip, ip, sizeof(client.ip));
     g_strlcpy(client.mac, mac, sizeof(client.mac));
@@ -221,7 +223,7 @@ static int __tethering_ext_connection_state_callback(_tethering_ext_h *tethering
         client.hostname = g_strdup(name);
     client.tm = (time_t)timestamp;
     if (callbacks->changed_cb) {
-        callbacks->changed_cb((_tethering_ext_client_h)&client, opened, callbacks->changed_user_data);
+        callbacks->changed_cb((tethering_ext_client_h)&client, opened, callbacks->changed_user_data);
     }
 
 DONE:
@@ -246,7 +248,7 @@ static _tethering_ext_err_e __tethering_ext_dbus_create(_tethering_ext_h *tether
 
     if (!tethering_ctx->tethering_ext_client) {
         if (error) {
-            LOGE("Failed to get dbus connection [%s]", error->message);
+            TETHERING_EXT_ERR("Failed to get dbus connection [%s]", error->message);
             g_error_free(error);
         }
         return TETHERING_EXT_ERR_UNKNOWN;
@@ -274,6 +276,7 @@ static void __tethering_ext_signal_filter(GDBusConnection *conn,
                const gchar *name, const gchar *path, const gchar *interface,
                const gchar *sig, GVariant *param, gpointer user_data)
 {
+    TETHERING_EXT_DBG("Received signal %s", sig);
     // __TETHERING_EXT_CAPI_FUNC_ENTER__;
     _tethering_ext_h *tethering_ctx = (_tethering_ext_h *)user_data;
 
@@ -327,7 +330,7 @@ static int __tethering_ext_dbus_register_signal(_tethering_ext_h *tethering_ctx)
 
 
     if (tethering_ctx->subscribe_id_wifi_tethering_state == 0) {
-        LOGE("Failed to register signal, subscribe_id_wifi_tethering_state(%d)",
+        TETHERING_EXT_ERR("Failed to register signal, subscribe_id_wifi_tethering_state(%d)",
             tethering_ctx->subscribe_id_wifi_tethering_state);
         __tethering_ext_unregister_signal(tethering_ctx);
         Error = TETHERING_EXT_ERR_INVALID_OPERATION;
@@ -349,7 +352,7 @@ int _tethering_ext_register_dbus(tethering_ext_h tethering_context) {
 
     Error = __tethering_ext_dbus_register_signal(tethering_ctx);
     if (Error != TETHERING_EXT_ERR_NONE) {
-        LOGE("Failed to register DBus signal, Error(%d)", Error);
+        TETHERING_EXT_ERR("Failed to register DBus signal, Error(%d)", Error);
         __tethering_ext_close_gdbus_call(tethering_ctx);
         // __TETHERING_EXT_CAPI_FUNC_EXIT__;
         return Error;
@@ -386,7 +389,7 @@ int _tethering_ext_set_wifi_tethering_mode(tethering_ext_h tethering_context, bo
 
     Error = _tethering_ext_dbus_set_wifi_tethering_mode(tethering_ctx, enable);
     if (Error != TETHERING_EXT_ERR_NONE)
-        LOGE("Failed to set tethering mode(%d), Error[%s])",
+        TETHERING_EXT_ERR("Failed to set tethering mode(%d), Error[%s])",
                 enable, tethering_ext_err_to_str(Error));
 
     // __TETHERING_EXT_CAPI_FUNC_EXIT__;
@@ -402,7 +405,7 @@ int _tethering_ext_set_wifi_tethering_mode_with_params(tethering_ext_h tethering
 
     Error = _tethering_ext_dbus_set_wifi_tethering_mode_with_params(tethering_ctx, enable);
     if (Error != TETHERING_EXT_ERR_NONE)
-        LOGE("Failed to set tethering mode(%d), Error[%s])",
+        TETHERING_EXT_ERR("Failed to set tethering mode(%d), Error[%s])",
                 enable, tethering_ext_err_to_str(Error));
 
     // __TETHERING_EXT_CAPI_FUNC_EXIT__;
@@ -411,14 +414,14 @@ int _tethering_ext_set_wifi_tethering_mode_with_params(tethering_ext_h tethering
 
 
 int _tethering_ext_get_wifi_tethering_mode(tethering_ext_h tethering_context, bool *is_enabled) {
-    // __TETHERING_EXT_CAPI_FUNC_ENTER__;    
+    // __TETHERING_EXT_CAPI_FUNC_ENTER__;
     _tethering_ext_h *tethering_ctx = (_tethering_ext_h *) tethering_context;
     _tethering_ext_err_e Error = TETHERING_EXT_ERR_NONE;
     _tethering_ext_state_e tethering_state = TETHERING_EXT_STATE_DISABLED;
 
     Error = _tethering_ext_dbus_get_wifi_tethering_state(tethering_ctx, &tethering_state);
     if (Error != TETHERING_EXT_ERR_NONE)
-        LOGE("Failed to get tethering state [%s]", tethering_ext_err_to_str(Error));
+        TETHERING_EXT_ERR("Failed to get tethering state [%s]", tethering_ext_err_to_str(Error));
     else {
         if (tethering_state == TETHERING_EXT_STATE_ENABLED) {
             *is_enabled = true;
@@ -437,27 +440,37 @@ int _tethering_ext_set_config(tethering_ext_h tethering_context, void *src_confi
     tethering_ext_config_h *target_config = &(tethering_ctx->tethering_ext_config);
 
     switch (type) {
-        case TETHERING_EXT_SSID | TETHERING_EXT_PASSPHRASE:
+        case TETHERING_EXT_SSID:
         {
-            const char *ssid = (const char *) src_config;
-            size_t length = sizeof(ssid);
-            strncpy(target_config->ssid, ssid, length);
-            target_config->ssid[length + 1] = 0;
+            _tethering_ext_data_h *ssid_data = (_tethering_ext_data_h *) src_config;
+            const char *ssid = ssid_data->Data;
+            if ((ssid_data->DataLength < TETHERING_EXT_WIFI_SSID_MIN_LEN) ||
+                    (ssid_data->DataLength > TETHERING_EXT_WIFI_SSID_MAX_LEN)) {
+                TETHERING_EXT_ERR("Invalid SSID of length %d", ssid_data->DataLength);
+                return TETHERING_EXT_ERR_INVALID_PARAM;
+            }
+            strncpy(target_config->ssid, ssid, ssid_data->DataLength);
+            target_config->ssid[ssid_data->DataLength + 1] = 0;
             break;
         }
         case TETHERING_EXT_PASSPHRASE:
         {
-            const char *passphrase = (const char *) src_config;
-            size_t length = sizeof(passphrase);
-            strncpy(target_config->passphrase, passphrase, length);
-            target_config->passphrase[length + 1] = 0;
+            _tethering_ext_data_h *passphrase_data = (_tethering_ext_data_h *) src_config;
+            const char *passphrase = passphrase_data->Data;
+            if ((passphrase_data->DataLength < TETHERING_EXT_WIFI_KEY_MIN_LEN) ||
+                    (passphrase_data->DataLength > TETHERING_EXT_WIFI_KEY_MAX_LEN)) {
+                TETHERING_EXT_ERR("Invalid passphrase of length %d", passphrase_data->DataLength);
+                return TETHERING_EXT_ERR_INVALID_PARAM;
+            }
+            strncpy(target_config->passphrase, passphrase, passphrase_data->DataLength);
+            target_config->passphrase[passphrase_data->DataLength + 1] = 0;
             break;
         }
         case TETHERING_EXT_CHANNEL:
             target_config->channel = *((int *) src_config);
             break;
         default:
-            LOGE("Unknown type %d", type);
+            TETHERING_EXT_ERR("Unknown type %d", type);
             Error = TETHERING_ERROR_INVALID_PARAMETER;
             break;
     }
@@ -465,27 +478,23 @@ int _tethering_ext_set_config(tethering_ext_h tethering_context, void *src_confi
 }
 
 int _tethering_ext_get_config(tethering_ext_h tethering_context, void *target_config, int type) {
-    int Error = TETHERING_EXT_ERR_NONE;
+    if (! target_config) {
+        return TETHERING_EXT_ERR_INVALID_PARAM;
+    }
     _tethering_ext_h *tethering_ctx = (_tethering_ext_h *) tethering_context;
     tethering_ext_config_h *src_config = &(tethering_ctx->tethering_ext_config);
     switch (type) {
         case TETHERING_EXT_SSID | TETHERING_EXT_PASSPHRASE:
         {
             _tethering_ext_tethering_info *t_info = (_tethering_ext_tethering_info *) target_config;
-            size_t ssid_length = strlen(src_config->ssid);
-            memcpy(t_info->tethering_ssid, src_config->ssid, ssid_length);
-            t_info->tethering_ssid[ssid_length + 1] = 0;
-            break;
-            size_t passphrase_length = strlen(src_config->passphrase);
-            memcpy(t_info->tethering_password, src_config->passphrase, passphrase_length);
-            t_info->tethering_password[passphrase_length + 1] = 0;
+            _tethering_ext_dbus_get_wifi_tethering_info(tethering_ctx, t_info);
             break;
         }
         case TETHERING_EXT_SECURITY_TYPE:
         {
             int *security_type = (int *) target_config;
             if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, security_type) < 0) {
-                LOGE("vconf_get_int is failed\n");
+                TETHERING_EXT_ERR("vconf_get_int is failed\n");
                 return TETHERING_EXT_ERR_OPERATION_FAILED;
             }
             break;
@@ -498,7 +507,7 @@ int _tethering_ext_get_config(tethering_ext_h tethering_context, void *target_co
             int hide = 0;
             bool *visible = (bool *) target_config;
             if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, &hide) < 0) {
-                LOGE("vconf_get_int is failed\n");
+                TETHERING_EXT_ERR("vconf_get_int is failed\n");
                 return TETHERING_EXT_ERR_OPERATION_FAILED;
             }
 
@@ -509,148 +518,69 @@ int _tethering_ext_get_config(tethering_ext_h tethering_context, void *target_co
             break;
         }
     }
-    return Error;
-}
-
-int _tethering_ext_client_clone(_tethering_ext_client_h *dest, _tethering_ext_client_h origin) {
-    // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
-
-       if (dest == NULL) {
-        LOGE("Parameter(dest) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
-    } 
-       
-    if (origin == NULL) {
-        LOGE("Parameter(origin) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
-    }
-               
-
-       _tethering_ext_client_info_h *si = NULL;
-       _tethering_ext_client_info_h *source = NULL;
-
-       source = (_tethering_ext_client_info_h *)origin;
-
-       si = malloc(sizeof(_tethering_ext_client_info_h));
-       if (si == NULL) {
-               LOGE("malloc is failed\n");
-               return TETHERING_EXT_ERR_OUT_OF_MEMORY;
-       }
-
-       memcpy(si, source, sizeof(_tethering_ext_client_info_h));
-       si->hostname = g_strdup(source->hostname);
-       if (si->hostname == NULL) {
-               LOGE("malloc is failed\n");
-               free(si);
-               return TETHERING_EXT_ERR_OUT_OF_MEMORY;
-       }
-
-       *dest = (_tethering_ext_client_h)si;
-
-       return TETHERING_EXT_ERR_NONE;
+    return TETHERING_EXT_ERR_NONE;
 }
 
-int _tethering_ext_client_get_name(_tethering_ext_client_h client, char **name)
-{
-       if(client == NULL) {
-        LOGE("Parameter(client) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
-    }
-       if(name == NULL) {
-        LOGE("Parameter(name) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
+int _tethering_ext_register_callback(tethering_ext_h tethering_context, _tethering_ext_callback_e cb_type, void *callback, void *data) {
+    _tethering_ext_h *tethering_ctx = (_tethering_ext_h *)tethering_context;
+    _tethering_ext_err_e error = TETHERING_EXT_ERR_NONE;
+    if (! tethering_ctx->tethering_ext_callbacks)
+    {
+        TETHERING_EXT_ERR("Callbacks not initialized");
+        return TETHERING_EXT_ERR_OPERATION_FAILED;
     }
+    switch (cb_type) {
+        case TETHERING_EXT_ENABLED_CALLBACK:
+            tethering_ctx->tethering_ext_callbacks->enabled_cb = (tethering_ext_enabled_cb) callback;
+            tethering_ctx->tethering_ext_callbacks->enabled_user_data = data;
+        break;
 
-       _tethering_ext_client_info_h *si = (_tethering_ext_client_info_h *)client;
-
-       *name = strdup(si->hostname);
-       if (*name == NULL) {
-               LOGE("strdup is failed\n");
-               return TETHERING_EXT_ERR_OUT_OF_MEMORY;
-       }
-
-       return TETHERING_EXT_ERR_NONE;
-}
+        case TETHERING_EXT_DISABLED_CALLBACK:
+            tethering_ctx->tethering_ext_callbacks->disabled_cb = (tethering_ext_disabled_cb) callback;
+            tethering_ctx->tethering_ext_callbacks->disabled_user_data = data;
+        break;
 
-int _tethering_ext_client_get_ip_address(_tethering_ext_client_h client, char **ip_address)
-{
-       // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
+        case TETHERING_EXT_CONNECTION_STATE_CHANGED_CALLBACK:
+            tethering_ctx->tethering_ext_callbacks->changed_cb = (tethering_ext_connection_state_changed_cb) callback;
+            tethering_ctx->tethering_ext_callbacks->changed_user_data = data;
+        break;
 
-       if(client == NULL) {
-        LOGE("Parameter(client) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
-    }
-       if(ip_address == NULL) {
-        LOGE("Parameter(ip_address) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
+        default:
+            TETHERING_EXT_ERR("Invalid callback type %d specified", (int) cb_type);
+            error = TETHERING_EXT_ERR_INVALID_PARAM;
+        break;
     }
-
-       _tethering_ext_client_info_h *si = (_tethering_ext_client_info_h *)client;
-
-       *ip_address = strdup(si->ip);
-       if (*ip_address == NULL) {
-               LOGE("strdup is failed\n");
-               return TETHERING_EXT_ERR_OUT_OF_MEMORY;
-       }
-
-       return TETHERING_EXT_ERR_NONE;
+    return error;
 }
 
-int _tethering_ext_client_get_mac_address(_tethering_ext_client_h client, char **mac_address)
-{
-       // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
-
-       if(client == NULL) {
-        LOGE("Parameter(client) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
-    }
-       if(mac_address == NULL) {
-        LOGE("Parameter(mac_address) is NULL\n");
-        return TETHERING_EXT_ERR_INVALID_PARAM;
+int _tethering_ext_unregister_callback(tethering_ext_h tethering_context, _tethering_ext_callback_e cb_type) {
+    _tethering_ext_h *tethering_ctx = (_tethering_ext_h *)tethering_context;
+    _tethering_ext_err_e error = TETHERING_EXT_ERR_NONE;
+    if (! tethering_ctx->tethering_ext_callbacks)
+    {
+        TETHERING_EXT_ERR("Callbacks not initialized");
+        return TETHERING_EXT_ERR_OPERATION_FAILED;
     }
+    switch (cb_type) {
+        case TETHERING_EXT_ENABLED_CALLBACK:
+            tethering_ctx->tethering_ext_callbacks->enabled_cb = NULL;
+            tethering_ctx->tethering_ext_callbacks->enabled_user_data = NULL;
+        break;
 
-       _tethering_ext_client_info_h *si = (_tethering_ext_client_info_h *)client;
-
-       *mac_address = strdup(si->mac);
-       if (*mac_address == NULL) {
-               LOGE("strdup is failed\n");
-               return TETHERING_EXT_ERR_OUT_OF_MEMORY;
-       }
-
-       return TETHERING_EXT_ERR_NONE;
-}
-
-int _tethering_ext_client_destroy(_tethering_ext_client_h client)
-{
-       // CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
-
-       if(client == NULL){
-        LOGE("Parameter(client) is NULL\n");  
-        return TETHERING_EXT_ERR_INVALID_PARAM;        
-    } 
-
-       _tethering_ext_client_info_h *si = NULL;
-
-       si = (_tethering_ext_client_info_h *)client;
-
-       g_free(si->hostname);
-
-       free(client);
-
-       return TETHERING_EXT_ERR_NONE;
-}
+        case TETHERING_EXT_DISABLED_CALLBACK:
+            tethering_ctx->tethering_ext_callbacks->disabled_cb = NULL;
+            tethering_ctx->tethering_ext_callbacks->disabled_user_data = NULL;
+        break;
 
+        case TETHERING_EXT_CONNECTION_STATE_CHANGED_CALLBACK:
+            tethering_ctx->tethering_ext_callbacks->changed_cb = NULL;
+            tethering_ctx->tethering_ext_callbacks->changed_user_data = NULL;
+        break;
 
-void _tethering_ext_register_callbacks(tethering_ext_h tethering_context, _tethering_ext_callback_h callbacks) {
-    _tethering_ext_h *tethering_ctx = (_tethering_ext_h *)tethering_context;
-    if (! tethering_ctx->tethering_ext_callbacks)
-    {
-        return;
+        default:
+            TETHERING_EXT_ERR("Invalid callback type %d specified", (int) cb_type);
+            error = TETHERING_EXT_ERR_INVALID_PARAM;
+        break;
     }
-    tethering_ctx->tethering_ext_callbacks->enabled_cb = callbacks.enabled_cb;
-    tethering_ctx->tethering_ext_callbacks->enabled_user_data = callbacks.enabled_user_data;
-    tethering_ctx->tethering_ext_callbacks->disabled_cb = callbacks.disabled_cb;
-    tethering_ctx->tethering_ext_callbacks->disabled_user_data = callbacks.disabled_user_data;
-    tethering_ctx->tethering_ext_callbacks->changed_cb = callbacks.changed_cb;
-    tethering_ctx->tethering_ext_callbacks->changed_user_data = callbacks.changed_user_data;
+    return error;
 }
\ No newline at end of file
diff --git a/test_application/CMakeLists.txt b/test_application/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..40fb416
--- /dev/null
@@ -0,0 +1,18 @@
+SET(fw_test "${fw_name}_ext_test")
+SET(test_executable "tethering_ext_test")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_test} REQUIRED glib-2.0 dlog)
+FOREACH(flag ${${fw_test}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+
+
+FILE(GLOB TETHERING_EXT_TEST_SRCS tethering_ext_test*.c)
+ADD_EXECUTABLE(${test_executable} ${TETHERING_EXT_TEST_SRCS})
+TARGET_LINK_LIBRARIES(${test_executable} ${fw_name} ${${fw_test}_LDFLAGS})
+SET_TARGET_PROPERTIES(${test_executable} PROPERTIES POSITION_INDEPENDENT_CODE ON)
+INSTALL(TARGETS ${test_executable} RUNTIME DESTINATION bin)
diff --git a/test_application/tethering_ext_test.c b/test_application/tethering_ext_test.c
new file mode 100644 (file)
index 0000000..5cbca93
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+* Copyright (c) 2025 Samsung Electronics Co., Ltd 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>
+#include <unistd.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include "tethering_ext_test.h"
+#include "tethering_ext_test_util.h"
+#include "tethering_ext.h"
+
+
+#define DISABLE_REASON_TEXT_LEN        64
+#define COMMON_STR_BUF_LEN     32
+
+typedef struct {
+       tethering_ext_enabled_cb enabled_cb;
+       tethering_ext_disabled_cb disabled_cb;
+       tethering_ext_connection_state_changed_cb changed_cb;
+} __tethering_ext_cbs;
+
+typedef struct {
+       char *ssid;
+       char *passphrase;
+} app_tethering_info_t;
+
+tethering_ext_h th = NULL;
+app_tethering_info_t *g_app_tethering_info = NULL;
+static GSemaphore_t g_tethering_sem;
+
+static bool __is_err(tethering_error_e ret)
+{
+       char *err_msg = NULL;
+
+       switch (ret) {
+       case TETHERING_ERROR_INVALID_PARAMETER:
+               err_msg = "Wrong parameter is used";
+               break;
+
+       case TETHERING_ERROR_OUT_OF_MEMORY:
+               err_msg = "Memory is not enough";
+               break;
+
+       case TETHERING_ERROR_NONE:
+               return false;
+
+       case TETHERING_ERROR_NOT_ENABLED:
+               err_msg = "Tethering is not enabled";
+               break;
+
+       case TETHERING_ERROR_OPERATION_FAILED:
+               err_msg = "Operation is failed";
+               break;
+
+       case TETHERING_ERROR_RESOURCE_BUSY:
+               err_msg = "Resource is busy";
+               break;
+
+       case TETHERING_ERROR_NOT_PERMITTED:
+               err_msg = "Operation is not permitted";
+               break;
+
+       case TETHERING_ERROR_NOT_SUPPORT_API:
+               err_msg = "Not supported";
+               break;
+
+       default:
+               err_msg = "This should not be happened";
+               break;
+       }
+
+       g_print("##ERR: %s\n", err_msg);
+
+       return true;
+}
+
+static bool test_get_user_string(const char *msg, char *buf, int buf_size)
+{
+       if (msg == NULL || buf == NULL || buf_size < 2)
+               return false;
+
+       int rv;
+       g_print("%s\n", msg);
+       memset(buf, 0, buf_size);
+       rv = read(0, buf, buf_size - 1);
+
+       if (rv < 0 || buf[0] == '\0' || buf[0] == '\n' || buf[0] == '\r') {
+               buf[0] = '\0';
+               return false;
+       }
+
+       buf[rv-1] = '\0';
+       return true;
+}
+
+static const char *__convert_disabled_code_to_str(const tethering_ext_disabled_cause_e code)
+{
+       static char str_buf[DISABLE_REASON_TEXT_LEN] = {0, };
+
+       switch (code) {
+       case TETHERING_EXT_DISABLED_BY_FLIGHT_MODE:
+               strncpy(str_buf, "disabled due to flight mode on", sizeof(str_buf));
+               break;
+
+       case TETHERING_EXT_DISABLED_BY_LOW_BATTERY:
+               strncpy(str_buf, "disabled due to low battery", sizeof(str_buf));
+               break;
+
+       case TETHERING_EXT_DISABLED_BY_NETWORK_CLOSE:
+               strncpy(str_buf, "disabled due to pdp network close", sizeof(str_buf));
+               break;
+
+       case TETHERING_EXT_DISABLED_BY_TIMEOUT:
+               strncpy(str_buf, "disabled due to timeout", sizeof(str_buf));
+               break;
+
+       case TETHERING_EXT_DISABLED_BY_OTHERS:
+               strncpy(str_buf, "disabled by other apps", sizeof(str_buf));
+               break;
+
+       case TETHERING_EXT_DISABLED_BY_REQUEST:
+               strncpy(str_buf, "disabled by my request", sizeof(str_buf));
+               break;
+
+       case TETHERING_EXT_DISABLED_BY_WIFI_ON:
+               strncpy(str_buf, "disabled by Wi-Fi station on", sizeof(str_buf));
+               break;
+
+       default:
+               strncpy(str_buf, "disabled by unknown reason", sizeof(str_buf));
+               break;
+       }
+
+       return str_buf;
+}
+
+static void __register_cbs(tethering_ext_h th, __tethering_ext_cbs *cbs, void *user_data)
+{
+       tethering_error_e ret = TETHERING_ERROR_NONE;
+
+       ret = tethering_ext_set_enabled_cb(th, cbs->enabled_cb, user_data);
+       if (__is_err(ret) == true)
+               g_print("tethering_ext_set_enabled_cb is failed\n");
+
+       ret = tethering_ext_set_disabled_cb(th, cbs->disabled_cb, user_data);
+       if (__is_err(ret) == true)
+               g_print("tethering_ext_set_disabled_cb is failed\n");
+
+       ret = tethering_ext_set_connection_state_changed_cb(th, cbs->changed_cb, user_data);
+       if (__is_err(ret) == true)
+               g_print("tethering_ext_set_connection_state_changed_cb is failed\n");
+
+       return;
+}
+
+static void __deregister_cbs(tethering_ext_h th)
+{
+       tethering_error_e ret = TETHERING_ERROR_NONE;
+
+       ret = tethering_ext_unset_enabled_cb(th);
+       if (__is_err(ret) == true)
+               g_print("tethering_ext_unset_enabled_cb is failed\n");
+
+       ret = tethering_ext_unset_disabled_cb(th);
+       if (__is_err(ret) == true)
+               g_print("tethering_uext_nset_disabled_cb is failed\n");
+
+       ret = tethering_ext_unset_connection_state_changed_cb(th);
+       if (__is_err(ret) == true)
+               g_print("tethering_ext_unset_connection_state_changed_cb is failed\n");
+
+       return;
+}
+
+static const char *tethering_state_str(tethering_state_e state) {
+    const char *retval;
+    switch (state) {
+        case TETHERING_STATE_IDLE:
+            retval = "IDLE";
+            break;
+        case TETHERING_STATE_ACTIVATING:
+            retval = "ACTIVATING";
+            break;
+        case TETHERING_STATE_ACTIVATED:
+            retval = "ACTIVATED";
+            break;
+        case TETHERING_STATE_DEACTIVATING:
+            retval = "DEACTIVATING";
+            break;
+        case TETHERING_STATE_DEACTIVATED:
+            retval = "DEACTIVATED";
+            break;
+        default:
+            retval  = "UNKNOWN";
+            break;
+    }
+    return retval;
+}
+
+
+/* Tethering callbacks */
+static void __enabled_cb(tethering_error_e result, bool is_requested, void *user_data)
+{
+       if (result != TETHERING_ERROR_NONE) {
+               if (!is_requested) {
+            TETHERING_EXT_DBG("P2P Tethering failed (not requested)\n");
+                       GSemaphore_post(&g_tethering_sem);
+                       return;
+        }
+
+               TETHERING_EXT_DBG("P2P Tethering is not enabled. error code[0x%X]\n", result);
+               GSemaphore_post(&g_tethering_sem);
+               return;
+       }
+
+       if (is_requested)
+               TETHERING_EXT_DBG("P2P Tethering is enabled successfully\n");
+       else
+               TETHERING_EXT_DBG("P2P Tethering is enabled by other app\n");
+       GSemaphore_update(&g_tethering_sem, TETHERING_STATE_ACTIVATED);
+       GSemaphore_post(&g_tethering_sem);
+}
+
+static void __disabled_cb(tethering_error_e result, tethering_ext_disabled_cause_e cause, void *user_data)
+{
+       if (result != TETHERING_ERROR_NONE) {
+               if (cause != TETHERING_EXT_DISABLED_BY_REQUEST) {
+                       GSemaphore_post(&g_tethering_sem);
+                       return;
+               }
+               g_print("P2P Tethering is not disabled. error code[0x%X]\n", result);
+               GSemaphore_post(&g_tethering_sem);
+               return;
+       }
+       GSemaphore_update(&g_tethering_sem, TETHERING_STATE_DEACTIVATED);
+    TETHERING_EXT_DBG("P2P Tethering is %s\n", __convert_disabled_code_to_str(cause));
+       GSemaphore_post(&g_tethering_sem);
+}
+
+static void __connection_state_changed_cb(tethering_ext_client_h client, bool open, void *user_data)
+{
+       tethering_ext_client_h clone = NULL;
+       // tethering_type_e type;
+       char *ip_address = NULL;
+       char *mac_address = NULL;
+       char *hostname = NULL;
+
+       tethering_ext_client_clone(&clone, client);
+       if (clone == NULL) {
+               g_print("tetheirng_client_clone is failed\n");
+               return;
+       }
+
+       tethering_ext_client_get_ip_address(clone, &ip_address);
+       tethering_ext_client_get_mac_address(clone, &mac_address);
+       tethering_ext_client_get_name(clone, &hostname);
+
+       if (open) {
+               g_print("## New station Type [P2P Tethering], IP [%s], MAC [%s], hostname [%s]\n",
+                               ip_address, mac_address, hostname);
+       } else {
+               g_print("## Disconnected station Type [P2P Tethering], IP [%s], MAC [%s], hostname [%s]\n",
+                               ip_address, mac_address, hostname);
+       }
+
+       if (ip_address)
+               free(ip_address);
+       if (mac_address)
+               free(mac_address);
+       if (hostname)
+               free(hostname);
+
+       tethering_ext_client_destroy(clone);
+
+       return;
+}
+/* End of tethering callbacks */
+
+int test_tethering_ext_initialize(void)
+{
+       int ret = tethering_ext_initialize(&th);
+       __tethering_ext_cbs cbs = {
+               __enabled_cb, __disabled_cb,
+               __connection_state_changed_cb};
+
+       if (__is_err(ret) == false) {
+               __register_cbs(th, &cbs, NULL);
+       } else {
+               g_print("Tethering extension initialize is failed\n");
+               return -1;
+       }
+    if (GSemaphore_init(&g_tethering_sem) < 0) {
+        g_print("Tethering extension initialize: GSemaphore_init failed\n");
+        return -1;
+    }
+       g_print("Tethering extension initialize and register callback success\n");
+       return 1;
+}
+
+int test_tethering_ext_deinitialize(void)
+{
+       tethering_state_e state;
+       GSemaphore_get_state(&g_tethering_sem, &state);
+       // Deinitialize only if idle or deactivated, wait otherwise
+       if ((state == TETHERING_STATE_DEACTIVATING) || (state == TETHERING_STATE_ACTIVATING)) {
+               g_print("test_tethering_ext_deinitialize error: Tethering in state %s\n", tethering_state_str(state));
+               return -1;
+       } else {
+               int ret = TETHERING_ERROR_NONE;
+               __deregister_cbs(th);
+
+               ret = tethering_ext_deinitialize(th);
+               if (__is_err(ret) == true) {
+                       g_print("Tethering deinitialize is failed\n");
+                       return -1;
+               }
+               th = NULL;
+               GSemaphore_update(&g_tethering_sem, TETHERING_STATE_IDLE);
+               if (GSemaphore_destroy(&g_tethering_sem) < 0) {
+                       g_print("Tethering extension initialize: GSemaphore_destroy failed\n");
+                       return -1;
+               }
+       }
+
+       return 1;
+}
+
+int test_tethering_ext_get_tethering_info() {
+       int ret = TETHERING_ERROR_NONE;
+       int rv = 1;
+       g_app_tethering_info = (app_tethering_info_t *) malloc(sizeof(app_tethering_info_t));
+       ret = tethering_ext_get_tethering_info(th, (void *) g_app_tethering_info);
+       if (ret != TETHERING_ERROR_NONE) {
+               g_print("Fail to get tethering ext info\n");
+               rv = -1;
+       }
+       if (g_app_tethering_info) {
+               g_print("Tethering info:\tssid: %s\nTethering info:\tpassphrase: %s\n", g_app_tethering_info->ssid, g_app_tethering_info->passphrase);
+               free(g_app_tethering_info);
+               g_app_tethering_info = NULL;
+       }
+
+       return rv;
+}
+
+int test_tethering_ext_activate(void)
+{
+       tethering_state_e state;
+       GSemaphore_get_state(&g_tethering_sem, &state);
+       if (state == TETHERING_STATE_ACTIVATING) {
+               g_print("Tethering ext activation already in progress\n");
+               return -1;
+       } else if (state == TETHERING_STATE_ACTIVATED) {
+               g_print("Tethering ext already activated\n");
+       } else if (state == TETHERING_STATE_DEACTIVATING) {
+               g_print("Tethering ext deactivation currently in progress\n");
+               return -1;
+       } else {
+               int ret;
+               ret = tethering_ext_activate(th);
+               if (ret != TETHERING_ERROR_NONE) {
+                       g_print("Tethering ext activation failed\n");
+                       return -1;
+               }
+               GSemaphore_update(&g_tethering_sem, TETHERING_STATE_ACTIVATING);
+               GSemaphore_wait(&g_tethering_sem);
+               GSemaphore_update(&g_tethering_sem, TETHERING_STATE_ACTIVATED);
+               TETHERING_EXT_DBG("Tethering activation succeeded\n");
+       }
+       return 1;
+}
+
+int test_tethering_ext_deactivate(void)
+{
+       tethering_state_e state;
+       GSemaphore_get_state(&g_tethering_sem, &state);
+       if (state == TETHERING_STATE_DEACTIVATING) {
+               g_print("Tethering ext deactivation already in progress\n");
+               return -1;
+       } else if(state == TETHERING_STATE_DEACTIVATED) {
+               g_print("Tethering ext already deactivated\n");
+       } else if (state == TETHERING_STATE_ACTIVATING) {
+               g_print("Tethering ext activation currently in progress\n");
+               return -1;
+       } else {
+               int ret;
+               ret = tethering_ext_deactivate(th);
+               if (ret != TETHERING_ERROR_NONE) {
+                       g_print("Tethering ext deactivation failed\n");
+                       return -1;
+               }
+               GSemaphore_update(&g_tethering_sem, TETHERING_STATE_DEACTIVATING);
+               GSemaphore_wait(&g_tethering_sem);
+               GSemaphore_update(&g_tethering_sem, TETHERING_STATE_DEACTIVATED);
+               TETHERING_EXT_DBG("Tethering deactivation succeeded\n");
+       }
+       return 1;
+}
+
+int test_tethering_ext_wifi_set_ssid(void)
+{
+       int ret;
+       char ssid[100] = {0, };
+
+       if (test_get_user_string("Input SSID for Wi-Fi tethering:",
+                               ssid, 100) == false) {
+               g_print("Failed to read user input!!\n");
+               return -1;
+       }
+
+       ret = tethering_ext_set_ssid(th, ssid);
+       if (__is_err(ret) == true) {
+               g_print("Fail to set wifi ssid!!\n");
+               return -1;
+       }
+
+       return 1;
+}
+
+int test_tethering_ext_wifi_set_passphrase(void)
+{
+       int ret;
+       char passphrase[100] = {0, };
+
+       if (test_get_user_string("Input passphrase for Wi-Fi tethering:",
+                               passphrase, 100) == false) {
+               g_print("Failed to read user input!!\n");
+               return -1;
+       }
+
+       ret = tethering_ext_set_passphrase(th, passphrase);
+       if (__is_err(ret) == true) {
+               g_print("Fail to set passphrase!!\n");
+               return -1;
+       }
+
+       return 1;
+}
+
+int test_tethering_ext_wifi_set_channel(void)
+{
+       int ret;
+       int channel;
+
+       g_print("Input channel for Wi-Fi tethering: ");
+       ret = scanf("%d", &channel);
+
+       ret = tethering_ext_set_channel(th, channel);
+       if (__is_err(ret) == true) {
+               g_print("Fail to set channel!!\n");
+               return -1;
+       }
+
+       return 1;
+}
+
diff --git a/test_application/tethering_ext_test.h b/test_application/tethering_ext_test.h
new file mode 100644 (file)
index 0000000..ed63746
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __TETHERING_EXT_TEST_H_
+#define __TETHERING_EXT_TEST_H_
+int test_tethering_ext_initialize(void);
+int test_tethering_ext_deinitialize(void);
+int test_tethering_ext_get_tethering_info(void);
+int test_tethering_ext_activate(void);
+int test_tethering_ext_deactivate(void);
+int test_tethering_ext_wifi_set_ssid(void);
+int test_tethering_ext_wifi_set_passphrase(void);
+int test_tethering_ext_wifi_set_channel(void);
+#endif // #ifndef __TETHERING_EXT_TEST_H_
diff --git a/test_application/tethering_ext_test_main.c b/test_application/tethering_ext_test_main.c
new file mode 100755 (executable)
index 0000000..4cfc561
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+* Copyright (c) 2025 Samsung Electronics Co., Ltd 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>
+#include <unistd.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <stdbool.h>
+#include "tethering_ext_test.h"
+#include "tethering_ext_test_scenario.h"
+
+GIOChannel *g_channel = NULL;
+gboolean g_verification = FALSE;
+
+#define TETHERING_EXT_VERIFY(scenario_fn, failed, total) \
+       do { \
+               int ret = scenario_fn();\
+               printf("%s", #scenario_fn);\
+               if (ret < 0) { \
+                       printf("FAIL\n");\
+                       failed++;\
+               } else { \
+                       printf("PASS\n");\
+               } \
+               total++;\
+       } while (0)
+
+gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data);
+
+int test_tethering_ext_verification(char *data)
+{
+       // Disable test_thread processing
+       g_verification = TRUE;
+    printf("[%s] Entry =>\n", __FUNCTION__);
+    int rv;
+       char *saveptr = NULL;
+       char *options = strtok_r(data, "\n", &saveptr);
+       if (options == NULL) {
+               options = data;
+       }
+
+       if (OPTION_MATCHES(options, "e") || OPTION_MATCHES(options, "f")) {
+               printf("\n\n Tethering Ext Verification\n\n");
+               printf("Options..\n");
+               printf("\"e1\"       - Verify Tethering Ext Enable\n");
+               printf("\"e2\"       - Verify Tethering Ext Enable (AP disconnected, WiFi Direct off)\n");
+               printf("\"e3\"       - Verify Tethering Ext Enable (AP disconnected, WiFi Direct on)\n");
+               printf("\"e4\"       - Verify Tethering Ext Enable (WiFi Disabled)\n");
+               printf("\"f1\"       - Verify Tethering Ext Enable (AP connected in 2.4GHz band)\n");
+               printf("\"f2\"       - Verify Tethering Ext Enable (AP connected in 5GHz band)\n");
+               printf("\"e\"|\"f\"  - Show verifications options.......\n");
+               rv =  1;
+       } else if (OPTION_MATCHES(options, "e1")) {
+               rv = tethering_ext_verify_enable_default();
+       } else if (OPTION_MATCHES(options, "e2")) {
+               rv = tethering_ext_verify_enable_ap_disconnected_wifi_direct_on();
+       } else if (OPTION_MATCHES(options, "e3")) {
+               rv = tethering_ext_verify_enable_ap_disconnected_wifi_direct_off();
+       } else if (OPTION_MATCHES(options, "e4")) {
+               rv = tethering_ext_verify_enable_ap_disconnected_wifi_off();
+       } else if (OPTION_MATCHES(options, "f1")) {
+               rv = tethering_ext_verify_enable_freq_band_lower();
+       } else if (OPTION_MATCHES(options, "f2")) {
+               rv = tethering_ext_verify_enable_freq_band_higher();
+       } else {
+               printf("Invalid option %s\n", options);
+               rv = -1;
+       }
+       printf("[%s] Exit <=", __FUNCTION__);
+       // Restore test_thread processing
+       g_verification = FALSE;
+       return rv;
+}
+
+gboolean input_handle_fn(gpointer data)
+{
+       int rv;
+       char *a = (char *) data;
+
+       if (a[0] == '0') {
+               g_free(a);
+               exit(1);
+       }
+
+       if (a[0] == '\n' || a[0] == '\r') {
+               printf("\n\n Network Connection API Test App\n\n");
+               printf("Options..\n");
+               printf("1       - Tethering Ext Initialize and set callbacks\n");
+               printf("2       - Tethering Ext Deinitialize and unset callbacks\n");
+               printf("s       - Set Wi-Fi tethering SSID\n");
+               printf("p       - Set Wi-Fi tethering passphrase\n");
+               printf("c       - Set Wi-Fi channel\n");
+               printf("a       - Activate Tethering\n");
+               printf("d       - Deactivate Tethering\n");
+               printf("l       - Get Tethering Ext Info (SSID, Passphrase)\n");
+               printf("e1-e4, f1-f2       - Verify Tethering Ext Scenarios (detailed)\n");
+               printf("0       - Exit\n");
+               printf("ENTER  - Show options menu.......\n");
+               g_free(a);
+               return true;
+       }
+
+       switch (a[0]) {
+               case '1':
+                       rv = test_tethering_ext_initialize();
+                       break;
+               case '2':
+                       rv = test_tethering_ext_deinitialize();
+                       break;
+               case 's':
+                       rv = test_tethering_ext_wifi_set_ssid();
+                       break;
+               case 'p':
+                       rv = test_tethering_ext_wifi_set_passphrase();
+                       break;
+               case 'c':
+                       rv = test_tethering_ext_wifi_set_channel();
+                       break;
+               case 'a':
+                       rv = test_tethering_ext_activate();
+                       break;
+               case 'd':
+                       rv = test_tethering_ext_deactivate();
+                       break;
+               case 'l':
+                       rv = test_tethering_ext_get_tethering_info();
+                       break;
+               case 'e':
+               case 'f':
+                       rv = test_tethering_ext_verification(a);
+                       break;
+
+               default:
+                       printf("unknown option %c\n", a[0]);
+                       rv = -1;
+                       break;
+       }
+
+       if (rv == 1)
+               printf("Operation succeeded!\n");
+       else
+               printf("Operation failed!\n");
+
+       g_free(a);
+       return true;
+}
+
+gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) {
+       if (g_verification) {
+               return true;
+       }
+       char a[10];
+       memset(a, 0, sizeof(a));
+       printf("Event received from stdin\n");
+
+       int rv = read(0, a, 10);
+       if (rv < 0) {
+               exit(1);
+       }
+       g_thread_new("Test Thread", (GThreadFunc) input_handle_fn, (gpointer) g_strdup(a));
+       return true;
+}
+
+int main(int argc, char **argv)
+{
+       GMainLoop *mainloop;
+
+#if !GLIB_CHECK_VERSION(2, 36, 0)
+       g_type_init();
+#endif
+       mainloop = g_main_loop_new(NULL, false);
+
+       g_channel = g_io_channel_unix_new(0);
+       g_io_add_watch(g_channel, (G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL), test_thread, NULL);
+       printf("Test Thread created...\n");
+       g_main_loop_run(mainloop);
+
+       return 0;
+}
+
diff --git a/test_application/tethering_ext_test_scenario.c b/test_application/tethering_ext_test_scenario.c
new file mode 100644 (file)
index 0000000..8c6920c
--- /dev/null
@@ -0,0 +1,122 @@
+#include "tethering_ext_test_scenario.h"
+#include "tethering_ext_test.h"
+#include "tethering_ext_test_util.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <glib.h>
+
+
+#define TETHERING_STEP_EXIT_ON_ERROR(tethering_test_fn) \
+    do { \
+        int rv = tethering_test_fn();\
+        if (rv < 0) {\
+            return -1;\
+        }\
+    } while (0)
+
+#define TETHERING_STEP_EXIT_ON_ERROR_CLEANUP(tethering_test_fn, cleanup_fn) \
+    do { \
+        int rv = tethering_test_fn();\
+        if (rv < 0) { \
+            cleanup_fn();\
+            return -1;\
+        }\
+    } while (0)
+
+
+typedef enum {
+    TETHERING_TEST_SCENARIO_DEFAULT = 0,
+    TETHERING_TEST_SCENARIO_AP_DISCONNECTED_WIFI_DIRECT_ON,
+    TETHERING_TEST_SCENARIO_AP_DISCONNECTED_WIFI_DIRECT_OFF,
+    TETHERING_TEST_SCENARIO_WIFI_OFF,
+    TETHERING_TEST_SCENARIO_LOWER_FREQ_BAND,
+    TETHERING_TEST_SCENARIO_HIGHER_FREQ_BAND,
+    TETHERING_TEST_SCENARIO_MAX
+} tethering_test_scenario_e;
+
+const char *pre_requisites_msg[] = {
+    "Make sure DUT is connected to WiFi AP, and WiFi Direct Link is disabled",
+    "Ensure that DUT is disconnected from WiFi AP",
+    "Ensure that DUT is disconnected from WiFi AP",
+    "Ensure that DUT has turned off WiFi interface",
+    "Make sure DUT is connected to WiFi AP on the 2.4 GHz band",
+    "Make sure DUT is connected to WiFi AP on the 5 GHz band",
+};
+
+const char *activation_msg[] = {
+    "Activating tethering",
+    "Activating tethering, please connect DUT to AP when ready",
+    "Activating tethering, please connect DUT to AP when ready",
+    "Activating tethering, please enable WiFi on DUT first, then connect to AP when ready",
+    "Activating tethering",
+    "Activating tethering"
+};
+
+#define TETHERING_WAIT_TILL_PREREQUISITES_MET(scenario_indx) \
+    do { \
+        if (scenario_indx < TETHERING_TEST_SCENARIO_DEFAULT || \
+                scenario_indx >= TETHERING_TEST_SCENARIO_MAX) { \
+            return -1;\
+        }\
+        printf("[PREREQUISITE] %s\n", pre_requisites_msg[scenario_indx]);\
+        printf("Press any key when ready.. ");\
+        getchar();\
+    } while(0)
+
+#define TETHERING_WAIT_TILL_USER_INPUT() \
+    do { \
+        char ch = '\0';\
+        while ((ch != '\n') && (ch != '\r')) {\
+            if (scanf("%c", &ch) < 0) {\
+                exit(1);\
+            }\
+        }\
+    } while(0)
+
+#define TETHERING_SCENARIO_IMPL(scenario_indx) \
+    do {\
+        TETHERING_WAIT_TILL_PREREQUISITES_MET(scenario_indx);\
+        TETHERING_STEP_EXIT_ON_ERROR(test_tethering_ext_initialize);\
+        TETHERING_STEP_EXIT_ON_ERROR_CLEANUP(test_tethering_ext_wifi_set_ssid, test_tethering_ext_deinitialize);\
+        TETHERING_STEP_EXIT_ON_ERROR_CLEANUP(test_tethering_ext_wifi_set_passphrase, test_tethering_ext_deinitialize);\
+        printf("%s\n", activation_msg[scenario_indx]);\
+        TETHERING_STEP_EXIT_ON_ERROR_CLEANUP(test_tethering_ext_activate, test_tethering_ext_deinitialize);\
+        printf("Tethering activated, please verify connection and press ENTER when done");\
+        TETHERING_WAIT_TILL_USER_INPUT();\
+        TETHERING_STEP_EXIT_ON_ERROR_CLEANUP(test_tethering_ext_deactivate, test_tethering_ext_deinitialize);\
+        TETHERING_STEP_EXIT_ON_ERROR(test_tethering_ext_deinitialize);\
+    } while(0)
+
+int tethering_ext_verify_enable_default() {
+    TETHERING_SCENARIO_IMPL(TETHERING_TEST_SCENARIO_DEFAULT);
+    return 1;
+}
+
+int tethering_ext_verify_enable_ap_disconnected_wifi_direct_on() {
+    TETHERING_SCENARIO_IMPL(TETHERING_TEST_SCENARIO_AP_DISCONNECTED_WIFI_DIRECT_ON);
+    return 1;
+}
+
+int tethering_ext_verify_enable_ap_disconnected_wifi_direct_off() {
+    TETHERING_SCENARIO_IMPL(TETHERING_TEST_SCENARIO_AP_DISCONNECTED_WIFI_DIRECT_OFF);
+    return 1;
+}
+
+int tethering_ext_verify_enable_ap_disconnected_wifi_off() {
+    TETHERING_SCENARIO_IMPL(TETHERING_TEST_SCENARIO_WIFI_OFF);
+    return 1;
+}
+
+int tethering_ext_verify_enable_freq_band_lower() {
+    TETHERING_SCENARIO_IMPL(TETHERING_TEST_SCENARIO_LOWER_FREQ_BAND);
+    return 1;
+}
+
+int tethering_ext_verify_enable_freq_band_higher() {
+    TETHERING_SCENARIO_IMPL(TETHERING_TEST_SCENARIO_HIGHER_FREQ_BAND);
+    return 1;
+}
+
+
+
diff --git a/test_application/tethering_ext_test_scenario.h b/test_application/tethering_ext_test_scenario.h
new file mode 100644 (file)
index 0000000..5236acc
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __TETHERING_EXT_TEST_SCENARIO_H_
+#define __TETHERING_EXT_TEST_SCENARIO_H_
+#define OPTION_MATCHES(arg, value) !strncmp(arg, value, strlen(arg))
+int tethering_ext_verify_enable_default();
+int tethering_ext_verify_enable_ap_disconnected_wifi_direct_on();
+int tethering_ext_verify_enable_ap_disconnected_wifi_direct_off();
+int tethering_ext_verify_enable_ap_disconnected_wifi_off();
+int tethering_ext_verify_enable_freq_band_lower();
+int tethering_ext_verify_enable_freq_band_higher();
+
+#endif // #ifndef __TETHERING_EXT_TEST_SCENARIO_H_
\ No newline at end of file
diff --git a/test_application/tethering_ext_test_util.c b/test_application/tethering_ext_test_util.c
new file mode 100644 (file)
index 0000000..8282ca9
--- /dev/null
@@ -0,0 +1,60 @@
+#include "tethering_ext_test_util.h"
+
+int GSemaphore_init(GSemaphore_t *sem) {
+    if (!sem) {
+        return -1;
+    }
+    sem->state = TETHERING_STATE_IDLE;
+    g_mutex_init(&sem->mutex);
+    g_cond_init(&sem->cond);
+    return 0;
+}
+
+int GSemaphore_destroy(GSemaphore_t *sem) {
+    if (!sem) {
+        return -1;
+    }
+    g_mutex_clear(&sem->mutex);
+    g_cond_clear(&sem->cond);
+    return 0;
+}
+
+int GSemaphore_post(GSemaphore_t *sem) {
+    if (!sem) {
+        return -1;
+    }
+    g_mutex_lock(&sem->mutex);
+    g_cond_signal(&sem->cond);
+    g_mutex_unlock(&sem->mutex);
+    return 0;
+}
+
+int GSemaphore_wait(GSemaphore_t *sem) {
+    if (!sem) {
+        return -1;
+    }
+    g_mutex_lock(&sem->mutex);
+    g_cond_wait(&sem->cond, &sem->mutex);
+    g_mutex_unlock(&sem->mutex);
+    return 0;
+}
+
+int GSemaphore_update(GSemaphore_t *sem, tethering_state_e state) {
+    if (!sem) {
+        return -1;
+    }
+    g_mutex_lock(&sem->mutex);
+    sem->state = state;
+    g_mutex_unlock(&sem->mutex);
+    return 0;
+}
+
+int GSemaphore_get_state(GSemaphore_t *sem, tethering_state_e *state) {
+    if (!sem) {
+        return -1;
+    }
+    g_mutex_lock(&sem->mutex);
+    *state = sem->state;
+    g_mutex_unlock(&sem->mutex);
+    return 0;
+}
diff --git a/test_application/tethering_ext_test_util.h b/test_application/tethering_ext_test_util.h
new file mode 100644 (file)
index 0000000..91d7396
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __TETHERING_EXT_TEST_UTIL_H_
+#define __TETHERING_EXT_TEST_UTIL_H_
+#include <glib.h>
+
+
+typedef enum {
+    TETHERING_STATE_IDLE = -1,
+    TETHERING_STATE_ACTIVATING,
+    TETHERING_STATE_ACTIVATED,
+    TETHERING_STATE_DEACTIVATING,
+    TETHERING_STATE_DEACTIVATED,
+} tethering_state_e;
+
+typedef struct {
+    tethering_state_e state;
+    GMutex mutex;
+    GCond cond;
+} GSemaphore_t;
+
+int GSemaphore_init(GSemaphore_t *sem);
+int GSemaphore_destroy(GSemaphore_t *sem);
+int GSemaphore_post(GSemaphore_t *sem);
+int GSemaphore_wait(GSemaphore_t *sem);
+int GSemaphore_update(GSemaphore_t *sem, tethering_state_e state);
+int GSemaphore_get_state(GSemaphore_t *sem, tethering_state_e *state);
+#endif // #ifndef __TETHERING_EXT_TEST_UTIL_H_
\ No newline at end of file