Check SSID when loading wifi configuration file
[platform/core/connectivity/net-config.git] / src / wifi-indicator.c
index 36cf86e..06ac9da 100755 (executable)
@@ -40,7 +40,7 @@
 #define VCONFKEY_WIFI_SNR_MIN  -89
 
 #if !defined TIZEN_WEARABLE
-#define WIFI_INDICATOR_INTERVAL        1
+#define WIFI_INDICATOR_INTERVAL        2
 #else
 #define WIFI_INDICATOR_INTERVAL        10
 #endif
 #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;
 
-int netconfig_wifi_get_rssi(void)
+static GSList *g_rssi_list = NULL;
+static guint netconfig_wifi_statistics_timer = 0;
+
+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 = 0;
-               int link = 0;
-               int noise = 0;
-               /* 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 */
-               char *saveptr;
-               p_entry = strtok_r(p_entry, " .", &saveptr);
-
-               /* status "%x" */
-               if (p_entry != NULL)
-                       status = (int)strtol(p_entry, NULL, 16);
-
-               p_entry = strtok_r(NULL, " .", &saveptr);
-
-               /* Quality link "%d" */
-               if (p_entry != NULL)
-                       link = (int)strtol(p_entry, NULL, 10);
-
-               p_entry = strtok_r(NULL, " .", &saveptr);
-
-               /* Quality level "%d" */
-               if (p_entry != NULL)
-                       rssi_dbm = (int)strtol(p_entry, NULL, 10);
-
-               p_entry = strtok_r(NULL, " .", &saveptr);
-
-               /* Quality noise "%d" */
-               if (p_entry != NULL)
-                       noise = (int)strtol(p_entry, NULL, 10);
-
-               DBG("status(%x) link(%d) rssi_dbm(%d) noise(%d)",
-                       status, link, rssi_dbm, 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
-               snr_level = 1;
+               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 = __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;
+               }
        }
 }
 
@@ -228,6 +251,7 @@ static void __netconfig_wifi_data_activity_booster(int level)
                                "org.tizen.system.deviced.PmQos",
                                "WifiThroughput",
                                params,
+                               NULL,
                                NULL);
                if (reply != TRUE)
                        return;
@@ -258,6 +282,7 @@ static void __netconfig_wifi_data_activity_booster(int level)
                        "org.tizen.system.deviced.PmQos",
                        "WifiThroughput",
                        params,
+                       NULL,
                        NULL);
        if (reply != TRUE)
                return;
@@ -265,108 +290,145 @@ static void __netconfig_wifi_data_activity_booster(int level)
        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 __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 (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 */
        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);
-       netconfig_start_timer_seconds(WIFI_INDICATOR_INTERVAL, __wifi_indicator_monitor, NULL, &netconfig_wifi_indicator_timer);
+       __create_rssi_data(interface_name);
+
+       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);
 }