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.
24 #include <sys/ioctl.h>
25 #include <netinet/in.h>
26 #include <netinet/ip.h>
27 #include <linux/wireless.h>
29 #include <vconf-keys.h>
34 #include "wifi-state.h"
35 #include "network-state.h"
36 #include "network-statistics.h"
37 #include "netsupplicant.h"
38 #include "wifi-indicator.h"
40 #define VCONFKEY_WIFI_SNR_MIN -89
42 #if !defined TIZEN_WEARABLE
43 #define WIFI_INDICATOR_INTERVAL 1
45 #define WIFI_INDICATOR_INTERVAL 10
48 #if defined TIZEN_WEARABLE
49 #define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 (19200 * 1024)
50 #define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2 (2560 * 1024)
51 #define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3 (1536 * 1024)
53 #define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 (19200 * 1024)
54 #define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2 (7680 * 1024)
55 #define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3 (3840 * 1024)
57 #define NETCONFIG_PROCWIRELESS "/proc/net/wireless"
64 static int netconfig_wifi_rssi = VCONFKEY_WIFI_SNR_MIN;
65 static guint32 netconfig_wifi_freq = 0;
66 static guint netconfig_wifi_indicator_timer = 0;
67 static GSList *g_rssi_list = NULL;
69 static rssi_data_s *__create_rssi_data(const char *interface_name)
71 rssi_data_s *rssi_data = g_try_malloc0(sizeof(rssi_data_s));
73 ERR("Memory allocation failed");
77 rssi_data->interface_name = g_strdup(interface_name);
79 g_rssi_list = g_slist_append(g_rssi_list, rssi_data);
84 static rssi_data_s *__get_rssi_data(const char *interface_name)
87 rssi_data_s *rssi_data = NULL;
89 for (list = g_rssi_list; list; list = list->next) {
90 rssi_data = list->data;
91 if (g_strcmp0(rssi_data->interface_name, interface_name) == 0)
98 static void __destroy_rssi_data(const char *interface_name)
100 rssi_data_s *rssi_data = __get_rssi_data(interface_name);
105 g_rssi_list = g_slist_remove(g_rssi_list, rssi_data);
106 g_free(rssi_data->interface_name);
110 int netconfig_wifi_get_rssi(void)
112 return netconfig_wifi_rssi;
115 unsigned int netconfig_wifi_get_freq(void)
117 return netconfig_wifi_freq;
120 static int __netconfig_wifi_update_and_get_rssi(const char *interface_name)
122 char *if_path = NULL;
123 GVariant *message = NULL;
124 GVariant *value = NULL;
129 int rssi_dbm = VCONFKEY_WIFI_SNR_MIN;
131 if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
132 if (if_path == NULL) {
133 ERR("Fail to get wpa_supplicant DBus path");
137 message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE, if_path,
138 SUPPLICANT_INTERFACE ".Interface", "SignalPoll", NULL);
139 if (message == NULL) {
140 ERR("Fail to get SignalPoll from wpa_supplicant");
145 g_variant_get(message, "(v)", &value);
147 g_variant_get(value, "a{sv}", &iter);
148 while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
150 if (g_strcmp0(key, "rssi") == 0) {
151 key_value = g_variant_get_int32(variant);
152 rssi_dbm = (int)key_value;
153 /* DBG("Currently signal dbm value [%d]", rssi_dbm); */
154 } else if (g_strcmp0(key, "frequency") == 0) {
155 netconfig_wifi_freq = g_variant_get_uint32(variant);
156 /* DBG("Currently frequency [%u]", netconfig_wifi_freq); */
160 g_variant_iter_free(iter);
162 g_variant_unref(message);
166 netconfig_wifi_rssi = rssi_dbm;
171 static int __netconfig_wifi_convert_dbm_to_level_24(int rssi_dbm)
175 /* Wi-Fi Signal Strength Display (for 2.4G (dB))
180 * Very weak : -83 ~ -88
186 else if (rssi_dbm >= -74)
188 else if (rssi_dbm >= -82)
190 else if (rssi_dbm >= -88)
198 static int __netconfig_wifi_convert_dbm_to_level_50(int rssi_dbm)
202 /* Wi-Fi Signal Strength Display (for 5G (dB))
207 * Very weak : -83 ~ -88
213 else if (rssi_dbm >= -76)
215 else if (rssi_dbm >= -82)
217 else if (rssi_dbm >= -88)
225 int netconfig_wifi_rssi_level(const int rssi_dbm)
231 ret = netconfig_vconf_get_int("memory/private/wifi/frequency", &freq);
233 if (!ret && freq > 4900)
234 snr_level = __netconfig_wifi_convert_dbm_to_level_50(rssi_dbm);
236 snr_level = __netconfig_wifi_convert_dbm_to_level_24(rssi_dbm);
241 static void __netconfig_wifi_set_rssi_level(const char *interface_name,
244 rssi_data_s *rssi_data = NULL;
245 const char *default_ifname = NULL;
247 rssi_data = __get_rssi_data(interface_name);
248 if (rssi_data == NULL)
251 if (snr_level != rssi_data->last_snr_level) {
252 wifi_emit_rssi_changed((Wifi *)get_wifi_object(), interface_name, snr_level);
254 default_ifname = netconfig_get_default_ifname();
255 if (g_strcmp0(default_ifname, interface_name) == 0)
256 netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, snr_level);
258 netconfig_battery_update_wifi_rssi(snr_level);
260 rssi_data->last_snr_level = snr_level;
264 static void __netconfig_wifi_data_activity_booster(int level)
266 gboolean reply = FALSE;
267 GVariant *params = NULL;
275 static int old_level = 0;
284 params = g_variant_new("(ii)", level1, lock);
287 params = g_variant_new("(ii)", level2, lock);
290 params = g_variant_new("(ii)", level3, lock);
293 ERR("Invalid level");
297 reply = netconfig_invoke_dbus_method_nonblock(
298 "org.tizen.system.deviced",
299 "/Org/Tizen/System/DeviceD/PmQos",
300 "org.tizen.system.deviced.PmQos",
309 /* disable previous booster */
310 if (old_level == 0 || old_level == level)
315 params = g_variant_new("(ii)", level1, unlock);
318 params = g_variant_new("(ii)", level2, unlock);
321 params = g_variant_new("(ii)", level3, unlock);
324 ERR("Invalid level");
328 reply = netconfig_invoke_dbus_method_nonblock(
329 "org.tizen.system.deviced",
330 "/Org/Tizen/System/DeviceD/PmQos",
331 "org.tizen.system.deviced.PmQos",
342 static void __netconfig_wifi_update_indicator(void)
344 static int last_transfer_state = 0;
345 static guint64 netconfig_wifi_tx_bytes = 0;
346 static guint64 netconfig_wifi_rx_bytes = 0;
347 static int booster_tic = 0;
348 static int old_level = 0;
349 int booster_level = 0;
350 guint64 tx, rx, tx_diff, rx_diff;
353 if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) {
354 tx_diff = tx - netconfig_wifi_tx_bytes;
355 rx_diff = rx - netconfig_wifi_rx_bytes;
359 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TXRX;
361 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TX;
364 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_RX;
366 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_NONE;
369 if (transfer_state != last_transfer_state) {
370 netconfig_set_vconf_int(VCONFKEY_WIFI_TRANSFER_STATE, transfer_state);
371 last_transfer_state = transfer_state;
374 /* NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER */
375 if (tx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 ||
376 rx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1)
378 else if (tx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2 ||
379 rx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2)
381 else if (tx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3 ||
382 rx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3)
385 if (old_level == booster_level) {
386 if (--booster_tic <= 0) {
387 __netconfig_wifi_data_activity_booster(booster_level);
392 __netconfig_wifi_data_activity_booster(booster_level);
394 if (booster_level > 0)
400 old_level = booster_level;
402 netconfig_wifi_tx_bytes = tx;
403 netconfig_wifi_rx_bytes = rx;
407 static gboolean __wifi_indicator_monitor(gpointer data)
411 int pm_state = VCONFKEY_PM_STATE_NORMAL;
412 char *interface_name = data;
414 if (wifi_state_get_service_state(interface_name) != NETCONFIG_WIFI_CONNECTED) {
415 g_free(interface_name);
419 /* In case of LCD off, we don't need to update Wi-Fi indicator */
420 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
421 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
424 rssi_dbm = __netconfig_wifi_update_and_get_rssi(interface_name);
425 snr_level = netconfig_wifi_rssi_level(rssi_dbm);
426 __netconfig_wifi_set_rssi_level(interface_name, snr_level);
428 __netconfig_wifi_update_indicator();
433 void netconfig_wifi_indicator_start(const char *interface_name)
435 const char *default_ifname = NULL;
437 INFO("Start Wi-Fi indicator");
439 __create_rssi_data(interface_name);
441 wifi_emit_rssi_changed((Wifi *)get_wifi_object(),
442 interface_name, VCONFKEY_WIFI_STRENGTH_MAX);
444 default_ifname = netconfig_get_default_ifname();
445 if (g_strcmp0(default_ifname, interface_name) == 0)
446 netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, VCONFKEY_WIFI_STRENGTH_MAX);
448 netconfig_start_timer_seconds(WIFI_INDICATOR_INTERVAL,
449 __wifi_indicator_monitor, g_strdup(interface_name),
450 &netconfig_wifi_indicator_timer);
452 netconfig_battery_update_wifi_rssi(VCONFKEY_WIFI_STRENGTH_MAX);
455 void netconfig_wifi_indicator_stop(const char *interface_name)
457 INFO("Stop Wi-Fi indicator");
459 netconfig_stop_timer(&netconfig_wifi_indicator_timer);
461 netconfig_wifi_rssi = VCONFKEY_WIFI_SNR_MIN;
462 netconfig_wifi_freq = 0;
464 __destroy_rssi_data(interface_name);