#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#define VCONFKEY_WIFI_SNR_MIN -89
-#define NETCONFIG_WIFI_INDICATOR_INTERVAL 1
+#if !defined TIZEN_WEARABLE
+#define WIFI_INDICATOR_INTERVAL 2
+#else
+#define WIFI_INDICATOR_INTERVAL 10
+#endif
#if defined TIZEN_WEARABLE
#define NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 (19200 * 1024)
#endif
#define NETCONFIG_PROCWIRELESS "/proc/net/wireless"
-static int netconfig_wifi_rssi = VCONFKEY_WIFI_SNR_MIN;
-static guint netconfig_wifi_indicator_timer = 0;
+typedef struct {
+ char *interface_name;
+ char *default_path;
+ int last_snr_level;
+} rssi_data_s;
+
+static GSList *g_rssi_list = NULL;
+static guint netconfig_wifi_statistics_timer = 0;
-int netconfig_wifi_get_rssi(void)
+static rssi_data_s *__create_rssi_data(const char *interface_name)
{
- return netconfig_wifi_rssi;
+ rssi_data_s *rssi_data = g_try_malloc0(sizeof(rssi_data_s));
+ if (!rssi_data) {
+ ERR("Memory allocation failed");
+ return NULL;
+ }
+
+ rssi_data->interface_name = g_strdup(interface_name);
+
+ g_rssi_list = g_slist_append(g_rssi_list, rssi_data);
+
+ return rssi_data;
}
-static int __netconfig_wifi_update_and_get_rssi(void)
+static rssi_data_s *__get_rssi_data(const char *interface_name)
{
- FILE *fp;
- char buf[512];
- char *p_ifname = NULL, *p_entry = NULL;
- int rssi_dbm = VCONFKEY_WIFI_SNR_MIN;
-
- fp = fopen(NETCONFIG_PROCWIRELESS, "r");
- if (fp == NULL) {
- ERR("Failed to open %s", NETCONFIG_PROCWIRELESS);
- return rssi_dbm;
+ GSList *list;
+ rssi_data_s *rssi_data = NULL;
+
+ for (list = g_rssi_list; list; list = list->next) {
+ rssi_data = list->data;
+ if (g_strcmp0(rssi_data->interface_name, interface_name) == 0)
+ return rssi_data;
}
- /* skip the first and second line */
- if (fgets(buf, sizeof(buf), fp) == NULL ||
- fgets(buf, sizeof(buf), fp) == NULL)
- goto endline;
-
- while (fgets(buf, sizeof(buf), fp)) {
- unsigned int status;
- int link, noise;
- /* No need to read */
- /*
- unsigned long nwid, crypt, frag, retry, misc, missed;
- */
-
- p_ifname = buf;
- while (*p_ifname == ' ') p_ifname++;
- p_entry = strchr(p_ifname, ':');
- if (p_entry == NULL)
- goto endline;
- *p_entry++ = '\0';
-
- if (g_strcmp0(p_ifname, WIFI_IFNAME) != 0)
- continue;
-
- /* read wireless status */
- p_entry = strtok(p_entry, " ."); // status "%x"
- if (p_entry != NULL)
- sscanf(p_entry, "%x", &status);
- p_entry = strtok(NULL, " ."); // Quality link "%d"
- if (p_entry != NULL)
- sscanf(p_entry, "%d", &link);
- p_entry = strtok(NULL, " ."); // Quality level "%d"
- if (p_entry != NULL)
- sscanf(p_entry, "%d", &rssi_dbm);
- p_entry = strtok(NULL, " ."); // Quality noise "%d"
- if (p_entry != NULL)
- sscanf(p_entry, "%d", &noise);
-
- /* No need to read */
- /*
- p_entry = strtok(NULL, " ."); // Discarded nwid "%lu"
- sscanf(p_entry, "%lu", &nwid);
- p_entry = strtok(NULL, " ."); // Discarded crypt "%lu"
- sscanf(p_entry, "%lu", &crypt);
- p_entry = strtok(NULL, " ."); // Discarded frag "%lu"
- sscanf(p_entry, "%lu", &frag);
- p_entry = strtok(NULL, " ."); // Discarded retry "%lu"
- sscanf(p_entry, "%lu", &retry);
- p_entry = strtok(NULL, " ."); // Discarded misc "%lu"
- sscanf(p_entry, "%lu", &misc);
- p_entry = strtok(NULL, " ."); // Discarded missed "%lu"
- sscanf(p_entry, "%lu", &missed);
- */
+ return rssi_data;
+}
- break;
- }
+static void __set_rssi_data_default_path(const char *interface_name,
+ const char *path)
+{
+ rssi_data_s *rssi_data = __get_rssi_data(interface_name);
+ if (rssi_data == NULL)
+ return;
-endline:
- fclose(fp);
- netconfig_wifi_rssi = rssi_dbm;
+ rssi_data->default_path = g_strdup(path);
+}
- return rssi_dbm;
+static void __destroy_rssi_data(const char *interface_name)
+{
+ rssi_data_s *rssi_data = __get_rssi_data(interface_name);
+
+ if (!rssi_data)
+ return;
+
+ g_rssi_list = g_slist_remove(g_rssi_list, rssi_data);
+ g_free(rssi_data->interface_name);
+ g_free(rssi_data->default_path);
+ g_free(rssi_data);
}
-int netconfig_wifi_rssi_level(const int rssi_dbm)
+static int __netconfig_wifi_convert_dbm_to_level_24(int rssi_dbm)
{
- int snr_level = 0;
+ int rssi_level = 0;
- /* Wi-Fi Signal Strength Display
+ /* Wi-Fi Signal Strength Display (for 2.4G (dB))
*
- * Excellent : -63 ~
- * Good: -74 ~ -64
- * Weak: -82 ~ -75
- * Very weak: ~ -83
+ * Excellent : ~ -63
+ * Good : -64 ~ -74
+ * Weak : -75 ~ -82
+ * Very weak : -83 ~ -88
+ * No signal : -89 ~
*/
+
if (rssi_dbm >= -63)
- snr_level = 4;
+ rssi_level = 4;
else if (rssi_dbm >= -74)
- snr_level = 3;
+ rssi_level = 3;
else if (rssi_dbm >= -82)
- snr_level = 2;
+ rssi_level = 2;
+ else if (rssi_dbm >= -88)
+ rssi_level = 1;
+ else
+ rssi_level = 0;
+
+ return rssi_level;
+}
+
+static int __netconfig_wifi_convert_dbm_to_level_50(int rssi_dbm)
+{
+ int rssi_level = 0;
+
+ /* Wi-Fi Signal Strength Display (for 5G (dB))
+ *
+ * Excellent : ~ -67
+ * Good : -68 ~ -76
+ * Weak : -77 ~ -82
+ * Very weak : -83 ~ -88
+ * No signal : -89 ~
+ */
+
+ if (rssi_dbm >= -67)
+ rssi_level = 4;
+ else if (rssi_dbm >= -76)
+ rssi_level = 3;
+ else if (rssi_dbm >= -82)
+ rssi_level = 2;
+ else if (rssi_dbm >= -88)
+ rssi_level = 1;
+ else
+ rssi_level = 0;
+
+ return rssi_level;
+}
+
+static int __netconfig_wifi_get_rssi_level(const int rssi_dbm)
+{
+ int snr_level = 0;
+ int freq = 0;
+ int ret = 0;
+
+ ret = netconfig_vconf_get_int("memory/private/wifi/frequency", &freq);
+
+ if (!ret && freq > 4900)
+ snr_level = __netconfig_wifi_convert_dbm_to_level_50(rssi_dbm);
else
- snr_level = 1;
+ snr_level = __netconfig_wifi_convert_dbm_to_level_24(rssi_dbm);
return snr_level;
}
-static void __netconfig_wifi_set_rssi_level(const int snr_level)
+static void __netconfig_wifi_set_rssi_level(const char *interface_name,
+ const char *path, const int snr_level)
{
- static int last_snr_level = 0;
+ rssi_data_s *rssi_data = NULL;
+ const char *default_ifname = NULL;
- if (snr_level != last_snr_level) {
- netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, snr_level);
- last_snr_level = snr_level;
+ rssi_data = __get_rssi_data(interface_name);
+ if (rssi_data == NULL)
+ return;
+
+ if (snr_level != rssi_data->last_snr_level) {
+ default_ifname = netconfig_get_default_ifname();
+ if (g_strcmp0(default_ifname, interface_name) == 0)
+ netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, snr_level, FALSE);
+
+ if (g_strcmp0(rssi_data->default_path, path) == 0) {
+ wifi_emit_rssi_changed((Wifi *)get_wifi_object(), interface_name, snr_level);
+
+ netconfig_battery_update_wifi_rssi(snr_level);
+
+ rssi_data->last_snr_level = snr_level;
+ }
}
}
if (level > 0) {
/* enable booster */
- switch(level) {
+ switch (level) {
case 1:
params = g_variant_new("(ii)", level1, lock);
break;
"org.tizen.system.deviced.PmQos",
"WifiThroughput",
params,
+ NULL,
NULL);
if (reply != TRUE)
return;
if (old_level == 0 || old_level == level)
return;
- switch(old_level) {
+ switch (old_level) {
case 1:
params = g_variant_new("(ii)", level1, unlock);
break;
"org.tizen.system.deviced.PmQos",
"WifiThroughput",
params,
+ NULL,
NULL);
if (reply != TRUE)
return;
old_level = level;
}
-static void __netconfig_wifi_update_indicator(void)
+static void __netconfig_wifi_get_statistics(void)
{
static int last_transfer_state = 0;
- static guint64 netconfig_wifi_tx_bytes = 0;
- static guint64 netconfig_wifi_rx_bytes = 0;
static int booster_tic = 0;
static int old_level = 0;
int booster_level = 0;
- guint64 tx, rx, tx_diff, rx_diff;
+ guint64 tx, rx;
int transfer_state;
- if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) {
- tx_diff = tx - netconfig_wifi_tx_bytes;
- rx_diff = rx - netconfig_wifi_rx_bytes;
-
- if (tx_diff > 0) {
- if (rx_diff > 0)
- transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TXRX;
- else
- transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TX;
- } else {
- if (rx_diff > 0)
- transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_RX;
- else
- transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_NONE;
- }
+ if (netconfig_wifi_get_bytes_statistics(&tx, &rx, TRUE))
+ netconfig_wifi_set_bytes_pkt_vconf(tx, rx, FALSE);
+
+ netconfig_wifi_get_bytes_default_iface(&tx, &rx);
+
+ if (tx > 0) {
+ if (rx > 0)
+ transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TXRX;
+ else
+ transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_TX;
+ } else {
+ if (rx > 0)
+ transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_RX;
+ else
+ transfer_state = VCONFKEY_WIFI_TRANSFER_STATE_NONE;
+ }
- if (transfer_state != last_transfer_state) {
- netconfig_set_vconf_int(VCONFKEY_WIFI_TRANSFER_STATE,
- transfer_state);
- last_transfer_state = transfer_state;
- }
+ if (transfer_state != last_transfer_state) {
+ netconfig_set_vconf_int(VCONFKEY_WIFI_TRANSFER_STATE, transfer_state, FALSE);
+ last_transfer_state = transfer_state;
+ }
- /* NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER */
- if (tx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 ||
- rx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1)
- booster_level = 1;
- else if (tx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2 ||
- rx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2)
- booster_level = 2;
- else if (tx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3 ||
- rx_diff >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3)
- booster_level = 3;
-
- if (old_level == booster_level) {
- if (--booster_tic <= 0) {
- __netconfig_wifi_data_activity_booster(booster_level);
-
- booster_tic = 2;
- }
- } else {
+ /* NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER */
+ if (tx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1 ||
+ rx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL1)
+ booster_level = 1;
+ else if (tx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2 ||
+ rx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL2)
+ booster_level = 2;
+ else if (tx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3 ||
+ rx >= NETCONFIG_WIFI_DATA_ACTIVITY_BOOSTER_LEVEL3)
+ booster_level = 3;
+
+ if (old_level == booster_level) {
+ if (--booster_tic <= 0) {
__netconfig_wifi_data_activity_booster(booster_level);
- if (booster_level > 0)
- booster_tic = 2;
- else
- booster_tic = 0;
+ booster_tic = 2;
}
+ } else {
+ __netconfig_wifi_data_activity_booster(booster_level);
- old_level = booster_level;
-
- netconfig_wifi_tx_bytes = tx;
- netconfig_wifi_rx_bytes = rx;
+ if (booster_level > 0)
+ booster_tic = 2;
+ else
+ booster_tic = 0;
}
+
+ old_level = booster_level;
}
-static gboolean __netconfig_wifi_indicator_monitor(gpointer data)
+static gboolean __netconfig_wifi_update_statistics(gpointer data)
{
- int rssi_dbm = 0;
- int snr_level = 0;
int pm_state = VCONFKEY_PM_STATE_NORMAL;
+ char *interface_name = data;
- if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
+ if (wifi_state_get_service_state(interface_name) != NETCONFIG_WIFI_CONNECTED) {
+ g_free(interface_name);
return FALSE;
+ }
/* In case of LCD off, we don't need to update Wi-Fi indicator */
- vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
+ netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
return TRUE;
- rssi_dbm = __netconfig_wifi_update_and_get_rssi();
- //INFO("%d dbm", rssi_dbm);
- snr_level = netconfig_wifi_rssi_level(rssi_dbm);
- __netconfig_wifi_set_rssi_level(snr_level);
-
- __netconfig_wifi_update_indicator();
+ __netconfig_wifi_get_statistics();
return TRUE;
}
-void netconfig_wifi_indicator_start(void)
+void netconfig_wifi_indicator_update(const char *interface_name,
+ const char *path, int rssi_dbm)
{
+ int pm_state = VCONFKEY_PM_STATE_NORMAL;
+ int snr_level = 0;
+
+ /* In case of LCD off, we don't need to update Wi-Fi indicator */
+ netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
+ if (pm_state >= VCONFKEY_PM_STATE_LCDOFF)
+ return;
+
+ snr_level = __netconfig_wifi_get_rssi_level(rssi_dbm);
+ __netconfig_wifi_set_rssi_level(interface_name, path, snr_level);
+}
+
+void netconfig_wifi_indicator_start(const char *interface_name,
+ const char *profile_path)
+{
+ const char *default_ifname = NULL;
+
INFO("Start Wi-Fi indicator");
- netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, VCONFKEY_WIFI_STRENGTH_MAX);
+ __create_rssi_data(interface_name);
- netconfig_start_timer_seconds(
- NETCONFIG_WIFI_INDICATOR_INTERVAL,
- __netconfig_wifi_indicator_monitor,
- NULL,
- &netconfig_wifi_indicator_timer);
+ if (profile_path)
+ __set_rssi_data_default_path(interface_name, profile_path);
+
+ default_ifname = netconfig_get_default_ifname();
+ if (g_strcmp0(default_ifname, interface_name) == 0)
+ netconfig_set_vconf_int(VCONFKEY_WIFI_STRENGTH, VCONFKEY_WIFI_STRENGTH_MAX, FALSE);
+
+ wifi_emit_rssi_changed((Wifi *)get_wifi_object(),
+ interface_name, VCONFKEY_WIFI_STRENGTH_MAX);
+
+ if (netconfig_wifi_statistics_timer == 0) {
+ netconfig_wifi_reset_last_bytes();
+ netconfig_start_timer_seconds(WIFI_INDICATOR_INTERVAL,
+ __netconfig_wifi_update_statistics, g_strdup(interface_name),
+ &netconfig_wifi_statistics_timer);
+ }
+
+ netconfig_battery_update_wifi_rssi(VCONFKEY_WIFI_STRENGTH_MAX);
}
-void netconfig_wifi_indicator_stop(void)
+void netconfig_wifi_indicator_stop(const char *interface_name)
{
+ int wifi_state = 0;
+ guint64 tx, rx;
+
INFO("Stop Wi-Fi indicator");
- netconfig_stop_timer(&netconfig_wifi_indicator_timer);
+ netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
+
+ if (wifi_state != VCONFKEY_WIFI_CONNECTED) {
+ if (netconfig_wifi_get_bytes_statistics(&tx, &rx, TRUE))
+ netconfig_wifi_set_bytes_pkt_vconf(tx, rx, FALSE);
+
+ netconfig_stop_timer(&netconfig_wifi_statistics_timer);
+ }
- netconfig_wifi_rssi = VCONFKEY_WIFI_SNR_MIN;
+ __destroy_rssi_data(interface_name);
}