Add CAPIs to handle Wi-Fi roaming signal 20/268320/1 accepted/tizen/unified/20220105.120858 submit/tizen/20211230.063452 submit/tizen/20211230.103710
authorJaehyun Kim <jeik01.kim@samsung.com>
Mon, 20 Dec 2021 09:02:49 +0000 (18:02 +0900)
committerJaehyun Kim <jeik01.kim@samsung.com>
Mon, 20 Dec 2021 09:02:49 +0000 (18:02 +0900)
Change-Id: I0330789ad6b7be26776c42e1bf022862898a745c
Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
include/wifi-manager-extension.h
packaging/capi-network-wifi-manager.spec
src/network_info.h
src/network_interface.h
src/network_internal.h
src/network_signal.c
src/wifi_internal.c
src/wifi_internal.h
src/wifi_manager.c
tools/manager-test/wman_test_main.c

index 04ad726..0c7019f 100644 (file)
@@ -68,6 +68,18 @@ typedef enum {
 } wifi_manager_mac_policy_e;
 
 /**
+ * @brief Enumeration for the Wi-Fi Roemaing State.
+ * @since_tizen 7.0
+ */
+typedef enum {
+       WIFI_MANAGER_ROAM_UNKNOWN,          /**< Unknown */
+       WIFI_MANAGER_ROAM_SCAN_REQUIRED,    /**< The SNR and signal of the connected AP are weakened */
+       WIFI_MANAGER_ROAM_STARTED,          /**< Wi-Fi Roaming is started */
+       WIFI_MANAGER_ROAM_FAILURE,          /**< Wi-Fi Roaming failed */
+       WIFI_MANAGER_ROAM_SUCCESS,          /**< Wi-Fi Roaming is successful. */
+} wifi_manager_roam_e;
+
+/**
  * @brief The Wi-Fi netlink scan handle.
  * @since_tizen 5.0
  */
@@ -756,6 +768,48 @@ int wifi_manager_set_country_code(wifi_manager_h wifi, const char *country);
 int wifi_manager_get_country_code(wifi_manager_h wifi, char **country_code);
 
 /**
+ * @brief Called when the Roaming state is changed.
+ * @since_tizen 7.0
+ * @param[in] state         The Wi-Fi roaming state
+ * @param[in] cur_bssid     The MAC address of connected AP
+ * @param[in] dst_bssid     The MAC address of AP to roam
+ * @param[in] user_data     The user data passed from the callback registration function
+ * @see wifi_manager_set_roaming_cb()
+ * @see wifi_manager_unset_roaming_cb()
+ */
+typedef void(*wifi_manager_roaming_state_changed_cb)(wifi_manager_roam_e state,
+                                                       char *cur_bssid, char *dst_bssid, void *user_data);
+
+/**
+ * @brief Registers the callback called when the Roaming state is changed.
+ * @since_tizen 7.0
+ * @param[in] wifi            The Wi-Fi handle
+ * @param[in] callback        The callback function to be called
+ * @param[in] user_data       The user data passed to the callback function
+ * @return 0 on success, otherwise negative error value
+ * @retval #WIFI_MANAGER_ERROR_NONE                 Successful
+ * @retval #WIFI_MANAGER_ERROR_NOT_INITIALIZED      Not initialized
+ * @retval #WIFI_MANAGER_ERROR_INVALID_OPERATION    Invalid operation
+ * @retval #WIFI_MANAGER_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval #WIFI_MANAGER_ERROR_NOT_SUPPORTED        Not supported
+ */
+int wifi_manager_set_roaming_cb(wifi_manager_h wifi,
+               wifi_manager_roaming_state_changed_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback called when the Roaming state is changed.
+ * @since_tizen 7.0
+ * @param[in] wifi            The Wi-Fi handle
+ * @return 0 on success, otherwise negative error value
+ * @retval #WIFI_MANAGER_ERROR_NONE                 Successful
+ * @retval #WIFI_MANAGER_ERROR_NOT_INITIALIZED      Not initialized
+ * @retval #WIFI_MANAGER_ERROR_INVALID_OPERATION    Invalid operation
+ * @retval #WIFI_MANAGER_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval #WIFI_MANAGER_ERROR_NOT_SUPPORTED        Not supported
+ */
+int wifi_manager_unset_roaming_cb(wifi_manager_h wifi);
+
+/**
  * @brief Checks available security types of the AP.
  * @details An AP may support several types of security modes together.
  * You can check all supported security modes with this API.
index 90390bd..111eeb7 100644 (file)
@@ -1,7 +1,7 @@
 Name:          capi-network-wifi-manager
 Summary:       Network Wi-Fi library in TIZEN C API
-Version:       1.3.12
-Release:       6
+Version:       1.3.13
+Release:       0
 Group:         System/Network
 License:       Apache-2.0
 Source0:       %{name}-%{version}.tar.gz
index d469cb1..8098747 100644 (file)
@@ -71,6 +71,7 @@ typedef enum {
        NET_EVENT_WIFI_DPP_FAILED,
        NET_EVENT_WIFI_DPP_REMOVED,
        NET_EVENT_WIFI_DPP_EVENT_IND, /* TODO: Make this in detail */
+       NET_EVENT_WIFI_ROAM_STATE_IND,
 } net_event_e;
 
 typedef struct {
@@ -139,6 +140,7 @@ typedef struct {
        guint subscribe_id_connman_error;
        guint subscribe_id_connman_scandone;
        guint subscribe_id_connman_scanstarted;
+       guint subscribe_id_connman_roaming;
        guint subscribe_id_netconfig_wifi;
 
        char interface_name[NET_WLAN_IF_NAME_LEN];
index 9ffc6ff..75e68b2 100644 (file)
@@ -247,6 +247,12 @@ typedef struct {
        char own_uri[MAX_DPP_URI_LEN];
 } net_dpp_event_info_s;
 
+typedef struct {
+       char *state;
+       char *cur_bssid;
+       char *dst_bssid;
+} net_roam_event_info_s;
+
 int net_register_client_ext(network_info_s **network_info,
                const char *interface_name, net_event_cb event_cb, void *user_data);
 void net_deregister_client_ext(network_info_s *network_info);
index 455d07e..dbf1702 100644 (file)
@@ -86,6 +86,7 @@ extern "C" {
 #define SIGNAL_SERVICES_CHANGED                        "ServicesChanged"
 #define SIGNAL_SCAN_DONE                               "ScanDone"
 #define SIGNAL_SCAN_CHANGED                            "ScanChanged"
+#define SIGNAL_ROAMING_STATE_CHANGED   "RoamingStateChanged"
 
 #define CONNMAN_WIFI_TECHNOLOGY_PREFIX CONNMAN_PATH "/technology/wifi"
 
index c45ebe0..d4f02ea 100644 (file)
@@ -33,6 +33,7 @@ struct cs_tid_info {
        guint subscribe_id_connman_error;
        guint subscribe_id_connman_scandone;
        guint subscribe_id_connman_scanstarted;
+       guint subscribe_id_connman_roaming;
        guint subscribe_id_netconfig_wifi;
 };
 
@@ -1063,6 +1064,70 @@ out:
        return NET_ERR_NONE;
 }
 
+static int __net_handle_roaming_changed(network_info_s *network_info, GVariant *param)
+{
+       __NETWORK_FUNC_ENTER__;
+
+       GVariant *var;
+       GVariantIter *iter = NULL;
+       const gchar *sub_key = NULL;
+       const gchar *value = NULL;
+       net_event_info_s *event_data = NULL;
+       net_roam_event_info_s roam_info = { 0, 0, 0};
+       gchar *interface_name = NULL;
+
+       int ret = NET_ERR_NONE;
+
+       g_variant_get(param, "(a{sv})", &iter);
+       while (g_variant_iter_loop(iter, "{sv}", &sub_key, &var)) {
+               if (g_strcmp0(sub_key, "Interface") == 0) {
+                       value = g_variant_get_string(var, NULL);
+                       interface_name = g_strdup(value);
+               } else if (g_strcmp0(sub_key, "State") == 0) {
+                       value = g_variant_get_string(var, NULL);
+                       roam_info.state = g_strdup(value);
+               } else if (g_strcmp0(sub_key, "ConnectedBSSID") == 0) {
+                       value = g_variant_get_string(var, NULL);
+                       roam_info.cur_bssid = g_strdup(value);
+               } else if (g_strcmp0(sub_key, "TargetBSSID") == 0) {
+                       value = g_variant_get_string(var, NULL);
+                       roam_info.dst_bssid = g_strdup(value);
+               }
+       }
+
+       WIFI_LOG(WIFI_INFO, "Interface: %s State: %s, Connected BSSID: %s, Target BSSID: %s",
+                       interface_name, roam_info.state, roam_info.cur_bssid, roam_info.dst_bssid);
+
+       if (g_strcmp0(interface_name, network_info->interface_name) != 0)
+               goto done;
+
+       event_data = g_try_malloc0(sizeof(net_event_info_s));
+       if (event_data == NULL) {
+               ret = NET_ERR_OUT_OF_MEMORY;
+               goto done;
+       }
+
+       event_data->Event = NET_EVENT_WIFI_ROAM_STATE_IND;
+       event_data->Error = NET_ERR_NONE;
+       event_data->Datalength = sizeof(net_roam_event_info_s);
+       event_data->Data = &roam_info;
+
+       if (network_info->event_callback)
+               network_info->event_callback(event_data, network_info->user_data);
+
+       g_free(event_data);
+
+done:
+       g_variant_iter_free(iter);
+       g_free(interface_name);
+       g_free(roam_info.state);
+       g_free(roam_info.cur_bssid);
+       g_free(roam_info.dst_bssid);
+
+       __NETWORK_FUNC_EXIT__;
+       return ret;
+}
+
 static void __net_connman_service_signal_filter(GDBusConnection *conn,
                const gchar *name, const gchar *path, const gchar *interface,
                const gchar *sig, GVariant *param, gpointer user_data)
@@ -1827,6 +1892,8 @@ static void __net_connman_manager_signal_filter(GDBusConnection *conn,
                __net_handle_scan_changed(network_info, param);
        else if (g_strcmp0(sig, SIGNAL_SCAN_DONE) == 0)
                __net_handle_scan_done(network_info, param);
+       else if (g_strcmp0(sig, SIGNAL_ROAMING_STATE_CHANGED) == 0)
+               __net_handle_roaming_changed(network_info, param);
 }
 
 static void __net_netconfig_signal_filter(GDBusConnection *conn,
@@ -2042,6 +2109,7 @@ void _net_set_cs_tid(network_info_s *network_info, int tid)
        tid_info->subscribe_id_connman_error = network_info->subscribe_id_connman_error;
        tid_info->subscribe_id_connman_scandone = network_info->subscribe_id_connman_scandone;
        tid_info->subscribe_id_connman_scanstarted = network_info->subscribe_id_connman_scanstarted;
+       tid_info->subscribe_id_connman_roaming = network_info->subscribe_id_connman_roaming;
        tid_info->subscribe_id_netconfig_wifi = network_info->subscribe_id_netconfig_wifi;
 
        WIFI_LOG(WIFI_INFO, "tid %d, tid_info %p", tid, tid_info);
@@ -2085,6 +2153,7 @@ void _net_unset_cs_tid(int tid)
        g_dbus_connection_signal_unsubscribe(connection, tid_info->subscribe_id_connman_error);
        g_dbus_connection_signal_unsubscribe(connection, tid_info->subscribe_id_connman_scandone);
        g_dbus_connection_signal_unsubscribe(connection, tid_info->subscribe_id_connman_scanstarted);
+       g_dbus_connection_signal_unsubscribe(connection, tid_info->subscribe_id_connman_roaming);
        g_dbus_connection_signal_unsubscribe(connection, tid_info->subscribe_id_netconfig_wifi);
        g_object_unref(connection);
 
@@ -2158,6 +2227,19 @@ int _net_register_signal(network_info_s *network_info)
                        network_info,
                        NULL);
 
+       /* Create connman technology roaming connection */
+       network_info->subscribe_id_connman_roaming = g_dbus_connection_signal_subscribe(
+                       network_info->connection,
+                       CONNMAN_SERVICE,
+                       CONNMAN_MANAGER_INTERFACE,
+                       SIGNAL_ROAMING_STATE_CHANGED,
+                       CONNMAN_MANAGER_PATH,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       __net_connman_manager_signal_filter,
+                       network_info,
+                       NULL);
+
        /* Create net-config service connection */
        network_info->subscribe_id_netconfig_wifi = g_dbus_connection_signal_subscribe(
                        network_info->connection,
@@ -2176,14 +2258,16 @@ int _net_register_signal(network_info_s *network_info)
                network_info->subscribe_id_connman_error == 0 ||
                network_info->subscribe_id_connman_scandone == 0 ||
                network_info->subscribe_id_connman_scanstarted == 0 ||
+               network_info->subscribe_id_connman_roaming == 0 ||
                network_info->subscribe_id_netconfig_wifi == 0) {
                WIFI_LOG(WIFI_ERROR, "Failed register signals "
                                "connman_state(%d), connman_error(%d), connman_scandone(%d), "
-                               "connman_scanstarted(%d), netconfig_wifi(%d)",
+                               "connman_scanstarted(%d), connman_roaming(%d), netconfig_wifi(%d)",
                                network_info->subscribe_id_connman_state,
                                network_info->subscribe_id_connman_error,
                                network_info->subscribe_id_connman_scandone,
                                network_info->subscribe_id_connman_scanstarted,
+                               network_info->subscribe_id_connman_roaming,
                                network_info->subscribe_id_netconfig_wifi);
                _net_deregister_signal(network_info);
                Error = NET_ERR_INVALID_OPERATION;
@@ -2208,6 +2292,8 @@ void _net_deregister_signal(network_info_s *network_info)
                g_dbus_connection_signal_unsubscribe(network_info->connection,
                                        network_info->subscribe_id_connman_scanstarted);
                g_dbus_connection_signal_unsubscribe(network_info->connection,
+                                       network_info->subscribe_id_connman_roaming);
+               g_dbus_connection_signal_unsubscribe(network_info->connection,
                                        network_info->subscribe_id_netconfig_wifi);
        }
 
index 1faf134..0fc278e 100644 (file)
@@ -1227,6 +1227,41 @@ static void __dpp_removed_cb(wifi_manager_handle_s *wifi_handle,
 
        g_p_dpp_current = NULL;
 }
+
+static void __roaming_state_changed_cb(wifi_manager_handle_s *wifi_handle,
+               net_roam_event_info_s *roam_event_info)
+{
+       char *cur_bssid = NULL;
+       char *dst_bssid = NULL;
+       char *state = roam_event_info->state;
+       wifi_manager_roam_e roam_state = WIFI_MANAGER_ROAM_UNKNOWN;
+
+       if (state) {
+               if (!strcmp(state, "required")) {
+                       roam_state = WIFI_MANAGER_ROAM_SCAN_REQUIRED;
+                       cur_bssid = roam_event_info->cur_bssid;
+               } else if (!strcmp(state, "started")) {
+                       roam_state = WIFI_MANAGER_ROAM_STARTED;
+                       cur_bssid = roam_event_info->cur_bssid;
+                       dst_bssid = roam_event_info->dst_bssid;
+               } else if (!strcmp(state, "failure")) {
+                       roam_state = WIFI_MANAGER_ROAM_FAILURE;
+                       cur_bssid = roam_event_info->cur_bssid;
+                       dst_bssid = roam_event_info->dst_bssid;
+               } else if (!strcmp(state, "success")) {
+                       roam_state = WIFI_MANAGER_ROAM_SUCCESS;
+                       cur_bssid = roam_event_info->cur_bssid;
+                       dst_bssid = roam_event_info->dst_bssid;
+               }
+       }
+
+       WIFI_LOG(WIFI_INFO, "Roaming state: %s, cur_bssid %s, dst_bssid %s",
+                                                                               state, cur_bssid, dst_bssid);
+
+       if (wifi_handle->roaming_state_changed_cb)
+               wifi_handle->roaming_state_changed_cb(roam_state,
+                               cur_bssid, dst_bssid, wifi_handle->roaming_state_changed_user_data);
+}
 //LCOV_EXCL_STOP
 
 static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
@@ -1492,6 +1527,9 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
        case NET_EVENT_WIFI_DPP_REMOVED:
                __dpp_removed_cb(wifi_handle, (net_dpp_event_info_s *)event_cb->Data);
                break;
+       case NET_EVENT_WIFI_ROAM_STATE_IND:
+               __roaming_state_changed_cb(wifi_handle, (net_roam_event_info_s *)event_cb->Data);
+               break;
        //LCOV_EXCL_STOP
        default:
                break;
index fd658d2..4358e75 100644 (file)
@@ -261,6 +261,8 @@ typedef struct {
        void *forget_ap_user_data;
        wifi_manager_dpp_event_cb dpp_event_cb;
        void *dpp_event_user_data;
+       wifi_manager_roaming_state_changed_cb roaming_state_changed_cb;
+       void *roaming_state_changed_user_data;
 
        network_info_s *network_info;
        char interface_name[NET_WLAN_IF_NAME_LEN];
index eef1126..e4e02f1 100644 (file)
@@ -85,6 +85,13 @@ static void __wifi_set_module_state_changed_cb(wifi_manager_handle_s *wifi_handl
        wifi_handle->module_state_changed_user_data = user_data;
 }
 
+static void __wifi_set_roaming_state_changed_cb(wifi_manager_handle_s *wifi_handle,
+                       void *callback, void *user_data)
+{
+       wifi_handle->roaming_state_changed_cb = callback;
+       wifi_handle->roaming_state_changed_user_data = user_data;
+}
+
 //LCOV_EXCL_STOP
 
 EXPORT_API int wifi_manager_initialize(wifi_manager_h *wifi)
@@ -2185,3 +2192,37 @@ EXPORT_API int wifi_manager_get_country_code(wifi_manager_h wifi, char **country
        __NETWORK_CAPI_FUNC_EXIT__;
        return rv;
 }
+
+EXPORT_API int wifi_manager_set_roaming_cb(wifi_manager_h wifi,
+               wifi_manager_roaming_state_changed_cb callback, void *user_data)
+{
+       __NETWORK_CAPI_FUNC_ENTER__;
+
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(wifi, __NETWORK_CAPI_FUNC_EXIT__);
+
+       if (callback == NULL) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
+       }
+
+       __wifi_set_roaming_state_changed_cb(wifi, callback, user_data);
+
+       __NETWORK_CAPI_FUNC_EXIT__;
+       return WIFI_MANAGER_ERROR_NONE;
+}
+
+EXPORT_API int wifi_manager_unset_roaming_cb(wifi_manager_h wifi)
+{
+       __NETWORK_CAPI_FUNC_ENTER__;
+
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(wifi, __NETWORK_CAPI_FUNC_EXIT__);
+
+       __wifi_set_roaming_state_changed_cb(wifi, NULL, NULL);
+
+       __NETWORK_CAPI_FUNC_EXIT__;
+       return WIFI_MANAGER_ERROR_NONE;
+}
index 0d492a9..b41cf02 100644 (file)
@@ -135,6 +135,33 @@ static void __test_tdls_state_callback(wifi_manager_tdls_state_e state, char *pe
                printf(", state : TDLS Disconnected, Peer Mac Address [%s]\n", peer_mac_add);
 }
 
+static void __test_roaming_state_changed_callback(wifi_manager_roam_e state,
+                                                       char *cur_bssid, char *dst_bssid, void *user_data)
+{
+       printf("[%s] Wi-Fi Roaming state changed callback", (char *)user_data);
+
+       switch (state) {
+       case WIFI_MANAGER_ROAM_SCAN_REQUIRED:
+               printf(", state : Scan Required");
+               break;
+       case WIFI_MANAGER_ROAM_STARTED:
+               printf(", state : Roaming Started");
+               break;
+       case WIFI_MANAGER_ROAM_FAILURE:
+               printf(", state : Romaing Failure");
+               break;
+       case WIFI_MANAGER_ROAM_SUCCESS:
+               printf(", state : Romaing Success");
+               break;
+       case WIFI_MANAGER_ROAM_UNKNOWN:
+       /* fall through */
+       default:
+               printf(", state : Unknown");
+       }
+
+       printf(", cur_bssid: %s, dst_bssid: %s\n", cur_bssid, dst_bssid);
+}
+
 int wman_test_init(void)
 {
        int rv = wifi_manager_initialize(&wifi);
@@ -149,6 +176,7 @@ int wman_test_init(void)
                wifi_manager_tdls_set_state_changed_cb(wifi, __test_tdls_state_callback, "1");
                wifi_manager_tdls_set_discovered_cb(wifi, __test_tdls_discover_callback, "1");
                wifi_manager_set_module_state_changed_cb(wifi, __test_get_wifi_module_state_callback, "1");
+               wifi_manager_set_roaming_cb(wifi, __test_roaming_state_changed_callback, "1");
 
        } else {
                printf("[1] Wifi init failed [%s]\n", wman_test_strerror(rv));