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;
40 gboolean bssid_enabled;
41 gboolean bssid_aborted;
42 gboolean bssid_scanning;
48 static GSList *g_scan_list = NULL;
50 static scan_data_s *__wifi_scan_create_data(const char *interface_name)
52 scan_data_s *scan_data = g_try_malloc0(sizeof(scan_data_s));
54 ERR("Memory allocation failed");
58 scan_data->interface_name = g_strdup(interface_name);
60 scan_data->scanning = FALSE;
62 scan_data->bg_interval = SCAN_EXPONENTIAL_MIN;
63 scan_data->bg_mode = WIFI_BGSCAN_MODE_EXPONENTIAL;
64 scan_data->bg_timer_id = 0;
65 scan_data->bg_paused = FALSE;
67 scan_data->bssid_enabled = FALSE;
68 scan_data->bssid_aborted = FALSE;
69 scan_data->bssid_scanning = FALSE;
71 g_scan_list = g_slist_append(g_scan_list, scan_data);
76 static scan_data_s *__wifi_scan_get_data(const char *interface_name)
79 scan_data_s *scan_data;
81 for (list = g_scan_list; list; list = list->next) {
82 scan_data = list->data;
83 if (g_strcmp0(scan_data->interface_name, interface_name) == 0)
87 scan_data = __wifi_scan_create_data(interface_name);
91 void netconfig_wifi_scan_set_scanning(const char *interface_name, gboolean scanning)
93 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
98 scan_data->scanning = scanning;
101 guint netconfig_wifi_scan_get_scanning(const char *interface_name)
103 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
108 return scan_data->scanning;;
111 gboolean netconfig_wifi_bgscan_set_mode(const char *interface_name, guint mode)
113 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
118 if (mode != WIFI_BGSCAN_MODE_EXPONENTIAL && mode != WIFI_BGSCAN_MODE_PERIODIC) {
119 ERR("Invalid scan mode [%d]", mode);
123 scan_data->bg_mode = mode;
128 guint netconfig_wifi_bgscan_get_mode(const char *interface_name)
130 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
135 return scan_data->bg_mode;
138 void netconfig_wifi_bgscan_set_timer_id(const char *interface_name, guint timer_id)
140 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
145 scan_data->bg_timer_id = timer_id;
148 guint netconfig_wifi_bgscan_get_timer_id(const char *interface_name)
150 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
155 return scan_data->bg_timer_id;
158 gboolean netconfig_wifi_bgscan_set_interval(const char *interface_name, guint interval)
160 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
165 if ((interval < SCAN_EXPONENTIAL_MIN) || (interval > SCAN_EXPONENTIAL_MAX)) {
166 ERR("Invalid interval [%d]", interval);
170 scan_data->bg_interval = interval;
175 guint netconfig_wifi_bgscan_get_interval(const char *interface_name)
177 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
180 return SCAN_EXPONENTIAL_MIN;
182 return scan_data->bg_interval;
185 void netconfig_wifi_bgscan_set_pause(const char *interface_name, gboolean pause)
187 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
191 scan_data->bg_paused = pause;
193 DBG("[%s] Wi-Fi background scan [%s]", interface_name,
194 pause ? "Pause" : "Resume");
197 gboolean netconfig_wifi_bgscan_is_paused(const char *interface_name)
199 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
203 DBG("[%s] Wi-Fi background scan is [%s]", interface_name,
204 scan_data->bg_paused ? "Paused" : "Runnable");
206 return scan_data->bg_paused;
209 static void __wifi_scan_request_reply(GObject *source_object,
210 GAsyncResult *res, gpointer user_data)
213 GDBusConnection *conn = NULL;
214 GError *error = NULL;
215 char *interface_name = user_data;
217 conn = G_DBUS_CONNECTION(source_object);
218 reply = g_dbus_connection_call_finish(conn, res, &error);
222 ERR("Fail to request status [%d: %s]", error->code, error->message);
223 netconfig_wifi_scan_set_scanning(interface_name, FALSE);
226 ERR("Fail to request scan");
227 netconfig_wifi_scan_set_scanning(interface_name, FALSE);
230 DBG("Successfully requested");
231 g_variant_unref(reply);
234 netconfig_gdbus_pending_call_unref();
235 g_free(interface_name);
238 static gboolean __wifi_scan_request_connman_scan(const char *interface_name)
240 GVariant *params = NULL;
241 gboolean reply = FALSE;
243 netconfig_wifi_scan_set_scanning(interface_name, TRUE);
245 params = g_variant_new("(s)", interface_name);
247 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
248 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
249 CONNMAN_TECHNOLOGY_INTERFACE, "ScanDevice", params,
250 __wifi_scan_request_reply, g_strdup(interface_name));
252 ERR("Failed to send Scan request to connman");
253 netconfig_wifi_scan_set_scanning(interface_name, FALSE);
259 static gboolean __wifi_bgscan_immediate_scan(gpointer data)
261 static int retries = 0;
262 scan_data_s *scan_data = data;
268 state = wifi_state_get_service_state(scan_data->interface_name);
270 #if !defined TIZEN_WEARABLE
271 if (netconfig_wifi_bgscan_is_paused(scan_data->interface_name)) {
276 if (state == NETCONFIG_WIFI_CONNECTED) {
277 if (netconfig_wifi_bgscan_get_mode(scan_data->interface_name) == WIFI_BGSCAN_MODE_EXPONENTIAL) {
278 DBG("[%s] Wi-Fi state is connected, scan is paused", scan_data->interface_name);
281 } else if (state == NETCONFIG_WIFI_ASSOCIATION || state == NETCONFIG_WIFI_CONFIGURATION) {
282 /* During WIFI connecting, WIFI can be disappeared.
283 * After 1 sec, try scan even if connecting state */
290 if (__wifi_scan_request_connman_scan(scan_data->interface_name) == TRUE) {
293 } else if (retries > 2) {
303 static gboolean __wifi_bgscan_next_scan(gpointer data)
305 int pm_state = VCONFKEY_PM_STATE_NORMAL;
306 scan_data_s *scan_data = data;
311 /* In case of LCD off, we don't need Wi-Fi scan */
312 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
313 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
316 netconfig_wifi_bgscan_start_timer(scan_data->interface_name, TRUE);
321 void netconfig_wifi_bgscan_start_timer(const char *interface_name, gboolean immediate_scan)
323 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
328 netconfig_stop_timer(&(scan_data->bg_timer_id));
330 switch (scan_data->bg_mode) {
331 case WIFI_BGSCAN_MODE_EXPONENTIAL:
332 if (scan_data->bg_interval < SCAN_EXPONENTIAL_MIN ||
333 scan_data->bg_interval == SCAN_PERIODIC_DELAY)
334 scan_data->bg_interval = SCAN_EXPONENTIAL_MIN;
336 case WIFI_BGSCAN_MODE_PERIODIC:
337 scan_data->bg_interval = SCAN_PERIODIC_DELAY;
340 DBG("Invalid Wi-Fi background scan mode[%d]", scan_data->bg_mode);
345 DBG("[%s] Scan immediately[%d], mode[%d](0 exponential / 1 periodic)",
346 interface_name, immediate_scan, scan_data->bg_mode);
348 DBG("[%s] Scan immediately[%d], mode[%d](0 exponential / 1 periodic), next[%d]",
349 interface_name, immediate_scan, scan_data->bg_mode, scan_data->bg_interval);
352 g_timeout_add(500, __wifi_bgscan_immediate_scan, scan_data);
354 netconfig_start_timer_seconds(scan_data->bg_interval,
355 __wifi_bgscan_next_scan, scan_data, &(scan_data->bg_timer_id));
357 if (scan_data->bg_mode == WIFI_BGSCAN_MODE_EXPONENTIAL && immediate_scan) {
358 scan_data->bg_interval = scan_data->bg_interval * 2;
359 if (scan_data->bg_interval > SCAN_EXPONENTIAL_MAX)
360 scan_data->bg_interval = SCAN_EXPONENTIAL_MAX;
364 void netconfig_wifi_bgscan_stop_timer(const char *interface_name)
366 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
371 netconfig_stop_timer(&(scan_data->bg_timer_id));
374 void netconfig_wifi_bssidscan_set_mode(const char *interface_name, gboolean enable)
376 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
380 scan_data->bssid_enabled = enable;
383 gboolean netconfig_wifi_bssidscan_get_mode(const char *interface_name)
385 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
389 return scan_data->bssid_enabled;
392 void netconfig_wifi_bssidscan_set_aborted(const char *interface_name, gboolean abort)
394 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
398 scan_data->bssid_aborted = abort;
401 gboolean netconfig_wifi_bssidscan_get_aborted(const char *interface_name)
403 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
407 return scan_data->bssid_aborted;
410 void netconfig_wifi_bssidscan_set_scanning(const char *interface_name, gboolean scanning)
412 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
417 scan_data->bssid_scanning = scanning;
420 guint netconfig_wifi_bssidscan_get_scanning(const char *interface_name)
422 scan_data_s *scan_data = __wifi_scan_get_data(interface_name);
427 return scan_data->bssid_scanning;;