Add method to get available wifi interfaces info 86/241286/4
authorNishant Chaprana <n.chaprana@samsung.com>
Wed, 19 Aug 2020 05:01:26 +0000 (10:31 +0530)
committerNishant Chaprana <n.chaprana@samsung.com>
Wed, 19 Aug 2020 19:37:23 +0000 (01:07 +0530)
Change-Id: Iddd62879f374c5f178b3675c2dbbe6d92c75b9b3
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
include/mobileap_wifi.h
include/tethering-dbus-interface.xml
src/mobileap.c
src/mobileap_wifi.c

index 5a9f3f0..b8dcc7b 100644 (file)
@@ -83,6 +83,9 @@ gboolean tethering_get_wifi_tethering_passphrase(Tethering *obj,
 gboolean tethering_set_wifi_tethering_passphrase(Tethering *obj,
                GDBusMethodInvocation *context, gchar *passphrase);
 
+gboolean tethering_get_wifi_interfaces(Tethering *obj,
+               GDBusMethodInvocation *context);
+
 gboolean tethering_enable_dhcp(Tethering *obj,
                GDBusMethodInvocation *context, gboolean enable);
 
index b79a08a..2d27a08 100755 (executable)
                   <arg type="u" name="result" direction="out"/>
                </method>
 
+               <method name="get_wifi_interfaces">
+                       <arg type="a(a{sv})" name="wifi_interfaces" direction="out"/>
+               </method>
+
                <method name="enable_dhcp">
                        <arg type="b" name="enable" direction="in"/>
                        <arg type="u" name="result" direction="out"/>
index a7b823a..7ad9663 100755 (executable)
@@ -481,6 +481,8 @@ static void on_bus_acquired_cb(GDBusConnection *connection, const gchar *name,
                        G_CALLBACK(tethering_get_wifi_tethering_passphrase), NULL);
        g_signal_connect(tethering_obj, "handle-set-wifi-tethering-passphrase",
                        G_CALLBACK(tethering_set_wifi_tethering_passphrase), NULL);
+       g_signal_connect(tethering_obj, "handle-get-wifi-interfaces",
+                       G_CALLBACK(tethering_get_wifi_interfaces), NULL);
        g_signal_connect(tethering_obj, "handle-enable-dhcp",
                        G_CALLBACK(tethering_enable_dhcp), NULL);
        g_signal_connect(tethering_obj, "handle-dhcp-range",
index 72db253..6ebd530 100755 (executable)
@@ -21,6 +21,9 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <sys/ioctl.h>
+#include <linux/wireless.h>
+
 #include <wifi-manager.h>
 #ifdef TIZEN_FEATURE_ENABLE_WIFI_DIRECT
 #include <wifi-direct.h>
 #include "mobileap_handler.h"
 #include "mobileap_notification.h"
 
+#ifndef IFNAMSIZ
+#define IFNAMEIZ 16
+#endif
+
 #define WIFI_RECOVERY_GUARD_TIME       1000    /* ms */
 #define MOBILE_AP_WIFI_KEY_MIN_LEN     8       /**< Minimum length of wifi key */
 #define MOBILE_AP_WIFI_KEY_MAX_LEN     64      /**< Maximum length of wifi key */
@@ -60,6 +67,14 @@ static softap_settings_t obj_softap_settings = {"", "", "", "", 0, 0, 0, 0, 0, 0
 
 static wifi_manager_h wifi_manager = NULL;
 
+typedef void (*wifi_interface_cb)(const char *ifname, void *user_data);
+
+typedef enum {
+       WIFI_BAND_NONE = 0,
+       WIFI_BAND_2G = 1 << 0,
+       WIFI_BAND_5G = 1 << 1
+} wifi_bands_e;
+
 void _init_wifi_manager(void)
 {
        int ret = wifi_manager_initialize(&wifi_manager);
@@ -485,6 +500,119 @@ static gboolean __is_valid_passphrase_length(char *key)
        return (strlen(key) && (strlen(key) <= MOBILE_AP_WIFI_KEY_MAX_LEN));
 }
 
+static char *_extract_ifname(char *ifname, int size, char *line)
+{
+       char *end;
+
+       while (*line == ' ')
+               line++;
+
+       end = strstr(line, ": ");
+
+       if ((end == NULL) || (((end - line) + 1) > size))
+               return NULL;
+
+       memcpy(ifname, line, (end - line));
+       ifname[end - line] = '\0';
+
+       return end;
+}
+
+static void _foreach_wifi_interface(wifi_interface_cb cb, void *user_data)
+{
+       char line[1024];
+       FILE *file;
+
+       if (cb == NULL)
+               return;
+
+       file = fopen("/proc/net/wireless", "r");
+       if (file == NULL) {
+               ERR("Error opening wireless interface details"); //LCOV_EXCL_LINE
+               return;
+       }
+
+       /* Skip first two lines of header */
+       if (fgets(line, sizeof(line), file) == NULL) {
+               ERR("Error skipping line 1"); //LCOV_EXCL_LINE
+               fclose(file);
+               return;
+       }
+
+       if (fgets(line, sizeof(line), file) == NULL) {
+               ERR("Error skipping line 2"); //LCOV_EXCL_LINE
+               fclose(file);
+               return;
+       }
+
+       while (fgets(line, sizeof(line), file)) {
+               char ifname[IFNAMSIZ + 1];
+
+               if((line[0] == '\0') || (line[1] == '\0'))
+                       continue;
+
+               if (_extract_ifname(ifname, sizeof(ifname), line) == NULL) {
+                       ERR("Failed to fetch ifname, continue for next interface");
+                       continue;
+               }
+
+               cb(ifname, user_data);
+       }
+
+       fclose(file);
+}
+
+static int _get_supported_wifi_bands(const char *ifname)
+{
+       struct iwreq req;
+       char buff[sizeof(struct iw_range) * 2];
+       struct iw_range *range;
+       int fd;
+       int i;
+       int ret = WIFI_BAND_NONE;
+
+       fd = socket(PF_INET, SOCK_DGRAM, 0);
+       if (fd < 0)
+               return ret;
+
+       memset(&req, 0, sizeof(req));
+
+       req.u.data.pointer = (caddr_t) buff;
+       req.u.data.length = sizeof(buff);
+       req.u.data.flags = 0;
+       strncpy(req.ifr_name, ifname, IFNAMSIZ);
+
+       if (ioctl(fd, SIOCGIWRANGE, &req) < 0) {
+               close(fd);
+               return ret;
+       }
+
+       range = (struct iw_range *) buff;
+
+       if (range->we_version_compiled <= 15) {
+               close(fd);
+               return ret;
+       }
+
+       if (range->num_frequency <= 0) {
+               close(fd);
+               return ret;
+       }
+
+       for (i = 0; i < range->num_frequency; i++) {
+               if (range->freq[i].i == 1)
+                       ret |= WIFI_BAND_2G;
+
+               if (range->freq[i].i == 36) {
+                       ret |= WIFI_BAND_5G;
+                       break;
+               }
+       }
+
+       close(fd);
+       return ret;
+}
+
 mobile_ap_error_code_e _reload_softap_settings(Tethering *obj, softap_settings_t *settings)
 {
        gboolean backup_prev_wifi_on = prev_wifi_on;
@@ -1444,6 +1572,59 @@ DONE:
        return TRUE;
 }
 
+static void _get_wifi_interface_details(const char *ifname, void *user_data)
+{
+       GVariantBuilder *builder = (GVariantBuilder *)user_data;
+       GVariantBuilder *sub_builder;
+       int supported_bands;
+
+       DBG("Available interface [%s]", ifname);
+       supported_bands = _get_supported_wifi_bands(ifname);
+
+       sub_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+       g_variant_builder_add(sub_builder, "{sv}", "IfName",
+                       g_variant_new_string(ifname));
+
+       g_variant_builder_add(sub_builder, "{sv}", "Is2GBandSupported",
+                       g_variant_new_boolean(supported_bands & WIFI_BAND_2G));
+
+       g_variant_builder_add(sub_builder, "{sv}", "Is5GBandSupported",
+                       g_variant_new_boolean(supported_bands & WIFI_BAND_5G));
+
+       g_variant_builder_add(builder, "(@a{sv})",
+                       g_variant_builder_end(sub_builder));
+
+       g_variant_builder_unref(sub_builder);
+}
+
+gboolean tethering_get_wifi_interfaces(Tethering *obj,
+               GDBusMethodInvocation *context)
+{
+       DBG("+");
+
+       GVariant *var = NULL;
+       GVariantBuilder *builder;
+
+       g_assert(obj != NULL);
+#ifndef TIZEN_FEATURE_UNITTEST
+       g_assert(context != NULL);
+#endif
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(a{sv})"));
+       _foreach_wifi_interface(_get_wifi_interface_details, builder);
+       var = g_variant_new("(@a(a{sv}))", g_variant_builder_end(builder));
+       g_variant_builder_unref(builder);
+
+#ifndef TIZEN_FEATURE_UNITTEST
+       g_dbus_method_invocation_return_value(context, var);
+#endif
+       g_variant_unref(var);
+
+       DBG("-");
+       return TRUE;
+}
+
 gboolean tethering_set_hostapd_tx_power(Tethering *obj,
                GDBusMethodInvocation *context, gint txpower)
 {