Add dbus methods for setting bg scan interval
[platform/core/connectivity/net-config.git] / src / wifi-background-scan.c
index 09874ef..0aa25a7 100755 (executable)
 #include "util.h"
 #include "netdbus.h"
 #include "wifi-state.h"
+#include "wifi-scan.h"
 #include "wifi-background-scan.h"
 
-struct bgscan_data {
-       guint time;
-       guint mode;
-       guint timer_id;
-       gboolean paused;
-};
-
-static gboolean netconfig_wifi_scanning = FALSE;
-
-static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data);
-
-static struct bgscan_data *__netconfig_wifi_bgscan_get_data(void)
-{
-       static struct bgscan_data data = {
-               SCAN_EXPONENTIAL_MIN, WIFI_BGSCAN_MODE_EXPONENTIAL, 0, FALSE};
-
-       return &data;
-}
-
-static gboolean __netconfig_wifi_bgscan_set_mode(guint mode)
-{
-       if (mode != WIFI_BGSCAN_MODE_EXPONENTIAL && mode != WIFI_BGSCAN_MODE_PERIODIC) {
-               ERR("Invalid scan mode [%d]", mode);
-               return FALSE;
-       }
-
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
-       data->mode = mode;
-
-       return TRUE;
-}
-
-static gboolean _set_scan_reset_interval(guint interval)
-{
-       if ((interval < SCAN_EXPONENTIAL_MIN) || (interval > SCAN_EXPONENTIAL_MAX)) {
-               ERR("Invalid interval [%d]", interval);
-               return FALSE;
-       }
-
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
-       data->time = interval;
-       return TRUE;
-}
-
-static guint _get_scan_reset_interval(void)
+void netconfig_wifi_bgscan_start(const char *interface_name, gboolean immediate_scan)
 {
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
-
-       return data->time;;
-}
-
-static void __netconfig_wifi_scan_request_reply(GObject *source_object,
-               GAsyncResult *res, gpointer user_data)
-{
-       GVariant *reply;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-
-       conn = G_DBUS_CONNECTION(source_object);
-       reply = g_dbus_connection_call_finish(conn, res, &error);
-
-       if (reply == NULL) {
-               if (error != NULL) {
-                       ERR("Fail to request status [%d: %s]", error->code, error->message);
-                       netconfig_wifi_set_scanning(FALSE);
-                       g_error_free(error);
-               } else {
-                       ERR("Fail to request scan");
-                       netconfig_wifi_set_scanning(FALSE);
-               }
-       } else {
-               DBG("Successfully requested");
-               g_variant_unref(reply);
-       }
-
-       netconfig_gdbus_pending_call_unref();
-}
-
-static gboolean __netconfig_wifi_bgscan_request_connman_scan(int retries)
-{
-       gboolean reply = FALSE;
-
-       netconfig_wifi_set_scanning(TRUE);
-
-       reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
-                       CONNMAN_WIFI_TECHNOLOGY_PREFIX,
-                       CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL, __netconfig_wifi_scan_request_reply);
-       if (reply != TRUE) {
-               ERR("Failed to send Scan request to connman");
-               netconfig_wifi_set_scanning(FALSE);
-       }
-
-       return reply;
-}
-
-static gboolean __netconfig_wifi_bgscan_immediate_scan(gpointer data)
-{
-       static int retries = 0;
-       guint state = wifi_state_get_service_state();
-
-#if !defined TIZEN_WEARABLE
-       if (netconfig_wifi_is_bgscan_paused()) {
-               return FALSE;
-       }
-#endif
-
-       if (state == NETCONFIG_WIFI_CONNECTED) {
-               if (netconfig_wifi_bgscan_get_mode() == WIFI_BGSCAN_MODE_EXPONENTIAL) {
-                       DBG("Wi-Fi state is connected, scan is paused");
-                       return FALSE;
-               }
-       } else if (state == NETCONFIG_WIFI_ASSOCIATION || state == NETCONFIG_WIFI_CONFIGURATION) {
-               /* During WIFI connecting, WIFI can be disappeared.
-                * After 1 sec, try scan even if connecting state */
-               if (retries < 2) {
-                       retries++;
-                       return TRUE;
-               }
-       }
+       wifi_tech_state_e wifi_tech_state;
+       wifi_service_state_e wifi_service_state;
+       int ug_state = VCONFKEY_WIFI_UG_RUN_STATE_OFF;
+       guint bg_mode = WIFI_BGSCAN_MODE_EXPONENTIAL;
 
-       if (__netconfig_wifi_bgscan_request_connman_scan(retries) == TRUE) {
-               retries = 0;
-               return FALSE;
-       } else if (retries > 2) {
-               retries = 0;
-               return FALSE;
-       }
+       netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state);
 
-       retries++;
+       if (netconfig_wifi_bgscan_get_timer_id(interface_name) > 0)
+               netconfig_wifi_bgscan_stop_timer(interface_name);
 
-       return TRUE;
-}
+       wifi_tech_state = wifi_state_get_technology_state(interface_name);
+       wifi_service_state = wifi_state_get_service_state(interface_name);
+       DBG("[%s] Wi-Fi tech state [%s] service state [%s]", interface_name,
+               _convert_wifi_technology_state_to_string(wifi_tech_state),
+               _convert_wifi_service_state_to_string(wifi_service_state));
 
-static void __netconfig_wifi_bgscan_start_timer(gboolean immediate_scan)
-{
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
-
-       netconfig_stop_timer(&(data->timer_id));
-
-       switch (data->mode) {
-       case WIFI_BGSCAN_MODE_EXPONENTIAL:
-               if (data->time < SCAN_EXPONENTIAL_MIN ||
-                       data->time == SCAN_PERIODIC_DELAY)
-                       data->time = SCAN_EXPONENTIAL_MIN;
-               break;
-       case WIFI_BGSCAN_MODE_PERIODIC:
-               data->time = SCAN_PERIODIC_DELAY;
-               break;
-       default:
-               DBG("Invalid Wi-Fi background scan mode[%d]", data->mode);
+       if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED)
                return;
-       }
 
-       if (immediate_scan)
-               DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic)", immediate_scan, data->mode);
-       else
-               DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]", immediate_scan, data->mode, data->time);
+       bg_mode = netconfig_wifi_bgscan_get_mode(interface_name);
 
-       if (immediate_scan)
-               g_timeout_add(500, __netconfig_wifi_bgscan_immediate_scan, NULL);
+       if (wifi_service_state == NETCONFIG_WIFI_CONNECTED &&
+                       (bg_mode == WIFI_BGSCAN_MODE_EXPONENTIAL ||
+                       (bg_mode == WIFI_BGSCAN_MODE_PERIODIC &&
+                        ug_state != VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)))
+               return;
 
-       netconfig_start_timer_seconds(data->time,
-                               __netconfig_wifi_bgscan_next_scan, data, &(data->timer_id));
-       if (data->mode == WIFI_BGSCAN_MODE_EXPONENTIAL && immediate_scan) {
-               data->time = data->time * 2;
-               if (data->time > SCAN_EXPONENTIAL_MAX)
-                       data->time = SCAN_EXPONENTIAL_MAX;
-       }
+       DBG("[%s] Wi-Fi background scan started or re-started(%d)",
+                       interface_name, immediate_scan);
 
-       //DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]", immediate_scan, data->mode, data->time);
+       netconfig_wifi_bgscan_start_timer(interface_name, immediate_scan);
 }
 
-static void __netconfig_wifi_bgscan_stop_timer(struct bgscan_data *data)
+void netconfig_wifi_bgscan_stop(const char *interface_name)
 {
-       if (data == NULL)
-               return;
-
-       netconfig_stop_timer(&(data->timer_id));
+       netconfig_wifi_bgscan_stop_timer(interface_name);
 }
 
-static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data)
+void netconfig_wifi_bgscan_restart(const gchar *interface_name)
 {
        int pm_state = VCONFKEY_PM_STATE_NORMAL;
 
-       /* In case of LCD off, we don't need Wi-Fi scan */
+       /* In case of LCD off, we don't need Wi-Fi scan right now */
        netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
        if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
-               return TRUE;
-
-       __netconfig_wifi_bgscan_start_timer(TRUE);
-
-       return FALSE;
-}
-
-void netconfig_wifi_set_bgscan_pause(gboolean pause)
-{
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
-       DBG("[%s] Wi-Fi background scan", pause ? "Pause" : "Resume");
-       data->paused = pause;
-}
-
-gboolean netconfig_wifi_is_bgscan_paused(void)
-{
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
-       DBG("Wi-Fi background scan is [%s]", data->paused ? "Paused" : "Runnable");
-       return data->paused;
-}
-
-void netconfig_wifi_bgscan_start(gboolean immediate_scan)
-{
-       wifi_tech_state_e wifi_tech_state;
-       wifi_service_state_e wifi_service_state;
-       struct bgscan_data *data =
-                       __netconfig_wifi_bgscan_get_data();
-
-       if (data == NULL)
-               return;
-
-       if (data->timer_id > 0)
-               __netconfig_wifi_bgscan_stop_timer(data);
-
-       wifi_tech_state = wifi_state_get_technology_state();
-       wifi_service_state = wifi_state_get_service_state();
-       DBG("wifi tech state [%s] service state [%s]",
-               _convert_wifi_technology_state_to_string(wifi_tech_state),
-               _convert_wifi_service_state_to_string(wifi_service_state));
-
-       if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED)
-               return;
-
-       if (data->mode == WIFI_BGSCAN_MODE_EXPONENTIAL &&
-               wifi_service_state == NETCONFIG_WIFI_CONNECTED)
-               return;
-
-       DBG("Wi-Fi background scan started or re-started(%d)", immediate_scan);
-       __netconfig_wifi_bgscan_start_timer(immediate_scan);
+               netconfig_wifi_bgscan_start(interface_name, FALSE);
+       else
+               netconfig_wifi_bgscan_start(interface_name, TRUE);
 }
 
-void netconfig_wifi_bgscan_stop(void)
+gboolean handle_set_bgscan(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname, guint scan_mode)
 {
-       struct bgscan_data *data =
-                       __netconfig_wifi_bgscan_get_data();
+       gint old_mode = 0;
 
-       if (data == NULL)
-               return;
+       old_mode = netconfig_wifi_bgscan_get_mode(ifname);
+       if (old_mode == scan_mode) {
+               wifi_complete_set_bgscan(wifi, context);
+               return TRUE;
+       }
 
-       DBG("Wi-Fi background scan stop [mode:%d]", data->mode);
+       if (netconfig_wifi_bgscan_set_mode(ifname, scan_mode) != TRUE) {
+               ERR("Invalid mode [%d]", scan_mode);
+               netconfig_error_invalid_parameter(context);
+               return TRUE;
+       }
 
-       data->time = 0;
+       INFO("[%s] Wi-Fi scan mode is changed [%d]", ifname, scan_mode);
 
-       __netconfig_wifi_bgscan_stop_timer(data);
-}
+       netconfig_wifi_bgscan_restart(ifname);
 
-gboolean netconfig_wifi_get_bgscan_state(void)
-{
-       struct bgscan_data *data =
-                       __netconfig_wifi_bgscan_get_data();
-       return ((data->timer_id > (guint)0) ? TRUE : FALSE);
+       wifi_complete_set_bgscan(wifi, context);
+       return TRUE;
 }
 
-guint netconfig_wifi_bgscan_get_mode(void)
+gboolean handle_set_bgscan_interval(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname, const gchar *mode, guint interval)
 {
-       struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
+       guint old_interval = 0;
+       gboolean rv = FALSE;
 
-       return data->mode;
-}
+       if (g_strcmp0(mode, "Periodic") == 0) {
+               old_interval = netconfig_wifi_bgscan_get_periodic_interval(ifname);
+       } else if (g_strcmp0(mode, "Exponential") == 0) {
+               old_interval = netconfig_wifi_bgscan_get_exp_interval(ifname);
+       } else {
+               ERR("invalid mode %s", mode);
+               netconfig_error_invalid_parameter(context);
+               return TRUE;
+       }
 
-gboolean netconfig_wifi_bgscan_set_interval(guint interval)
-{
-       gboolean ret = FALSE;
+       if (old_interval == interval) {
+               wifi_complete_set_bgscan_interval(wifi, context);
+               return TRUE;
+       }
 
-       ret = _set_scan_reset_interval(interval);
+       if (g_strcmp0(mode, "Periodic") == 0)
+               rv = netconfig_wifi_bgscan_set_periodic_interval(ifname, interval);
+       else
+               rv = netconfig_wifi_bgscan_set_exp_interval(ifname, interval);
 
-       return ret;
-}
+       if (!rv) {
+               netconfig_error_invalid_parameter(context);
+               return TRUE;
+       }
 
-void netconfig_wifi_bgscan_get_interval(guint *interval)
-{
-       *interval = _get_scan_reset_interval();
-}
+       INFO("[%s] Wi-Fi periodic scan interval is changed to [%d] from [%d]",
+                       ifname, interval, old_interval);
 
-gboolean netconfig_wifi_get_scanning(void)
-{
-       return netconfig_wifi_scanning;
-}
+       netconfig_wifi_bgscan_restart(ifname);
 
-void netconfig_wifi_set_scanning(gboolean scanning)
-{
-       if (netconfig_wifi_scanning != scanning)
-               netconfig_wifi_scanning = scanning;
+       wifi_complete_set_bgscan_interval(wifi, context);
+       return TRUE;
 }
 
-gboolean handle_set_bgscan(Wifi *wifi, GDBusMethodInvocation *context, guint scan_mode)
+gboolean handle_get_bgscan_interval(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname, const gchar *mode)
 {
-       gint old_mode = 0;
-       int pm_state = VCONFKEY_PM_STATE_NORMAL;
-
-       old_mode = netconfig_wifi_bgscan_get_mode();
-       if (old_mode == scan_mode) {
-               wifi_complete_set_bgscan(wifi, context);
-               return TRUE;
-       }
+       guint bgscan_interval = 0;
 
-       if (__netconfig_wifi_bgscan_set_mode(scan_mode) != TRUE) {
-               ERR("Invalid mode [%d]", scan_mode);
+       if (g_strcmp0(mode, "Periodic") == 0) {
+               bgscan_interval = netconfig_wifi_bgscan_get_periodic_interval(ifname);
+       } else if (g_strcmp0(mode, "Exponential") == 0) {
+               bgscan_interval = netconfig_wifi_bgscan_get_exp_interval(ifname);
+       } else {
+               ERR("invalid mode %s", mode);
                netconfig_error_invalid_parameter(context);
                return TRUE;
        }
 
-       INFO("scan mode is changed [%d]", scan_mode);
-
-       /* In case of LCD off, we don't need Wi-Fi scan right now */
-       netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
-       if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
-               netconfig_wifi_bgscan_start(FALSE);
-       else
-               netconfig_wifi_bgscan_start(TRUE);
-
-       wifi_complete_set_bgscan(wifi, context);
+       wifi_complete_get_bgscan_interval(wifi, context, bgscan_interval);
        return TRUE;
 }
 
-gboolean handle_resume_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_resume_bgscan(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname)
 {
-       netconfig_wifi_set_bgscan_pause(FALSE);
+       netconfig_wifi_bgscan_set_pause(ifname, FALSE);
 
        wifi_complete_resume_bgscan(wifi, context);
        return TRUE;
 }
 
-gboolean handle_pause_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_pause_bgscan(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname)
 {
-       netconfig_wifi_set_bgscan_pause(TRUE);
+       netconfig_wifi_bgscan_set_pause(ifname, TRUE);
 
        wifi_complete_pause_bgscan(wifi, context);
        return TRUE;
 }
 
-gboolean handle_reset_bgscan_interval(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_reset_bgscan_interval(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname)
 {
-
-       _set_scan_reset_interval(SCAN_EXPONENTIAL_MIN);
+       netconfig_wifi_bgscan_set_exp_interval(ifname, SCAN_EXPONENTIAL_MIN);
 
        wifi_complete_reset_bgscan_interval(wifi, context);
        return TRUE;
 }
 
-gboolean handle_get_autoscan(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_get_autoscan(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname)
 {
 
        gboolean autoscan = 0;
 
-       autoscan = netconfig_wifi_is_bgscan_paused();
+       autoscan = netconfig_wifi_bgscan_is_paused(ifname);
 
        wifi_complete_get_autoscan(wifi, context, autoscan);
        return TRUE;
 }
 
-gboolean handle_get_autoscanmode(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_get_autoscanmode(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname)
 {
        guint autoscanmode = 0;
 
-       autoscanmode = netconfig_wifi_bgscan_get_mode();
+       autoscanmode = netconfig_wifi_bgscan_get_mode(ifname);
 
        wifi_complete_get_autoscanmode(wifi, context, autoscanmode);
        return TRUE;