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"
37 static gboolean netconfig_wifi_scanning = FALSE;
39 static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data);
41 static struct bgscan_data *__netconfig_wifi_bgscan_get_data(void)
43 static struct bgscan_data data = {
44 SCAN_EXPONENTIAL_MIN, WIFI_BGSCAN_MODE_EXPONENTIAL, 0, FALSE};
49 static gboolean __netconfig_wifi_bgscan_set_mode(guint mode)
51 if (mode != WIFI_BGSCAN_MODE_EXPONENTIAL && mode != WIFI_BGSCAN_MODE_PERIODIC) {
52 ERR("Invalid scan mode [%d]", mode);
56 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
62 static gboolean _set_scan_reset_interval(guint interval)
64 if ((interval < SCAN_EXPONENTIAL_MIN) || (interval > SCAN_EXPONENTIAL_MAX)) {
65 ERR("Invalid interval [%d]", interval);
69 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
70 data->time = interval;
74 static guint _get_scan_reset_interval(void)
76 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
81 static void __netconfig_wifi_scan_request_reply(GObject *source_object,
82 GAsyncResult *res, gpointer user_data)
85 GDBusConnection *conn = NULL;
88 conn = G_DBUS_CONNECTION(source_object);
89 reply = g_dbus_connection_call_finish(conn, res, &error);
93 ERR("Fail to request status [%d: %s]", error->code, error->message);
94 netconfig_wifi_set_scanning(FALSE);
97 ERR("Fail to request scan");
98 netconfig_wifi_set_scanning(FALSE);
101 DBG("Successfully requested");
102 g_variant_unref(reply);
105 netconfig_gdbus_pending_call_unref();
108 static gboolean __netconfig_wifi_bgscan_request_connman_scan(int retries)
110 gboolean reply = FALSE;
112 netconfig_wifi_set_scanning(TRUE);
114 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
115 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
116 CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL, __netconfig_wifi_scan_request_reply);
118 ERR("Failed to send Scan request to connman");
119 netconfig_wifi_set_scanning(FALSE);
125 static gboolean __netconfig_wifi_bgscan_immediate_scan(gpointer data)
127 static int retries = 0;
128 guint state = wifi_state_get_service_state();
130 #if !defined TIZEN_WEARABLE
131 if (netconfig_wifi_is_bgscan_paused()) {
135 if (netconfig_wifi_block_bgscan(-1))
138 if (state == NETCONFIG_WIFI_CONNECTED) {
139 if (netconfig_wifi_bgscan_get_mode() == WIFI_BGSCAN_MODE_EXPONENTIAL) {
140 DBG("Wi-Fi state is connected, scan is paused");
143 } else if (state == NETCONFIG_WIFI_ASSOCIATION || state == NETCONFIG_WIFI_CONFIGURATION) {
144 /* During WIFI connecting, WIFI can be disappeared.
145 * After 1 sec, try scan even if connecting state */
152 if (__netconfig_wifi_bgscan_request_connman_scan(retries) == TRUE) {
155 } else if (retries > 2) {
165 static void __netconfig_wifi_bgscan_start_timer(gboolean immediate_scan)
167 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
169 netconfig_stop_timer(&(data->timer_id));
171 switch (data->mode) {
172 case WIFI_BGSCAN_MODE_EXPONENTIAL:
173 if (data->time < SCAN_EXPONENTIAL_MIN ||
174 data->time == SCAN_PERIODIC_DELAY)
175 data->time = SCAN_EXPONENTIAL_MIN;
177 case WIFI_BGSCAN_MODE_PERIODIC:
178 data->time = SCAN_PERIODIC_DELAY;
181 DBG("Invalid Wi-Fi background scan mode[%d]", data->mode);
186 DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic)", immediate_scan, data->mode);
188 DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]", immediate_scan, data->mode, data->time);
191 g_timeout_add(500, __netconfig_wifi_bgscan_immediate_scan, NULL);
193 netconfig_start_timer_seconds(data->time,
194 __netconfig_wifi_bgscan_next_scan, data, &(data->timer_id));
195 if (data->mode == WIFI_BGSCAN_MODE_EXPONENTIAL && immediate_scan) {
196 data->time = data->time * 2;
197 if (data->time > SCAN_EXPONENTIAL_MAX)
198 data->time = SCAN_EXPONENTIAL_MAX;
201 //DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]", immediate_scan, data->mode, data->time);
204 static void __netconfig_wifi_bgscan_stop_timer(struct bgscan_data *data)
209 netconfig_stop_timer(&(data->timer_id));
212 static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data)
214 int pm_state = VCONFKEY_PM_STATE_NORMAL;
216 /* In case of LCD off, we don't need Wi-Fi scan */
217 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
218 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
221 __netconfig_wifi_bgscan_start_timer(TRUE);
226 gboolean netconfig_wifi_block_bgscan(int status)
228 static gboolean blocked = FALSE;
232 else if (status == 0)
238 void netconfig_wifi_set_bgscan_pause(gboolean pause)
240 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
241 DBG("[%s] Wi-Fi background scan", pause ? "Pause" : "Resume");
242 data->paused = pause;
245 gboolean netconfig_wifi_is_bgscan_paused(void)
247 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
248 DBG("Wi-Fi background scan is [%s]", data->paused ? "Paused" : "Runable");
252 void netconfig_wifi_bgscan_start(gboolean immediate_scan)
254 wifi_tech_state_e wifi_tech_state;
255 wifi_service_state_e wifi_service_state;
256 struct bgscan_data *data =
257 __netconfig_wifi_bgscan_get_data();
262 if (data->timer_id > 0)
263 __netconfig_wifi_bgscan_stop_timer(data);
265 wifi_tech_state = wifi_state_get_technology_state(FALSE);
266 wifi_service_state = wifi_state_get_service_state();
267 DBG("wifi tech state [%s] service state [%s]",
268 _convert_wifi_technology_state_to_string(wifi_tech_state),
269 _convert_wifi_service_state_to_string(wifi_service_state));
271 if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED)
274 if (data->mode == WIFI_BGSCAN_MODE_EXPONENTIAL &&
275 wifi_service_state == NETCONFIG_WIFI_CONNECTED)
278 DBG("Wi-Fi background scan started or re-started(%d)", immediate_scan);
279 __netconfig_wifi_bgscan_start_timer(immediate_scan);
282 void netconfig_wifi_bgscan_stop(void)
284 struct bgscan_data *data =
285 __netconfig_wifi_bgscan_get_data();
290 DBG("Wi-Fi background scan stop [mode:%d]", data->mode);
294 __netconfig_wifi_bgscan_stop_timer(data);
297 gboolean netconfig_wifi_get_bgscan_state(void)
299 struct bgscan_data *data =
300 __netconfig_wifi_bgscan_get_data();
301 return ((data->timer_id > (guint)0) ? TRUE : FALSE);
304 guint netconfig_wifi_bgscan_get_mode(void)
306 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
311 gboolean netconfig_wifi_bgscan_set_interval(guint interval)
313 gboolean ret = FALSE;
315 ret = _set_scan_reset_interval(interval);
320 void netconfig_wifi_bgscan_get_interval(guint *interval)
322 *interval = _get_scan_reset_interval();
325 gboolean netconfig_wifi_get_scanning(void)
327 return netconfig_wifi_scanning;
330 void netconfig_wifi_set_scanning(gboolean scanning)
332 if (netconfig_wifi_scanning != scanning)
333 netconfig_wifi_scanning = scanning;
336 gboolean handle_set_bgscan(Wifi *wifi, GDBusMethodInvocation *context, guint scan_mode)
339 int pm_state = VCONFKEY_PM_STATE_NORMAL;
341 old_mode = netconfig_wifi_bgscan_get_mode();
342 if (old_mode == scan_mode) {
343 wifi_complete_set_bgscan(wifi, context);
347 if (__netconfig_wifi_bgscan_set_mode(scan_mode) != TRUE) {
348 ERR("Invalid mode [%d]", scan_mode);
349 netconfig_error_invalid_parameter(context);
353 INFO("scan mode is changed [%d]", scan_mode);
355 /* In case of LCD off, we don't need Wi-Fi scan right now */
356 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
357 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
358 netconfig_wifi_bgscan_start(FALSE);
360 netconfig_wifi_bgscan_start(TRUE);
362 wifi_complete_set_bgscan(wifi, context);
366 gboolean handle_resume_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
368 netconfig_wifi_set_bgscan_pause(FALSE);
370 wifi_complete_resume_bgscan(wifi, context);
374 gboolean handle_pause_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
376 netconfig_wifi_set_bgscan_pause(TRUE);
378 wifi_complete_pause_bgscan(wifi, context);
382 gboolean handle_reset_bgscan_interval(Wifi *wifi, GDBusMethodInvocation *context)
385 _set_scan_reset_interval(SCAN_EXPONENTIAL_MIN);
387 wifi_complete_reset_bgscan_interval(wifi, context);
391 gboolean handle_get_autoscan(Wifi *wifi, GDBusMethodInvocation *context)
394 gboolean autoscan = 0;
396 autoscan = netconfig_wifi_is_bgscan_paused();
398 wifi_complete_get_autoscan(wifi, context, autoscan);
402 gboolean handle_get_autoscanmode(Wifi *wifi, GDBusMethodInvocation *context)
404 guint autoscanmode = 0;
406 autoscanmode = netconfig_wifi_bgscan_get_mode();
408 wifi_complete_get_autoscanmode(wifi, context, autoscanmode);