2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include <vconf-keys.h>
27 #include "wifi-state.h"
28 #include "wifi-background-scan.h"
30 #if defined TIZEN_WEARABLE
31 #define SCAN_PERIODIC_DELAY 15
32 #define SCAN_EXPONENTIAL_MIN 5
33 #define SCAN_EXPONENTIAL_MAX 320
35 #define SCAN_PERIODIC_DELAY 10
36 #define SCAN_EXPONENTIAL_MIN 4
37 #define SCAN_EXPONENTIAL_MAX 128
41 WIFI_BGSCAN_MODE_EXPONENTIAL = 0x00,
42 WIFI_BGSCAN_MODE_PERIODIC,
46 struct bgscan_timer_data {
52 static gboolean netconfig_wifi_scanning = FALSE;
53 static gboolean netconfig_bgscan_paused = FALSE;
55 static struct bgscan_timer_data *__netconfig_wifi_bgscan_get_bgscan_data(void)
57 static struct bgscan_timer_data timer_data = {
58 SCAN_EXPONENTIAL_MIN, WIFI_BGSCAN_MODE_EXPONENTIAL, 0};
63 static guint __netconfig_wifi_bgscan_mode(gboolean is_set_mode, guint mode)
65 static guint bgscan_mode = WIFI_BGSCAN_MODE_EXPONENTIAL;
67 if (is_set_mode != TRUE)
70 if (mode < WIFI_BGSCAN_MODE_MAX)
73 DBG("Wi-Fi background scan mode set %d", bgscan_mode);
78 static void __netconfig_wifi_bgscan_set_mode(guint mode)
80 __netconfig_wifi_bgscan_mode(TRUE, mode);
83 static guint __netconfig_wifi_bgscan_get_mode(void)
85 return __netconfig_wifi_bgscan_mode(FALSE, -1);
88 static void __netconfig_wifi_scan_request_reply(GObject *source_object, GAsyncResult *res, gpointer user_data)
92 GDBusConnection *conn = NULL;
95 conn = G_DBUS_CONNECTION(source_object);
96 reply = g_dbus_connection_call_finish(conn, res, &error);
100 ERR("Fail to request status [%d: %s]", error->code, error->message);
101 netconfig_wifi_set_scanning(FALSE);
104 ERR("Fail to request scan");
105 netconfig_wifi_set_scanning(FALSE);
108 DBG("Successfully requested");
111 g_variant_unref(reply);
112 netconfig_gdbus_pending_call_unref();
115 static gboolean __netconfig_wifi_bgscan_request_connman_scan(int retries)
117 gboolean reply = FALSE;
118 guint state = wifi_state_get_service_state();
120 if (state == NETCONFIG_WIFI_CONNECTED)
121 if (__netconfig_wifi_bgscan_get_mode() == WIFI_BGSCAN_MODE_EXPONENTIAL)
124 if (state == NETCONFIG_WIFI_ASSOCIATION || state == NETCONFIG_WIFI_CONFIGURATION) {
125 /* During Wi-Fi connecting, Wi-Fi can be disappeared.
126 * After 1 sec, try scan even if connecting state */
131 netconfig_wifi_set_scanning(TRUE);
133 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
134 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
135 CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL, __netconfig_wifi_scan_request_reply);
137 netconfig_wifi_set_scanning(FALSE);
142 static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data);
144 static gboolean __netconfig_wifi_bgscan_immediate_scan(gpointer data)
146 static int retries = 0;
148 #if !defined TIZEN_WEARABLE
149 if (netconfig_wifi_is_bgscan_paused())
153 if (__netconfig_wifi_bgscan_request_connman_scan(retries) == TRUE) {
156 } else if (retries > 2) {
166 static void __netconfig_wifi_bgscan_start_timer(gboolean immediate_scan,
167 struct bgscan_timer_data *data)
172 netconfig_stop_timer(&(data->timer_id));
174 data->mode = __netconfig_wifi_bgscan_get_mode();
176 if (data->time < SCAN_EXPONENTIAL_MIN)
177 data->time = SCAN_EXPONENTIAL_MIN;
179 switch (data->mode) {
180 case WIFI_BGSCAN_MODE_EXPONENTIAL:
181 if (immediate_scan == TRUE) {
182 if ((data->time * 2) > SCAN_EXPONENTIAL_MAX)
183 data->time = SCAN_EXPONENTIAL_MAX;
185 data->time = data->time * 2;
189 case WIFI_BGSCAN_MODE_PERIODIC:
190 if ((data->time * 2) > SCAN_PERIODIC_DELAY)
191 data->time = SCAN_PERIODIC_DELAY;
193 data->time = data->time * 2;
197 DBG("Invalid Wi-Fi background scan mode[%d]", data->mode);
201 if (immediate_scan == TRUE)
202 g_timeout_add(500, __netconfig_wifi_bgscan_immediate_scan, NULL);
204 DBG("Scan immediately[%d], mode[%d], next[%d]",
205 immediate_scan, data->mode, data->time);
207 netconfig_start_timer_seconds(data->time,
208 __netconfig_wifi_bgscan_next_scan, data, &(data->timer_id));
211 static void __netconfig_wifi_bgscan_stop_timer(struct bgscan_timer_data *data)
216 netconfig_stop_timer(&(data->timer_id));
219 static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data)
221 struct bgscan_timer_data *timer = (struct bgscan_timer_data *)data;
222 int pm_state = VCONFKEY_PM_STATE_NORMAL;
227 /* In case of LCD off, we don't need Wi-Fi scan */
228 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
229 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
232 __netconfig_wifi_bgscan_start_timer(TRUE, timer);
237 void netconfig_wifi_set_bgscan_pause(gboolean pause)
239 DBG("[%s] Wi-Fi background scan", pause ? "Pause" : "Resume");
240 netconfig_bgscan_paused = pause;
243 gboolean netconfig_wifi_is_bgscan_paused(void)
245 DBG("Wi-Fi background scan is [%s]", netconfig_bgscan_paused ? "Paused" : "Runnable");
246 return netconfig_bgscan_paused;
249 void netconfig_wifi_bgscan_start(gboolean immediate_scan)
251 wifi_tech_state_e wifi_tech_state;
252 struct bgscan_timer_data *timer_data =
253 __netconfig_wifi_bgscan_get_bgscan_data();
255 if (timer_data == NULL)
258 wifi_tech_state = wifi_state_get_technology_state();
259 if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED)
262 DBG("Wi-Fi background scan started or re-started(%d)", immediate_scan);
264 __netconfig_wifi_bgscan_start_timer(immediate_scan, timer_data);
267 void netconfig_wifi_bgscan_stop(void)
269 struct bgscan_timer_data *timer_data =
270 __netconfig_wifi_bgscan_get_bgscan_data();
272 if (timer_data == NULL)
275 DBG("Wi-Fi background scan stop");
277 timer_data->time = SCAN_EXPONENTIAL_MIN;
279 __netconfig_wifi_bgscan_stop_timer(timer_data);
282 gboolean netconfig_wifi_get_bgscan_state(void)
284 struct bgscan_timer_data *timer_data =
285 __netconfig_wifi_bgscan_get_bgscan_data();
287 return ((timer_data->timer_id > (guint)0) ? TRUE : FALSE);
290 gboolean netconfig_wifi_get_scanning(void)
292 return netconfig_wifi_scanning;
295 void netconfig_wifi_set_scanning(gboolean scanning)
297 if (netconfig_wifi_scanning != scanning)
298 netconfig_wifi_scanning = scanning;
301 gboolean handle_set_bgscan(Wifi *wifi, GDBusMethodInvocation *context, guint scan_mode)
304 int pm_state = VCONFKEY_PM_STATE_NORMAL;
306 old_mode = __netconfig_wifi_bgscan_get_mode();
307 if (old_mode == scan_mode) {
308 wifi_complete_set_bgscan(wifi, context);
312 __netconfig_wifi_bgscan_set_mode(scan_mode);
314 netconfig_wifi_bgscan_stop();
316 /* In case of LCD off, we don't need Wi-Fi scan right now */
317 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
318 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
319 netconfig_wifi_bgscan_start(FALSE);
321 netconfig_wifi_bgscan_start(TRUE);
323 wifi_complete_set_bgscan(wifi, context);
327 gboolean handle_resume_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
329 netconfig_wifi_set_bgscan_pause(FALSE);
331 wifi_complete_resume_bgscan(wifi, context);
335 gboolean handle_pause_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
337 netconfig_wifi_set_bgscan_pause(TRUE);
339 wifi_complete_pause_bgscan(wifi, context);