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 2
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"
65 static GSList *g_rssi_list = NULL;
66 static guint netconfig_wifi_statistics_timer = 0;
68 static rssi_data_s *__create_rssi_data(const char *interface_name)
70 rssi_data_s *rssi_data = g_try_malloc0(sizeof(rssi_data_s));
72 ERR("Memory allocation failed");
76 rssi_data->interface_name = g_strdup(interface_name);
78 g_rssi_list = g_slist_append(g_rssi_list, rssi_data);
83 static rssi_data_s *__get_rssi_data(const char *interface_name)
86 rssi_data_s *rssi_data = NULL;
88 for (list = g_rssi_list; list; list = list->next) {
89 rssi_data = list->data;
90 if (g_strcmp0(rssi_data->interface_name, interface_name) == 0)
97 static void __set_rssi_data_default_path(const char *interface_name,
100 rssi_data_s *rssi_data = __get_rssi_data(interface_name);
101 if (rssi_data == NULL)
104 rssi_data->default_path = g_strdup(path);
107 static void __destroy_rssi_data(const char *interface_name)
109 rssi_data_s *rssi_data = __get_rssi_data(interface_name);
114 g_rssi_list = g_slist_remove(g_rssi_list, rssi_data);
115 g_free(rssi_data->interface_name);
116 g_free(rssi_data->default_path);
120 static int __netconfig_wifi_convert_dbm_to_level_24(int rssi_dbm)
124 /* Wi-Fi Signal Strength Display (for 2.4G (dB))
129 * Very weak : -83 ~ -88
135 else if (rssi_dbm >= -74)
137 else if (rssi_dbm >= -82)
139 else if (rssi_dbm >= -88)
147 static int __netconfig_wifi_convert_dbm_to_level_50(int rssi_dbm)
151 /* Wi-Fi Signal Strength Display (for 5G (dB))
156 * Very weak : -83 ~ -88
162 else if (rssi_dbm >= -76)
164 else if (rssi_dbm >= -82)
166 else if (rssi_dbm >= -88)
174 static int __netconfig_wifi_convert_dbm_to_level_60(int rssi_dbm)
178 /* Wi-Fi Signal Strength Display (for 6G (dB))
183 * Very weak : -83 ~ -88
189 else if (rssi_dbm >= -77)
191 else if (rssi_dbm >= -82)
193 else if (rssi_dbm >= -88)
201 static int __netconfig_wifi_get_rssi_level(const int rssi_dbm)
207 ret = netconfig_vconf_get_int("memory/private/wifi/frequency", &freq);
209 if (!ret && freq > 5925)
210 snr_level = __netconfig_wifi_convert_dbm_to_level_60(rssi_dbm);
211 else if (!ret && freq > 4900)
212 snr_level = __netconfig_wifi_convert_dbm_to_level_50(rssi_dbm);
214 snr_level = __netconfig_wifi_convert_dbm_to_level_24(rssi_dbm);
219 static void __netconfig_wifi_set_rssi_level(const char *interface_name,
220 const char *path, const int snr_level)
222 rssi_data_s *rssi_data = NULL;
223 const char *default_ifname = NULL;
225 rssi_data = __get_rssi_data(interface_name);
226 if (rssi_data == NULL)
229 if (snr_level != rssi_data->last_snr_level) {
230 default_ifname = netconfig_get_default_ifname();
231 if (g_strcmp0(default_ifname, interface_name) == 0)
232 netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, snr_level, FALSE);
234 if (g_strcmp0(rssi_data->default_path, path) == 0) {
235 wifi_emit_rssi_changed((Wifi *)get_wifi_object(), interface_name, snr_level);
237 netconfig_battery_update_wifi_rssi(snr_level);
239 rssi_data->last_snr_level = snr_level;
244 static void __netconfig_wifi_data_activity_booster(int level)
246 gboolean reply = FALSE;
247 GVariant *params = NULL;
255 static int old_level = 0;
264 params = g_variant_new("(ii)", level1, lock);
267 params = g_variant_new("(ii)", level2, lock);
270 params = g_variant_new("(ii)", level3, lock);
273 ERR("Invalid level");
277 reply = netconfig_invoke_dbus_method_nonblock(
278 "org.tizen.system.deviced",
279 "/Org/Tizen/System/DeviceD/PmQos",
280 "org.tizen.system.deviced.PmQos",
289 /* disable previous booster */
290 if (old_level == 0 || old_level == level)
295 params = g_variant_new("(ii)", level1, unlock);
298 params = g_variant_new("(ii)", level2, unlock);
301 params = g_variant_new("(ii)", level3, unlock);
304 ERR("Invalid level");
308 reply = netconfig_invoke_dbus_method_nonblock(
309 "org.tizen.system.deviced",
310 "/Org/Tizen/System/DeviceD/PmQos",
311 "org.tizen.system.deviced.PmQos",
322 static void __netconfig_wifi_get_statistics(void)
324 static int last_transfer_state = 0;
325 static int booster_tic = 0;
326 static int old_level = 0;
327 int booster_level = 0;
331 if (netconfig_wifi_get_bytes_statistics(&tx, &rx, TRUE))
332 netconfig_wifi_set_bytes_pkt_vconf(tx, rx, FALSE);
334 netconfig_wifi_get_bytes_default_iface(&tx, &rx);
338 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TXRX;
340 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TX;
343 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_RX;
345 transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_NONE;
348 if (transfer_state != last_transfer_state) {
349 netconfig_set_vconf_int(VCONFKEY_WIFI_TRANSFER_STATE, transfer_state, FALSE);
350 last_transfer_state = transfer_state;
353 /* NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER */
354 if (tx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 ||
355 rx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1)
357 else if (tx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2 ||
358 rx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2)
360 else if (tx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3 ||
361 rx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3)
364 if (old_level == booster_level) {
365 if (--booster_tic <= 0) {
366 __netconfig_wifi_data_activity_booster(booster_level);
371 __netconfig_wifi_data_activity_booster(booster_level);
373 if (booster_level > 0)
379 old_level = booster_level;
382 static gboolean __netconfig_wifi_update_statistics(gpointer data)
384 int pm_state = VCONFKEY_PM_STATE_NORMAL;
385 char *interface_name = data;
387 if (wifi_state_get_service_state(interface_name) != NETCONFIG_WIFI_CONNECTED) {
388 g_free(interface_name);
392 /* In case of LCD off, we don't need to update Wi-Fi indicator */
393 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
394 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
397 __netconfig_wifi_get_statistics();
402 void netconfig_wifi_indicator_update(const char *interface_name,
403 const char *path, int rssi_dbm)
405 int pm_state = VCONFKEY_PM_STATE_NORMAL;
408 /* In case of LCD off, we don't need to update Wi-Fi indicator */
409 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
410 if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
413 snr_level = __netconfig_wifi_get_rssi_level(rssi_dbm);
414 __netconfig_wifi_set_rssi_level(interface_name, path, snr_level);
417 void netconfig_wifi_indicator_start(const char *interface_name,
418 const char *profile_path)
420 const char *default_ifname = NULL;
422 INFO("Start Wi-Fi indicator");
424 __create_rssi_data(interface_name);
427 __set_rssi_data_default_path(interface_name, profile_path);
429 default_ifname = netconfig_get_default_ifname();
430 if (g_strcmp0(default_ifname, interface_name) == 0)
431 netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, VCONFKEY_WIFI_STRENGTH_MAX, FALSE);
433 wifi_emit_rssi_changed((Wifi *)get_wifi_object(),
434 interface_name, VCONFKEY_WIFI_STRENGTH_MAX);
436 if (netconfig_wifi_statistics_timer == 0) {
437 netconfig_wifi_reset_last_bytes();
438 netconfig_start_timer_seconds(WIFI_INDICATOR_INTERVAL,
439 __netconfig_wifi_update_statistics, g_strdup(interface_name),
440 &netconfig_wifi_statistics_timer);
443 netconfig_battery_update_wifi_rssi(VCONFKEY_WIFI_STRENGTH_MAX);
446 void netconfig_wifi_indicator_stop(const char *interface_name)
451 INFO("Stop Wi-Fi indicator");
453 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
455 if (wifi_state != VCONFKEY_WIFI_CONNECTED) {
456 if (netconfig_wifi_get_bytes_statistics(&tx, &rx, TRUE))
457 netconfig_wifi_set_bytes_pkt_vconf(tx, rx, FALSE);
459 netconfig_stop_timer(&netconfig_wifi_statistics_timer);
462 __destroy_rssi_data(interface_name);