2 * Network Configuration Module
4 * Copyright (c) 2020 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-scan.h"
31 const char *interface_name;
34 guint bg_exp_interval;
35 guint bg_periodic_interval;
41 gboolean bssid_enabled;
42 gboolean bssid_aborted;
43 gboolean bssid_scanning;
49 static GSList *g_scan_list = NULL;
51 static scan_data_s *__wifi_scan_create_data(const char *interface_name)
53 scan_data_s *scan_data = g_try_malloc0(sizeof(scan_data_s));
55 ERR("Memory allocation failed");
59 scan_data->interface_name = g_strdup(interface_name);
61 scan_data->scanning = FALSE;
63 scan_data->bg_exp_interval = SCAN_EXPONENTIAL_MIN;
64 scan_data->bg_periodic_interval = SCAN_PERIODIC_DELAY;
65 scan_data->bg_mode = WIFI_BGSCAN_MODE_EXPONENTIAL;
66 scan_data->bg_timer_id = 0;
67 scan_data->bg_paused = FALSE;
69 scan_data->bssid_enabled = FALSE;
70 scan_data->bssid_aborted = FALSE;
71 scan_data->bssid_scanning = FALSE;
73 g_scan_list = g_slist_append(g_scan_list, scan_data);
78 static scan_data_s *__wifi_scan_get_data(const char *interface_name)
81 scan_data_s *scan_data;
83 for (list = g_scan_list; list; list = list->next) {
84 scan_data = list->data;
85 if (g_strcmp0(scan_data->interface_name, interface_name) == 0)
89 scan_data = __wifi_scan_create_data(interface_name);
93 void netconfig_wifi_scan_set_scanning(const char *interface_name, gboolean scanning)
95 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
100 scan_data->scanning = scanning;
103 guint netconfig_wifi_scan_get_scanning(const char *interface_name)
105 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
110 return scan_data->scanning;;
113 gboolean netconfig_wifi_bgscan_set_mode(const char *interface_name, guint mode)
115 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
120 if (mode != WIFI_BGSCAN_MODE_EXPONENTIAL && mode != WIFI_BGSCAN_MODE_PERIODIC) {
121 ERR("Invalid scan mode [%d]", mode);
125 scan_data->bg_mode = mode;
130 guint netconfig_wifi_bgscan_get_mode(const char *interface_name)
132 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
137 return scan_data->bg_mode;
140 guint netconfig_wifi_bgscan_get_periodic_interval(const char *interface_name)
142 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
147 return scan_data->bg_periodic_interval;
150 gboolean netconfig_wifi_bgscan_set_periodic_interval(const char *interface_name, guint interval)
152 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
157 if ((interval < SCAN_PERIODIC_DELAY_MIN) || (interval > SCAN_PERIODIC_DELAY_MAX)) {
158 ERR("Invalid interval [%d]", interval);
162 scan_data->bg_periodic_interval = interval;
167 void netconfig_wifi_bgscan_set_timer_id(const char *interface_name, guint timer_id)
169 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
174 scan_data->bg_timer_id = timer_id;
177 guint netconfig_wifi_bgscan_get_timer_id(const char *interface_name)
179 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
184 return scan_data->bg_timer_id;
187 gboolean netconfig_wifi_bgscan_set_exp_interval(const char *interface_name, guint interval)
189 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
194 if ((interval < SCAN_EXPONENTIAL_MIN) || (interval > SCAN_EXPONENTIAL_MAX)) {
195 ERR("Invalid interval [%d]", interval);
199 scan_data->bg_exp_interval = interval;
204 guint netconfig_wifi_bgscan_get_exp_interval(const char *interface_name)
206 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
209 return SCAN_EXPONENTIAL_MIN;
211 return scan_data->bg_exp_interval;
214 void netconfig_wifi_bgscan_set_pause(const char *interface_name, gboolean pause)
216 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
220 scan_data->bg_paused = pause;
222 DBG("[%s] Wi-Fi background scan [%s]", interface_name,
223 pause ? "Pause" : "Resume");
226 gboolean netconfig_wifi_bgscan_is_paused(const char *interface_name)
228 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
232 DBG("[%s] Wi-Fi background scan is [%s]", interface_name,
233 scan_data->bg_paused ? "Paused" : "Runnable");
235 return scan_data->bg_paused;
238 static void __wifi_scan_request_reply(GObject *source_object,
239 GAsyncResult *res, gpointer user_data)
242 GDBusConnection *conn = NULL;
243 GError *error = NULL;
244 char *interface_name = user_data;
246 conn = G_DBUS_CONNECTION(source_object);
247 reply = g_dbus_connection_call_finish(conn, res, &error);
251 ERR("Fail to request status [%d: %s]", error->code, error->message);
252 netconfig_wifi_scan_set_scanning(interface_name, FALSE);
255 ERR("Fail to request scan");
256 netconfig_wifi_scan_set_scanning(interface_name, FALSE);
259 DBG("Successfully requested");
260 g_variant_unref(reply);
263 netconfig_gdbus_pending_call_unref();
264 g_free(interface_name);
267 static gboolean __wifi_scan_request_connman_scan(const char *interface_name)
269 GVariant *params = NULL;
270 gboolean reply = FALSE;
272 netconfig_wifi_scan_set_scanning(interface_name, TRUE);
274 params = g_variant_new("(s)", interface_name);
276 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
277 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
278 CONNMAN_TECHNOLOGY_INTERFACE, "ScanDevice", params,
279 __wifi_scan_request_reply, g_strdup(interface_name));
281 ERR("Failed to send Scan request to connman");
282 netconfig_wifi_scan_set_scanning(interface_name, FALSE);
288 static gboolean __wifi_bgscan_immediate_scan(gpointer data)
290 static int retries = 0;
291 scan_data_s *scan_data = data;
293 int ug_state = VCONFKEY_WIFI_UG_RUN_STATE_OFF;
294 guint bg_mode = WIFI_BGSCAN_MODE_EXPONENTIAL;
299 netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state);
301 state = wifi_state_get_service_state(scan_data->interface_name);
303 #if !defined TIZEN_WEARABLE
304 if (netconfig_wifi_bgscan_is_paused(scan_data->interface_name)) {
309 if (state == NETCONFIG_WIFI_CONNECTED) {
310 bg_mode = netconfig_wifi_bgscan_get_mode(scan_data->interface_name);
311 if (bg_mode == WIFI_BGSCAN_MODE_EXPONENTIAL ||
312 (bg_mode == WIFI_BGSCAN_MODE_PERIODIC &&
313 ug_state != VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)) {
314 DBG("[%s] Wi-Fi state is connected, scan is paused", scan_data->interface_name);
317 } else if (state == NETCONFIG_WIFI_ASSOCIATION || state == NETCONFIG_WIFI_CONFIGURATION) {
318 /* During WIFI connecting, WIFI can be disappeared.
319 * After 1 sec, try scan even if connecting state */
326 if (__wifi_scan_request_connman_scan(scan_data->interface_name) == TRUE) {
329 } else if (retries > 2) {
339 static gboolean __wifi_bgscan_next_scan(gpointer data)
341 int pm_state = VCONFKEY_PM_STATE_NORMAL;
342 scan_data_s *scan_data = data;
347 if (scan_data->bg_mode == WIFI_BGSCAN_MODE_EXPONENTIAL) {
348 scan_data->bg_exp_interval = scan_data->bg_exp_interval * 2;
349 if (scan_data->bg_exp_interval > SCAN_EXPONENTIAL_MAX)
350 scan_data->bg_exp_interval = SCAN_EXPONENTIAL_MAX;
353 /* In case of LCD off, we don't need Wi-Fi scan */
354 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
355 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
358 netconfig_wifi_bgscan_start_timer(scan_data->interface_name, TRUE);
363 void netconfig_wifi_bgscan_start_timer(const char *interface_name, gboolean immediate_scan)
365 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
366 guint bg_interval = 0;
371 netconfig_stop_timer(&(scan_data->bg_timer_id));
373 switch (scan_data->bg_mode) {
374 case WIFI_BGSCAN_MODE_EXPONENTIAL:
375 if (scan_data->bg_exp_interval < SCAN_EXPONENTIAL_MIN)
376 scan_data->bg_exp_interval = SCAN_EXPONENTIAL_MIN;
378 bg_interval = scan_data->bg_exp_interval;
380 case WIFI_BGSCAN_MODE_PERIODIC:
381 bg_interval = scan_data->bg_periodic_interval;
384 DBG("Invalid Wi-Fi background scan mode[%d]", scan_data->bg_mode);
389 DBG("[%s] Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]",
390 interface_name, immediate_scan, scan_data->bg_mode, bg_interval);
392 DBG("[%s] Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]",
393 interface_name, immediate_scan, scan_data->bg_mode, bg_interval);
396 g_timeout_add(500, __wifi_bgscan_immediate_scan, scan_data);
398 netconfig_start_timer_seconds(bg_interval,
399 __wifi_bgscan_next_scan, scan_data, &(scan_data->bg_timer_id));
403 void netconfig_wifi_bgscan_stop_timer(const char *interface_name)
405 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
410 netconfig_stop_timer(&(scan_data->bg_timer_id));
413 void netconfig_wifi_bssidscan_set_mode(const char *interface_name, gboolean enable)
415 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
419 scan_data->bssid_enabled = enable;
422 gboolean netconfig_wifi_bssidscan_get_mode(const char *interface_name)
424 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
428 return scan_data->bssid_enabled;
431 void netconfig_wifi_bssidscan_set_aborted(const char *interface_name, gboolean abort)
433 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
437 scan_data->bssid_aborted = abort;
440 gboolean netconfig_wifi_bssidscan_get_aborted(const char *interface_name)
442 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
446 return scan_data->bssid_aborted;
449 void netconfig_wifi_bssidscan_set_scanning(const char *interface_name, gboolean scanning)
451 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
456 scan_data->bssid_scanning = scanning;
459 guint netconfig_wifi_bssidscan_get_scanning(const char *interface_name)
461 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
466 return scan_data->bssid_scanning;;