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()) {
136 if (state == NETCONFIG_WIFI_CONNECTED) {
137 if (netconfig_wifi_bgscan_get_mode() == WIFI_BGSCAN_MODE_EXPONENTIAL) {
138 DBG("Wi-Fi state is connected, scan is paused");
141 } else if (state == NETCONFIG_WIFI_ASSOCIATION || state == NETCONFIG_WIFI_CONFIGURATION) {
142 /* During WIFI connecting, WIFI can be disappeared.
143 * After 1 sec, try scan even if connecting state */
150 if (__netconfig_wifi_bgscan_request_connman_scan(retries) == TRUE) {
153 } else if (retries > 2) {
163 static void __netconfig_wifi_bgscan_start_timer(gboolean immediate_scan)
165 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
167 netconfig_stop_timer(&(data->timer_id));
169 switch (data->mode) {
170 case WIFI_BGSCAN_MODE_EXPONENTIAL:
171 if (data->time < SCAN_EXPONENTIAL_MIN ||
172 data->time == SCAN_PERIODIC_DELAY)
173 data->time = SCAN_EXPONENTIAL_MIN;
175 case WIFI_BGSCAN_MODE_PERIODIC:
176 data->time = SCAN_PERIODIC_DELAY;
179 DBG("Invalid Wi-Fi background scan mode[%d]", data->mode);
184 DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic)", immediate_scan, data->mode);
186 DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]", immediate_scan, data->mode, data->time);
189 g_timeout_add(500, __netconfig_wifi_bgscan_immediate_scan, NULL);
191 netconfig_start_timer_seconds(data->time,
192 __netconfig_wifi_bgscan_next_scan, data, &(data->timer_id));
193 if (data->mode == WIFI_BGSCAN_MODE_EXPONENTIAL && immediate_scan) {
194 data->time = data->time * 2;
195 if (data->time > SCAN_EXPONENTIAL_MAX)
196 data->time = SCAN_EXPONENTIAL_MAX;
199 //DBG("Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]", immediate_scan, data->mode, data->time);
202 static void __netconfig_wifi_bgscan_stop_timer(struct bgscan_data *data)
207 netconfig_stop_timer(&(data->timer_id));
210 static gboolean __netconfig_wifi_bgscan_next_scan(gpointer data)
212 int pm_state = VCONFKEY_PM_STATE_NORMAL;
214 /* In case of LCD off, we don't need Wi-Fi scan */
215 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
216 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
219 __netconfig_wifi_bgscan_start_timer(TRUE);
224 void netconfig_wifi_set_bgscan_pause(gboolean pause)
226 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
227 DBG("[%s] Wi-Fi background scan", pause ? "Pause" : "Resume");
228 data->paused = pause;
231 gboolean netconfig_wifi_is_bgscan_paused(void)
233 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
234 DBG("Wi-Fi background scan is [%s]", data->paused ? "Paused" : "Runnable");
238 void netconfig_wifi_bgscan_start(gboolean immediate_scan)
240 wifi_tech_state_e wifi_tech_state;
241 wifi_service_state_e wifi_service_state;
242 struct bgscan_data *data =
243 __netconfig_wifi_bgscan_get_data();
248 if (data->timer_id > 0)
249 __netconfig_wifi_bgscan_stop_timer(data);
251 wifi_tech_state = wifi_state_get_technology_state();
252 wifi_service_state = wifi_state_get_service_state();
253 DBG("wifi tech state [%s] service state [%s]",
254 _convert_wifi_technology_state_to_string(wifi_tech_state),
255 _convert_wifi_service_state_to_string(wifi_service_state));
257 if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED)
260 if (data->mode == WIFI_BGSCAN_MODE_EXPONENTIAL &&
261 wifi_service_state == NETCONFIG_WIFI_CONNECTED)
264 DBG("Wi-Fi background scan started or re-started(%d)", immediate_scan);
265 __netconfig_wifi_bgscan_start_timer(immediate_scan);
268 void netconfig_wifi_bgscan_stop(void)
270 struct bgscan_data *data =
271 __netconfig_wifi_bgscan_get_data();
276 DBG("Wi-Fi background scan stop [mode:%d]", data->mode);
280 __netconfig_wifi_bgscan_stop_timer(data);
283 gboolean netconfig_wifi_get_bgscan_state(void)
285 struct bgscan_data *data =
286 __netconfig_wifi_bgscan_get_data();
287 return ((data->timer_id > (guint)0) ? TRUE : FALSE);
290 guint netconfig_wifi_bgscan_get_mode(void)
292 struct bgscan_data *data = __netconfig_wifi_bgscan_get_data();
297 gboolean netconfig_wifi_bgscan_set_interval(guint interval)
299 gboolean ret = FALSE;
301 ret = _set_scan_reset_interval(interval);
306 void netconfig_wifi_bgscan_get_interval(guint *interval)
308 *interval = _get_scan_reset_interval();
311 gboolean netconfig_wifi_get_scanning(void)
313 return netconfig_wifi_scanning;
316 void netconfig_wifi_set_scanning(gboolean scanning)
318 if (netconfig_wifi_scanning != scanning)
319 netconfig_wifi_scanning = scanning;
322 gboolean handle_set_bgscan(Wifi *wifi, GDBusMethodInvocation *context, guint scan_mode)
325 int pm_state = VCONFKEY_PM_STATE_NORMAL;
327 old_mode = netconfig_wifi_bgscan_get_mode();
328 if (old_mode == scan_mode) {
329 wifi_complete_set_bgscan(wifi, context);
333 if (__netconfig_wifi_bgscan_set_mode(scan_mode) != TRUE) {
334 ERR("Invalid mode [%d]", scan_mode);
335 netconfig_error_invalid_parameter(context);
339 INFO("scan mode is changed [%d]", scan_mode);
341 /* In case of LCD off, we don't need Wi-Fi scan right now */
342 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
343 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
344 netconfig_wifi_bgscan_start(FALSE);
346 netconfig_wifi_bgscan_start(TRUE);
348 wifi_complete_set_bgscan(wifi, context);
352 gboolean handle_resume_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
354 netconfig_wifi_set_bgscan_pause(FALSE);
356 wifi_complete_resume_bgscan(wifi, context);
360 gboolean handle_pause_bgscan(Wifi *wifi, GDBusMethodInvocation *context)
362 netconfig_wifi_set_bgscan_pause(TRUE);
364 wifi_complete_pause_bgscan(wifi, context);
368 gboolean handle_reset_bgscan_interval(Wifi *wifi, GDBusMethodInvocation *context)
371 _set_scan_reset_interval(SCAN_EXPONENTIAL_MIN);
373 wifi_complete_reset_bgscan_interval(wifi, context);
377 gboolean handle_get_autoscan(Wifi *wifi, GDBusMethodInvocation *context)
380 gboolean autoscan = 0;
382 autoscan = netconfig_wifi_is_bgscan_paused();
384 wifi_complete_get_autoscan(wifi, context, autoscan);
388 gboolean handle_get_autoscanmode(Wifi *wifi, GDBusMethodInvocation *context)
390 guint autoscanmode = 0;
392 autoscanmode = netconfig_wifi_bgscan_get_mode();
394 wifi_complete_get_autoscanmode(wifi, context, autoscanmode);