[Implemention] Asynchronous API for forgetting access point. 33/183233/4 accepted/tizen/unified/20180709.064826 submit/tizen/20180706.050915
authorNishant Chaprana <n.chaprana@samsung.com>
Tue, 3 Jul 2018 12:48:49 +0000 (18:18 +0530)
committerNishant Chaprana <n.chaprana@samsung.com>
Thu, 5 Jul 2018 10:19:49 +0000 (15:49 +0530)
This patch implements asynchronous API for forgetting access point.
The API name is "wifi_manager_forget_ap_async()"

Change-Id: I03e823a7bbd63b994fec3d6d3fe151b92af72a0a
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
include/network_dbus.h
include/network_interface.h
include/network_internal.h
include/wifi_internal.h
packaging/capi-network-wifi-manager.spec
src/network_dbus.c
src/network_interface.c
src/network_signal.c
src/wifi_internal.c
src/wifi_manager.c
test/wifi_manager_test.c

index 1d36bb4..5f7c780 100755 (executable)
@@ -58,6 +58,8 @@ extern "C" {
 #define CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE        "PrivateKeyPassphrase"
 #define CONNMAN_CONFIG_FIELD_EAP_KEYMGMT_TYPE  "KeymgmtType"
 
+#define DBUS_REPLY_TIMEOUT (120 * 1000)
+
 typedef struct {
        char *type;
        char *mode;
index 5a5e343..58e646c 100755 (executable)
@@ -70,6 +70,7 @@ typedef enum {
        NET_EVENT_WIFI_TDLS_DISCOVERED_IND,
        NET_EVENT_WIFI_TDLS_CONNECTED_IND,
        NET_EVENT_WIFI_TDLS_DISCONNECTED_IND,
+       NET_EVENT_WIFI_FORGET_AP_IND,
 } net_event_e;
 
 typedef enum {
@@ -266,6 +267,8 @@ int net_get_profile_list(GSList **profile_list);
 
 int net_modify_profile(const char *profile_name, net_profile_info_s *prof_info);
 int net_delete_profile(const char *profile_name);
+int net_delete_profile_async(const char *profile_name);
+void net_forget_ap_finshed(net_err_e Error);
 
 int net_get_wifi_state(net_wifi_state_e *current_state);
 int net_init_profile_info(net_profile_info_s *ProfInfo);
index b7651c6..98a6728 100755 (executable)
@@ -125,6 +125,7 @@ typedef enum {
        NETWORK_REQUEST_TYPE_SET_DEFAULT,
        NETWORK_REQUEST_TYPE_RESET_DEFAULT,
        NETWORK_REQUEST_TYPE_TDLS_DISCOVERY,
+       NETWORK_REQUEST_TYPE_FORGET_AP,
        NETWORK_REQUEST_TYPE_MAX
 } network_async_request_type_e;
 
index 5c30a49..5358371 100755 (executable)
@@ -104,6 +104,7 @@ typedef enum {
        WIFI_MANAGER_RSSI_LEVEL_CHANGED_CB,
        WIFI_MANAGER_TDLS_STATE_CHANGED_CB,
        WIFI_MANAGER_TDLS_DISCOVERED_CB,
+       WIFI_MANAGER_FORGET_AP_CB,
 } wifi_manager_handle_cb_e;
 
 typedef enum {
@@ -191,6 +192,8 @@ typedef struct {
        void *multi_scan_user_data;
        wifi_manager_netlink_scan_finished_cb netlink_scan_cb;
        void *netlink_scan_user_data;
+       wifi_manager_forget_ap_finished_cb forget_ap_cb;
+       void *forget_ap_user_data;
 
 } wifi_manager_handle_s;
 
@@ -253,6 +256,9 @@ int _wifi_connect_with_wps_pbc(wifi_manager_h wifi, wifi_manager_ap_h ap,
 int _wifi_connect_with_wps_pin(wifi_manager_h wifi, wifi_manager_ap_h ap,
                const char *pin, wifi_manager_connected_cb callback, void *user_data);
 int _wifi_forget_ap(wifi_manager_ap_h ap);
+int _wifi_forget_ap_async(wifi_manager_h wifi, wifi_manager_ap_h ap,
+                         wifi_manager_forget_ap_finished_cb callback,
+                         void* user_data);
 
 void _wifi_rssi_level_changed_cb(keynode_t *node, void *user_data);
 
index 86813d6..d802ad2 100755 (executable)
@@ -1,6 +1,6 @@
 Name:          capi-network-wifi-manager
 Summary:       Network Wi-Fi library in TIZEN C API
-Version:       1.0.37
+Version:       1.0.38
 Release:       1
 Group:         System/Network
 License:       Apache-2.0
index 89029de..a9c0797 100755 (executable)
@@ -21,7 +21,6 @@
 #include "network_internal.h"
 #include "network_dbus.h"
 
-#define DBUS_REPLY_TIMEOUT (120 * 1000)
 #define DBUS_REPLY_TIMEOUT_SYNC (10 * 1000)
 
 #define WIFI_SECURITY_NONE                     "none"
@@ -783,17 +782,17 @@ int _net_invoke_dbus_method_nonblock(const char *dest, const char *path,
        }
 
        g_dbus_connection_call(connection,
-                                                       dest,
-                                                       path,
-                                                       interface_name,
-                                                       method,
-                                                       params,
-                                                       NULL,
-                                                       G_DBUS_CALL_FLAGS_NONE,
-                                                       timeout,
-                                                       _net_dbus_get_gdbus_cancellable(),
-                                                       (GAsyncReadyCallback) notify_func,
-                                                       NULL);
+                              dest,
+                              path,
+                              interface_name,
+                              method,
+                              params,
+                              NULL,
+                              G_DBUS_CALL_FLAGS_NONE,
+                              timeout,
+                              _net_dbus_get_gdbus_cancellable(),
+                              (GAsyncReadyCallback) notify_func,
+                              NULL);
 
        if (notify_func != NULL)
                _net_dbus_pending_call_ref();
index 198c5ca..d86e5c9 100755 (executable)
@@ -1333,6 +1333,36 @@ static void __net_abort_open_connection(const char *profile_name)
 
        __NETWORK_FUNC_EXIT__;
 }
+
+void net_forget_ap_finshed(net_err_e Error)
+{
+       __NETWORK_FUNC_ENTER__;
+
+       net_event_info_s event_data;
+       char event_string[64];
+
+       if (request_table[NETWORK_REQUEST_TYPE_FORGET_AP].flag == FALSE) {
+               __NETWORK_FUNC_EXIT__;
+               return;
+       }
+
+       memset(&request_table[NETWORK_REQUEST_TYPE_FORGET_AP], 0,
+              sizeof(network_request_table_s));
+
+       event_data.Event = NET_EVENT_WIFI_FORGET_AP_IND;
+       g_strlcpy(event_string, "Sending NET_EVENT_WIFI_FORGET_AP_IND", 64);
+
+       _net_dbus_pending_call_unref();
+
+       event_data.Error = Error;
+       event_data.Datalength = 0;
+       event_data.Data = NULL;
+
+       WIFI_LOG(WIFI_INFO, "%s, Error: %d", event_string, event_data.Error);
+       _net_client_callback(&event_data);
+
+       __NETWORK_FUNC_EXIT__;
+}
 //LCOV_EXCL_STOP
 
 int _net_check_profile_name(const char* ProfileName)
@@ -3040,6 +3070,124 @@ int net_delete_profile(const char* profile_name)
        return NET_ERR_NONE;
 }
 
+static void _net_delete_profile_async_reply(GObject *source_object,
+                                           GAsyncResult *res,
+                                           gpointer user_data)
+{
+       __NETWORK_FUNC_ENTER__;
+
+       GDBusConnection *conn = NULL;
+       GError *error = NULL;
+       net_err_e Error = NET_ERR_NONE;
+       GVariant *message = NULL;
+       GVariantIter *iter = NULL;
+       GVariantIter *service = NULL;
+       gchar *path = NULL;
+       net_profile_name_s wifi_prof_name;
+       net_profile_info_s prof_info;
+
+       conn = G_DBUS_CONNECTION(source_object);
+       message = g_dbus_connection_call_finish(conn, res, &error);
+       if (message == NULL && error != NULL) {
+               WIFI_LOG(WIFI_ERROR, "Delete profile, error [%s]\n", error->message);
+               Error = NET_ERR_UNKNOWN;
+               g_error_free(error);
+               _net_dbus_pending_call_unref();
+               __NETWORK_FUNC_EXIT__;
+               return;
+       }
+
+       Error = NET_ERR_NO_PROFILE;
+       g_variant_get(message, "(a(oa{sv}))", &iter);
+       if (iter == NULL) {
+               g_variant_unref(message);
+               _net_dbus_pending_call_unref();
+               __NETWORK_FUNC_EXIT__;
+               return;
+       }
+
+       while (g_variant_iter_loop(iter, "(oa{sv})", &path, &service)) {
+               if (g_strcmp0(request_table[NETWORK_REQUEST_TYPE_FORGET_AP].ProfileName, path) == 0) {
+                       Error = __net_extract_service_info(path, service,
+                                                          &prof_info);
+                       g_variant_iter_free(service);
+                       g_free(path);
+                       break;
+               }
+       }
+
+       g_variant_iter_free(iter);
+       g_variant_unref(message);
+
+       g_strlcpy(wifi_prof_name.ProfileName,
+                 request_table[NETWORK_REQUEST_TYPE_FORGET_AP].ProfileName,
+                 NET_PROFILE_NAME_LEN_MAX + 1);
+
+       Error = __net_wifi_delete_profile(&wifi_prof_name,
+                                         prof_info.security_info.sec_mode,
+                                         prof_info.passpoint);
+       if (Error != NET_ERR_NONE) {
+               WIFI_LOG(WIFI_ERROR, //LCOV_EXCL_LINE
+                               "Failed to delete service(profile). Error [%s]",
+                               _net_print_error(Error));
+
+               Error = NET_ERR_UNKNOWN; //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+       }
+
+
+       if (prof_info.ProfileState != NET_STATE_TYPE_ONLINE &&
+           prof_info.ProfileState != NET_STATE_TYPE_READY)
+               net_forget_ap_finshed(Error);
+
+       __NETWORK_FUNC_EXIT__;
+}
+
+int net_delete_profile_async(const char* profile_name)
+{
+       __NETWORK_FUNC_ENTER__;
+
+       net_err_e Error = NET_ERR_NONE;
+
+       if (NetworkInfo.ref_count < 1) {
+               WIFI_LOG(WIFI_ERROR, "Application is not registered"); //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return NET_ERR_APP_NOT_REGISTERED; //LCOV_EXCL_LINE
+       }
+
+       WIFI_LOG(WIFI_INFO, "Delete Profile [%s]", profile_name);
+
+       if (_net_check_profile_name(profile_name) != NET_ERR_NONE) {
+               WIFI_LOG(WIFI_ERROR, "Invalid Parameter"); //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return NET_ERR_INVALID_PARAM; //LCOV_EXCL_LINE
+       }
+
+       /* Get service details */
+       request_table[NETWORK_REQUEST_TYPE_FORGET_AP].flag = TRUE;
+       g_strlcpy(request_table[NETWORK_REQUEST_TYPE_FORGET_AP].ProfileName,
+                 profile_name, NET_PROFILE_NAME_LEN_MAX+1);
+
+       Error = _net_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
+                                                CONNMAN_MANAGER_PATH,
+                                                CONNMAN_MANAGER_INTERFACE,
+                                                "GetServices", NULL,
+                                                DBUS_REPLY_TIMEOUT,
+                                                _net_delete_profile_async_reply);
+       if (Error != NET_ERR_NONE) {
+               WIFI_LOG(WIFI_ERROR, //LCOV_EXCL_LINE
+                               "Failed to get service(profile) information. Error [%s]",
+                               _net_print_error(Error));
+
+               request_table[NETWORK_REQUEST_TYPE_FORGET_AP].flag = FALSE;
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return Error; //LCOV_EXCL_LINE
+       }
+
+       __NETWORK_FUNC_EXIT__;
+       return NET_ERR_NONE;
+}
+
 int net_modify_profile(const char* profile_name, net_profile_info_s* prof_info)
 {
        __NETWORK_FUNC_ENTER__;
index 7db8c08..411f790 100755 (executable)
@@ -812,6 +812,7 @@ static int __net_handle_service_state_changed(const gchar *sig_path,
                WIFI_LOG(WIFI_INFO, "Sending NET_EVENT_CLOSE_IND");
 
                _net_client_callback(&event_data);
+               net_forget_ap_finshed(NET_ERR_NONE);
 
                break;
        }
index 4afd0b1..72bf7a9 100755 (executable)
@@ -1103,6 +1103,40 @@ static void __tdls_state_changed_cb(wifi_manager_tdls_state_e state,
 }
 //LCOV_EXCL_STOP
 
+static void __set_forget_ap_cb(wifi_manager_h wifi,
+               wifi_manager_forget_ap_finished_cb user_cb, void *user_data)
+{
+       wifi_manager_handle_s *local_handle = (wifi_manager_handle_s *)wifi;
+
+       if (user_cb != NULL) {
+               local_handle->forget_ap_cb = user_cb;
+               local_handle->forget_ap_user_data = user_data;
+       }
+}
+
+static void __forget_ap_cb(wifi_manager_error_e result)
+{
+       GSList *list;
+
+       if (net_check_ref_count() != true) {
+               WIFI_LOG(WIFI_ERROR, "Application is not registered"
+                               "If multi-threaded, thread integrity be broken.");
+               return;
+       }
+
+       if (_wifi_get_callback_count_from_handle_list(WIFI_MANAGER_FORGET_AP_CB)) {
+               for (list = wifi_manager_handle_list; list; list = list->next) {
+                       wifi_manager_handle_s *local_handle = (wifi_manager_handle_s *)list->data;
+                       if (local_handle->forget_ap_cb != NULL)
+                               local_handle->forget_ap_cb(result,
+                                                          local_handle->forget_ap_user_data);
+
+                       local_handle->forget_ap_cb = NULL;
+                       local_handle->forget_ap_user_data = NULL;
+               }
+       }
+}
+
 static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
 {
        bool is_requested = false;
@@ -1332,6 +1366,10 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
                WIFI_LOG(WIFI_INFO, "Got Wi-Fi multi scan IND\n"); //LCOV_EXCL_LINE
                __multi_scan_cb(event_cb); //LCOV_EXCL_LINE
                break;
+       case NET_EVENT_WIFI_FORGET_AP_IND:
+               WIFI_LOG(WIFI_INFO, "Got Wi-Fi forget AP IND\n"); //LCOV_EXCL_LINE
+               __forget_ap_cb(event_cb->Error); //LCOV_EXCL_LINE
+               break;
        default:
                break;
        }
@@ -1467,6 +1505,10 @@ int _wifi_get_callback_count_from_handle_list(wifi_manager_handle_cb_e e)
                        if (local_handle->netlink_scan_cb)
                                ++count;
                        break;
+               case WIFI_MANAGER_FORGET_AP_CB:
+                       if (local_handle->forget_ap_cb)
+                               ++count;
+                       break;
                default:
                        break;
                }
@@ -2488,6 +2530,43 @@ int _wifi_forget_ap(wifi_manager_ap_h ap)
        return WIFI_MANAGER_ERROR_NONE;
 }
 
+int _wifi_forget_ap_async(wifi_manager_h wifi, wifi_manager_ap_h ap,
+                         wifi_manager_forget_ap_finished_cb callback,
+                         void* user_data)
+{
+       int rv = 0;
+       GSList *list;
+       net_profile_info_s *ap_info = ap;
+
+       if (ap_info == NULL) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
+       }
+
+       if (_wifi_get_callback_count_from_handle_list(WIFI_MANAGER_FORGET_AP_CB)) {
+               for (list = wifi_manager_handle_list; list; list = list->next) {
+                       wifi_manager_handle_s *local_handle = (wifi_manager_handle_s *)list->data;
+                       if (local_handle->forget_ap_cb != NULL) {
+                               WIFI_LOG(WIFI_ERROR, "Already in progress"); //LCOV_EXCL_LINE
+                               return WIFI_MANAGER_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
+                       }
+               }
+       }
+
+       rv = net_delete_profile_async(ap_info->ProfileName);
+       if (rv == NET_ERR_ACCESS_DENIED) {
+               WIFI_LOG(WIFI_ERROR, "Access denied"); //LCOV_EXCL_LINE
+               return WIFI_MANAGER_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
+       } else if (rv != NET_ERR_NONE) {
+               return WIFI_MANAGER_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       ap_info->Favourite = (char)FALSE;
+       __set_forget_ap_cb(wifi, callback, user_data);
+
+       return WIFI_MANAGER_ERROR_NONE;
+}
+
 //LCOV_EXCL_START
 void _wifi_rssi_level_changed_cb(keynode_t *node, void *user_data)
 {
index bcb3a1c..26ea7bc 100755 (executable)
@@ -776,6 +776,31 @@ EXPORT_API int wifi_manager_forget_ap(wifi_manager_h wifi, wifi_manager_ap_h ap)
        return _wifi_forget_ap(ap);
 }
 
+EXPORT_API int wifi_manager_forget_ap_async(wifi_manager_h wifi, wifi_manager_ap_h ap,
+                                           wifi_manager_forget_ap_finished_cb callback,
+                                           void *user_data)
+
+{
+       __NETWORK_CAPI_FUNC_ENTER__;
+
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+
+       if (!(__wifi_check_handle_validity(wifi))) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
+               __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
+       }
+
+       if (_wifi_check_ap_validity(ap) == false) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
+               __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
+       }
+
+       __NETWORK_CAPI_FUNC_EXIT__;
+       return _wifi_forget_ap_async(wifi, ap, callback, user_data);
+}
+
 EXPORT_API int wifi_manager_update_ap(wifi_manager_h wifi, wifi_manager_ap_h ap)
 {
        __NETWORK_CAPI_FUNC_ENTER__;
index 0252d6e..4656c72 100755 (executable)
@@ -465,6 +465,41 @@ static bool __test_found_forget_ap_callback(wifi_manager_ap_h ap, void *user_dat
        return true;
 }
 
+static void __test_forget_ap_finished_cb(wifi_manager_error_e result, void *user_data)
+{
+       printf("Forget AP callback %s, error: [%s]\n",
+              (result == WIFI_MANAGER_ERROR_NONE) ? "succeeded" : "failed",
+              __test_convert_error_to_string(result));
+}
+
+static bool __test_found_forget_ap_async_callback(wifi_manager_ap_h ap, void *user_data)
+{
+       int rv = 0;
+       char *ap_name = NULL;
+       char *ap_name_part = (char*)user_data;
+
+       rv = wifi_manager_ap_get_essid(ap, &ap_name);
+       if (rv != WIFI_MANAGER_ERROR_NONE) {
+               printf("Fail to get AP name [%s]\n", __test_convert_error_to_string(rv));
+               return false;
+       }
+
+       if (__test_compare_ap_name(ap_name, ap_name_part)) {
+               rv = wifi_manager_forget_ap_async(wifi, ap,
+                                                 __test_forget_ap_finished_cb, NULL);
+               if (rv != WIFI_MANAGER_ERROR_NONE)
+                       printf("Fail to forget [%s] : %s\n", ap_name, __test_convert_error_to_string(rv));
+               else
+                       printf("Success to forget [%s]\n", ap_name);
+
+               g_free(ap_name);
+               return false;
+       }
+
+       g_free(ap_name);
+       return true;
+}
+
 static bool __test_found_eap_ap_callback(wifi_manager_ap_h ap, void *user_data)
 {
        int rv = 0;
@@ -1910,21 +1945,37 @@ int test_wifi_manager_forget_ap(void)
        int rv = 0;
        char ap_name[33];
        bool state = false;
+       int use_async;
 
        wifi_manager_is_activated(wifi, &state);
        if (state == false)
                return -1;
 
+       printf("Forget AP using async API? (0/1) : ");
+       rv = scanf("%1d", &use_async);
+
        printf("Input a part of AP name to forget : ");
        rv = scanf("%32s", ap_name);
 
-       rv = wifi_manager_foreach_found_ap(wifi, __test_found_forget_ap_callback, ap_name);
-       if (rv != WIFI_MANAGER_ERROR_NONE) {
-               printf("Fail to forget (can't get AP list) [%s]\n", __test_convert_error_to_string(rv));
-               return -1;
+       if (use_async) {
+               rv = wifi_manager_foreach_found_ap(wifi, __test_found_forget_ap_async_callback, ap_name);
+               if (rv != WIFI_MANAGER_ERROR_NONE) {
+                       printf("Fail to forget (can't get AP list) [%s]\n", __test_convert_error_to_string(rv));
+                       return -1;
+               }
+
+               printf("Forget AP async finished\n");
+
+       } else {
+               rv = wifi_manager_foreach_found_ap(wifi, __test_found_forget_ap_callback, ap_name);
+               if (rv != WIFI_MANAGER_ERROR_NONE) {
+                       printf("Fail to forget (can't get AP list) [%s]\n", __test_convert_error_to_string(rv));
+                       return -1;
+               }
+
+               printf("Forget AP finished\n");
        }
 
-       printf("Forget AP finished\n");
        return 1;
 }