#define IEEE80211_CAP_IBSS 0x0002
#define IEEE80211_CAP_PRIVACY 0x0010
+#if defined TIZEN_EXT
+#define WLAN_EID_HT_CAP 45
+#define WLAN_EID_VHT_CAP 191
+#define WLAN_EID_SUPP_RATES 1
+#define WLAN_EID_EXT_SUPP_RATES 50
+#define COUNTRY_CODE_LENGTH 2
+#define WIFI_BSSID_LEN_MAX 6
+#endif
+
#define BSS_UNKNOWN_STRENGTH -90
static DBusConnection *connection;
{ "wpa-eap", G_SUPPLICANT_KEYMGMT_WPA_EAP },
{ "wpa-eap-sha256", G_SUPPLICANT_KEYMGMT_WPA_EAP_256 },
{ "wps", G_SUPPLICANT_KEYMGMT_WPS },
+#if defined TIZEN_EXT
+ { "sae", G_SUPPLICANT_KEYMGMT_SAE },
+#endif
{ }
};
{ "ad-hoc", G_SUPPLICANT_CAPABILITY_MODE_IBSS },
{ "ap", G_SUPPLICANT_CAPABILITY_MODE_AP },
{ "p2p", G_SUPPLICANT_CAPABILITY_MODE_P2P },
+#if defined TIZEN_EXT_WIFI_MESH
+ { "mesh", G_SUPPLICANT_CAPABILITY_MODE_MESH },
+#endif
{ }
};
char * private_passphrase;
};
+#if defined TIZEN_EXT_WIFI_MESH
+struct _GSupplicantMeshGroupInfo {
+ unsigned char ssid[32];
+ unsigned int ssid_len;
+ int disconnect_reason;
+};
+#endif
+
struct _GSupplicantInterface {
char *path;
char *network_path;
GSupplicantNetwork *current_network;
struct added_network_information network_info;
#if defined TIZEN_EXT
+ dbus_bool_t is_5_0_Ghz_supported;
int disconnect_reason;
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+ bool mesh_support;
+ struct _GSupplicantMeshGroupInfo group_info;
+#endif
};
struct g_supplicant_bss {
#if defined TIZEN_EXT
dbus_bool_t ft_psk;
dbus_bool_t ft_ieee8021x;
- char *wifi_vsie;
- unsigned int wifi_vsie_len;
+ GSList *vsie_list;
dbus_bool_t hs20;
+ unsigned char country_code[COUNTRY_CODE_LENGTH];
+ GSupplicantPhy_mode phy_mode;
#endif
unsigned int wps_capabilities;
+#if defined TIZEN_EXT
+ dbus_bool_t sae;
+#endif
};
struct _GSupplicantNetwork {
char *identity;
char *phase2;
unsigned int keymgmt;
- char *wifi_vsie;
- unsigned int wifi_vsie_len;
+ GSList *vsie_list;
+ unsigned char country_code[COUNTRY_CODE_LENGTH];
+ GSupplicantPhy_mode phy_mode;
#endif
};
GSupplicantSSID *ssid;
};
+#if defined TIZEN_EXT
+struct interface_signalpoll_data {
+ GSupplicantInterface *interface;
+ char *path;
+ GSupplicantMaxSpeedCallback callback;
+ void *user_data;
+};
+#endif
+
struct interface_create_data {
char *ifname;
char *driver;
char *bridge;
+#if defined TIZEN_EXT_WIFI_MESH
+ char *parent_ifname;
+ bool is_mesh_interface;
+#endif
GSupplicantInterface *interface;
GSupplicantInterfaceCallback callback;
void *user_data;
void *user_data;
};
+#if defined TIZEN_EXT
+struct g_connman_bssids {
+ unsigned char bssid[WIFI_BSSID_LEN_MAX];
+ uint16_t strength;
+ uint16_t frequency;
+};
+#endif
+
static int network_remove(struct interface_data *data);
+#if defined TIZEN_EXT_WIFI_MESH
+struct _GSupplicantMeshPeer {
+ GSupplicantInterface *interface;
+ char *peer_address;
+ int disconnect_reason;
+};
+#endif
+
static inline void debug(const char *format, ...)
{
char str[256];
return G_SUPPLICANT_MODE_INFRA;
else if (g_str_equal(mode, "ad-hoc"))
return G_SUPPLICANT_MODE_IBSS;
+#if defined TIZEN_EXT_WIFI_MESH
+ else if (g_str_equal(mode, "mesh"))
+ return G_SUPPLICANT_MODE_MESH;
+#endif
return G_SUPPLICANT_MODE_UNKNOWN;
}
return "adhoc";
case G_SUPPLICANT_MODE_MASTER:
return "ap";
+#if defined TIZEN_EXT_WIFI_MESH
+ case G_SUPPLICANT_MODE_MESH:
+ return "mesh";
+#endif
}
return NULL;
return "ft_psk";
case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
return "ft_ieee8021x";
+ case G_SUPPLICANT_SECURITY_SAE:
+ return "sae";
#endif
}
static bool compare_network_parameters(GSupplicantInterface *interface,
GSupplicantSSID *ssid)
{
+#if defined TIZEN_EXT
+ if (!interface->network_info.ssid)
+ return FALSE;
+#endif
+
if (memcmp(interface->network_info.ssid, ssid->ssid, ssid->ssid_len))
return FALSE;
}
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+static void callback_mesh_support(GSupplicantInterface *interface)
+{
+ SUPPLICANT_DBG("");
+
+ if (!interface->mesh_support)
+ return;
+
+ if (callbacks_pointer && callbacks_pointer->mesh_support)
+ callbacks_pointer->mesh_support(interface);
+}
+
+bool g_supplicant_interface_has_mesh(GSupplicantInterface *interface)
+{
+ if (!interface)
+ return false;
+
+ return interface->mesh_support;
+}
+#endif
+
static void callback_scan_started(GSupplicantInterface *interface)
{
if (!callbacks_pointer)
g_free(network->phase2);
#endif
#if defined TIZEN_EXT
- g_free(network->wifi_vsie);
+ g_slist_free_full(network->vsie_list, g_free);
#endif
g_free(network);
g_free(bss->path);
#if defined TIZEN_EXT
- g_free(bss->wifi_vsie);
+ g_slist_free_full(bss->vsie_list, g_free);
#endif
g_free(bss);
}
if (max_scan_ssid < 2)
max_scan_ssid = 0;
interface->max_scan_ssids = max_scan_ssid;
+#if defined TIZEN_EXT
+ } else if (g_strcmp0(key, "Is5GhzSupported") == 0) {
+ dbus_bool_t is_5_0_Ghz_supported;
+ dbus_message_iter_get_basic(iter, &is_5_0_Ghz_supported);
+ interface->is_5_0_Ghz_supported = is_5_0_Ghz_supported;
+#endif
} else
SUPPLICANT_DBG("key %s type %c",
key, dbus_message_iter_get_arg_type(iter));
return interface->ifname;
}
+#if defined TIZEN_EXT
+bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface)
+{
+ if (!interface)
+ return NULL;
+
+ return interface->is_5_0_Ghz_supported;
+}
+#endif
+
const char *g_supplicant_interface_get_driver(GSupplicantInterface *interface)
{
if (!interface)
return FALSE;
}
+#ifdef TIZEN_EXT
+GSupplicantPhy_mode g_supplicant_network_get_phy_mode(GSupplicantNetwork *network)
+{
+ if (!network)
+ return G_SUPPLICANT_MODE_IEEE80211_UNKNOWN;
+
+ return network->phy_mode;
+}
+#endif
+
GSupplicantInterface *g_supplicant_peer_get_interface(GSupplicantPeer *peer)
{
if (!peer)
return network->keymgmt;
}
+
+const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork
+ *network)
+{
+ if (!network)
+ return NULL;
+
+ return network->country_code;
+}
#endif
const unsigned char *g_supplicant_peer_get_widi_ies(GSupplicantPeer *peer,
return NULL;
if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
+#if defined TIZEN_EXT
+ network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
+#endif /* TIZEN_EXT */
network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
unsigned int pairwise;
if (network == NULL || network->best_bss == NULL)
return 0;
+#if defined TIZEN_EXT
+ if (network->best_bss->security == G_SUPPLICANT_SECURITY_SAE)
+ return false;
+#endif /* TIZEN_EXT */
+
if (network->best_bss->rsn_selected) {
const char *mode = g_supplicant_network_get_enc_mode(network);
if (g_strcmp0(mode, "aes") == 0 ||
return false;
}
-const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
- unsigned int *wifi_vsie_len)
+void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network)
{
- if (!network) {
- *wifi_vsie_len = 0;
+ GSList *vsie_list = NULL;
+
+ if (!network)
return NULL;
+
+ if (g_slist_length(network->vsie_list) > 0) {
+ GSList *list = NULL;
+ unsigned char *vsie = NULL;
+ for (list = network->vsie_list; list; list = list->next) {
+ unsigned char *ie = (unsigned char *)list->data;
+ if (ie == NULL)
+ continue;
+ vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
+
+ if (vsie) {
+ memcpy(vsie, ie, ie[1]+2);
+ vsie_list = g_slist_append(vsie_list, vsie);
+ } else
+ SUPPLICANT_DBG("Failed to allocate memory");
+ }
}
- *wifi_vsie_len = network->wifi_vsie_len;
- return network->wifi_vsie;
+ return vsie_list;
+}
+
+static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
+{
+ struct g_supplicant_bss *bss = value;
+ struct g_connman_bssids *bssids = NULL;
+ GSList **list = (GSList **)user_data;
+
+ bssids = (struct g_connman_bssids *)g_try_malloc0(sizeof(struct g_connman_bssids));
+
+ if (bssids) {
+ memcpy(bssids->bssid, bss->bssid, WIFI_BSSID_LEN_MAX);
+
+ bssids->strength = bss->signal;
+ bssids->strength += 120;
+
+ if (bssids->strength > 100)
+ bssids->strength = 100;
+
+ bssids->frequency = bss->frequency;
+ *list = g_slist_append(*list, bssids);
+ } else
+ SUPPLICANT_DBG("Failed to allocate memory");
+}
+
+static gint cmp_bss(gconstpointer a, gconstpointer b)
+{
+ struct g_connman_bssids *entry_a = (struct g_connman_bssids *)a;
+ struct g_connman_bssids *entry_b = (struct g_connman_bssids *)b;
+
+ if (entry_a->strength > entry_b->strength)
+ return -1;
+
+ if (entry_a->strength < entry_b->strength)
+ return 1;
+
+ return 0;
+}
+
+void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
+{
+ GSList *bssid_list = NULL;
+
+ if (g_hash_table_size(network->bss_table) < 1)
+ return NULL;
+
+ g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_list);
+ bssid_list = g_slist_sort(bssid_list, cmp_bss);
+
+ return bssid_list;
}
#endif
GString *str;
const char *ssid, *mode, *key_mgmt;
#if defined TIZEN_EXT
- GSupplicantInterface *interface;
const char *isHS20AP;
const char *eap, *identity, *phase2;
#endif
eap = g_hash_table_lookup(network->config_table, "eap");
identity = g_hash_table_lookup(network->config_table, "identity");
phase2 = g_hash_table_lookup(network->config_table, "phase2");
- interface = network->interface;
#endif
SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
g_string_append_printf(str, "_managed");
else if (g_strcmp0(mode, "1") == 0)
g_string_append_printf(str, "_adhoc");
+#if defined TIZEN_EXT_WIFI_MESH
+ else if (g_strcmp0(mode, "5") == 0)
+ g_string_append_printf(str, "_mesh");
+#endif
if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
g_string_append_printf(str, "_psk");
} else
network->isHS20AP = 0;
- if (interface)
- interface->network_path = g_strdup(network->path);
-
network->group = g_strdup(group);
callback_network_merged(network);
+ g_free(network->group);
#endif
g_free(group);
#if defined TIZEN_EXT
network->keymgmt = bss->keymgmt;
- if (bss->wifi_vsie_len > 0) {
- SUPPLICANT_DBG("vsie len: %d", bss->wifi_vsie_len);
- network->wifi_vsie = (char *)g_try_malloc0(bss->wifi_vsie_len);
- if(network->wifi_vsie) {
- network->wifi_vsie_len = bss->wifi_vsie_len;
- memcpy(network->wifi_vsie, bss->wifi_vsie, network->wifi_vsie_len);
- } else {
- SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
+ if (g_slist_length(bss->vsie_list) > 0) {
+ GSList *list = NULL;
+ unsigned char *vsie = NULL;
+ for (list = bss->vsie_list; list; list = list->next) {
+ unsigned char *ie = (unsigned char *)list->data;
+ vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
+
+ if (vsie) {
+ memcpy(vsie, ie, ie[1]+2);
+ network->vsie_list = g_slist_append(network->vsie_list, vsie);
+ } else
+ SUPPLICANT_DBG("Failed to allocate memory.");
}
}
network->isHS20AP = bss->hs20;
+ memcpy(network->country_code, bss->country_code, COUNTRY_CODE_LENGTH);
+ network->phy_mode = bss->phy_mode;
#endif
SUPPLICANT_DBG("New network %s created", network->name);
return 0;
}
+#if defined TIZEN_EXT
+static void get_bss_phy_mode(unsigned int max_rate,
+ unsigned int max_ext_rate, bool ht, bool vht, void *data)
+{
+ struct g_supplicant_bss *bss = data;
+ unsigned int freq = bss->frequency;
+
+ /* Following conditions are used to determine
+ * IEEE 802.11 Protocol Modes:-
+ *
+ * 1. If “Supported rates” is only till 11 Mbps,
+ * and frequency is in 2.4GHz band, then protocol is 11B.
+ * 2. If “Supported rates” is till 54Mbps or
+ * “Extended supported rates” are present,
+ * and frequency is in 2.4GHz band, then protocol is 11G.
+ * 3. If “Supported rates” is only till 54 Mbps,
+ * frequency is in 5GHz band , then protocol is 11A.
+ * 4. If “HT capabilities” is supported , then protocol is 11N.
+ * 5. If “HT capabilities” & “VHT” is supported and
+ * frequency is in 5 GHz band, then protocol is 11AC.
+ * */
+
+ if (freq >= 2412 && freq <= 2484) { /* 2.4 Ghz Band */
+ if (max_rate <= 11 && max_ext_rate <= 0 && !ht)
+ bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211B;
+ else if ((max_rate <= 54 || max_ext_rate > 0) && !ht)
+ bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211BG;
+ else if ((max_rate >= 54 || max_ext_rate > 0) && ht)
+ bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211BGN;
+ else
+ bss->phy_mode = G_SUPPLICANT_MODE_UNKNOWN;
+ } else if (freq >= 5180 && freq <= 5825) { /* 5 Ghz Band */
+ if (max_rate <= 54 && !ht)
+ bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211A;
+ else if ((max_rate >= 54 || max_ext_rate > 0) && ht && !vht)
+ bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211AN;
+ else if ((max_rate >= 54 || max_ext_rate > 0) && ht && vht)
+ bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211ANAC;
+ else
+ bss->phy_mode = G_SUPPLICANT_MODE_UNKNOWN;
+ }
+}
+#endif
+
static void bss_process_ies(DBusMessageIter *iter, void *user_data)
{
struct g_supplicant_bss *bss = user_data;
const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
-#if defined TIZEN_EXT
- const unsigned char WIFI_OUI[] = {0x00, 0x16, 0x32};
-#endif
unsigned char *ie, *ie_end;
DBusMessageIter array;
unsigned int value;
int ie_len;
+#if defined TIZEN_EXT
+ int r_len, j;
+ unsigned char *rates = NULL;
+ unsigned char *ext_rates = NULL;
+ unsigned int max_rate = 0;
+ unsigned int max_ext_rate = 0;
+ bool ht = false;
+ bool vht = false;
+#endif
#define WMM_WPA1_WPS_INFO 221
#define WPS_INFO_MIN_LEN 6
#define WPS_CONFIGURED 0x02
#if defined TIZEN_EXT
#define VENDOR_SPECIFIC_INFO 0xDD
+#define WLAN_EID_COUNTRY 7
#endif
dbus_message_iter_recurse(iter, &array);
bss->wps_capabilities = 0;
bss->keymgmt = 0;
+ memset(bss->country_code, 0, COUNTRY_CODE_LENGTH);
for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
ie += ie[1] + 2) {
#if defined TIZEN_EXT
- if((ie[0] == VENDOR_SPECIFIC_INFO) && (memcmp(ie+2, WIFI_OUI, sizeof(WIFI_OUI)) == 0)) {
- SUPPLICANT_DBG("IE: match WIFI_OUI");
- bss->wifi_vsie = (char *)g_try_malloc0(ie[1] + 2); // tag number size(1), tag length size(1)
- if (bss->wifi_vsie) {
- bss->wifi_vsie_len = ie[1] + 2;
- memcpy(bss->wifi_vsie, ie, bss->wifi_vsie_len);
- } else {
- SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
- }
+ unsigned char *vsie;
+ int vsie_len = 0;
+ if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
+ SUPPLICANT_DBG("IE: match vendor specific data");
+
+ vsie_len = ie[1]+2; // tag number size(1), tag length size(1)
+ vsie = (unsigned char *)g_try_malloc0(vsie_len);
+
+ if (vsie) {
+ memcpy(vsie, ie, vsie_len);
+ bss->vsie_list = g_slist_append(bss->vsie_list, vsie);
+ } else
+ SUPPLICANT_DBG("Failed to allocate memory");
+ continue;
+ }
+
+ if(ie[0] == WLAN_EID_COUNTRY && ie[1] >= 2) {
+ /* Add country code only if it is a valid alphabet */
+ if (ie[2] >= 65 && ie[2] <= 90 && ie[3] >= 65 && ie[3] <= 90) {
+ memcpy(bss->country_code, ie+2, COUNTRY_CODE_LENGTH);
+ continue;
+ }
+ }
+
+ if (ie[0] == WLAN_EID_HT_CAP && ie[1]) {
+ ht = true;
+ continue;
+ }
+
+ if (ie[0] == WLAN_EID_VHT_CAP && ie[1]) {
+ vht = true;
+ continue;
+ }
+
+ if (ie[0] == WLAN_EID_SUPP_RATES && ie[1]) {
+ r_len = ie[1];
+ rates = g_malloc0(r_len);
+ if (!rates)
+ continue;
+
+ for (j = 0; ie && j < r_len; j++) {
+ rates[j] = ((ie[j + 2] & 0x7f) * 500000)/1000000;
+ if (max_rate < rates[j])
+ max_rate = rates[j];
+ }
+ continue;
+ }
+
+ if (ie[0] == WLAN_EID_EXT_SUPP_RATES && ie[1] > 0) {
+ r_len = ie[1];
+ ext_rates = g_malloc0(r_len);
+ if (!ext_rates)
continue;
+
+ for (j = 0; ie && j < r_len; j++) {
+ ext_rates[j] = ((ie[j + 2] & 0x7f) * 500000)/1000000;
+ if (max_ext_rate < ext_rates[j])
+ max_ext_rate = ext_rates[j];
+ }
+ continue;
}
#endif
if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
SUPPLICANT_DBG("WPS Methods 0x%x", bss->wps_capabilities);
}
+#ifdef TIZEN_EXT
+ get_bss_phy_mode(max_rate, max_ext_rate, ht, vht, user_data);
+ if (rates)
+ g_free(rates);
+ if (ext_rates)
+ g_free(ext_rates);
+#endif
}
static void bss_compute_security(struct g_supplicant_bss *bss)
bss->psk = TRUE;
#endif
+#if defined TIZEN_EXT
+ if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
+ bss->sae = TRUE;
+#endif
+
if (bss->ieee8021x)
bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
else if (bss->psk)
else if (bss->ft_ieee8021x == TRUE)
bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
#endif
+#if defined TIZEN_EXT
+ else if (bss->sae)
+ bss->security = G_SUPPLICANT_SECURITY_SAE;
+#endif
else if (bss->privacy)
bss->security = G_SUPPLICANT_SECURITY_WEP;
else
GSupplicantNetwork *network;
struct g_supplicant_bss *bss = NULL;
const char *path = NULL;
+ bool is_current_network_bss = false;
dbus_message_iter_get_basic(iter, &path);
if (!path)
if (network->best_bss == bss) {
network->best_bss = NULL;
network->signal = BSS_UNKNOWN_STRENGTH;
+ is_current_network_bss = true;
}
g_hash_table_remove(bss_mapping, path);
update_network_signal(network);
- if (g_hash_table_size(network->bss_table) == 0)
+ if (g_hash_table_size(network->bss_table) == 0) {
g_hash_table_remove(interface->network_table, network->group);
+ } else {
+ if (is_current_network_bss && network->best_bss)
+#if defined TIZEN_EXT
+ callback_network_changed(network, "CheckMultiBssidConnect");
+#else
+ callback_network_changed(network, "");
+#endif
+ }
}
static void set_config_methods(DBusMessageIter *iter, void *user_data)
if (interface->mode_capa & G_SUPPLICANT_CAPABILITY_MODE_P2P)
interface->p2p_support = true;
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+ if (interface->mode_capa & G_SUPPLICANT_CAPABILITY_MODE_MESH)
+ interface->mesh_support = true;
+#endif
} else if (g_strcmp0(key, "State") == 0) {
const char *str = NULL;
interface_network_removed(iter, interface);
}
+#if defined TIZEN_EXT
+void *copy_vsie_list(gconstpointer src, gpointer data)
+{
+ return g_strdup(src);
+}
+#endif
+
static void signal_bss_changed(const char *path, DBusMessageIter *iter)
{
supplicant_dbus_property_foreach(iter, bss_property, bss);
#if defined TIZEN_EXT
network->frequency = bss->frequency;
+ network->phy_mode = bss->phy_mode;
#endif
old_security = network->security;
bss_compute_security(bss);
memcpy(new_bss, bss, sizeof(struct g_supplicant_bss));
new_bss->path = g_strdup(bss->path);
+#if defined TIZEN_EXT
+ new_bss->vsie_list = g_slist_copy_deep(bss->vsie_list, copy_vsie_list, NULL);
+#endif
g_hash_table_remove(interface->network_table, network->group);
peer->connection_requested = false;
}
-static struct {
- const char *interface;
- const char *member;
- void (*function) (const char *path, DBusMessageIter *iter);
-} signal_map[] = {
- { DBUS_INTERFACE_DBUS, "NameOwnerChanged", signal_name_owner_changed },
+#if defined TIZEN_EXT_WIFI_MESH
+const void *g_supplicant_interface_get_mesh_group_ssid(
+ GSupplicantInterface *interface,
+ unsigned int *ssid_len)
+{
+ if (!ssid_len)
+ return NULL;
- { SUPPLICANT_INTERFACE, "PropertiesChanged", signal_properties_changed },
- { SUPPLICANT_INTERFACE, "InterfaceAdded", signal_interface_added },
- { SUPPLICANT_INTERFACE, "InterfaceCreated", signal_interface_added },
- { SUPPLICANT_INTERFACE, "InterfaceRemoved", signal_interface_removed },
+ if (!interface || interface->group_info.ssid_len == 0) {
+ *ssid_len = 0;
+ return NULL;
+ }
- { SUPPLICANT_INTERFACE ".Interface", "PropertiesChanged", signal_interface_changed },
- { SUPPLICANT_INTERFACE ".Interface", "ScanDone", signal_scan_done },
- { SUPPLICANT_INTERFACE ".Interface", "BSSAdded", signal_bss_added },
- { SUPPLICANT_INTERFACE ".Interface", "BSSRemoved", signal_bss_removed },
- { SUPPLICANT_INTERFACE ".Interface", "NetworkAdded", signal_network_added },
- { SUPPLICANT_INTERFACE ".Interface", "NetworkRemoved", signal_network_removed },
+ *ssid_len = interface->group_info.ssid_len;
+ return interface->group_info.ssid;
+}
- { SUPPLICANT_INTERFACE ".BSS", "PropertiesChanged", signal_bss_changed },
+int g_supplicant_mesh_get_disconnect_reason(GSupplicantInterface *interface)
+{
+ if (!interface)
+ return -EINVAL;
- { SUPPLICANT_INTERFACE ".Interface.WPS", "Credentials", signal_wps_credentials },
- { SUPPLICANT_INTERFACE ".Interface.WPS", "Event", signal_wps_event },
-#if defined TIZEN_EXT
- { "org.tizen.system.deviced.PowerOff", "ChangeState", signal_power_off },
-#endif
+ return interface->group_info.disconnect_reason;
+}
- { SUPPLICANT_INTERFACE".Interface", "StaAuthorized", signal_station_connected },
- { SUPPLICANT_INTERFACE".Interface", "StaDeauthorized", signal_station_disconnected },
+const char *g_supplicant_mesh_peer_get_address(GSupplicantMeshPeer *mesh_peer)
+{
+ if (!mesh_peer || !mesh_peer->peer_address)
+ return NULL;
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", signal_peer_found },
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost", signal_peer_lost },
+ return mesh_peer->peer_address;
+}
- { SUPPLICANT_INTERFACE ".Peer", "PropertiesChanged", signal_peer_changed },
+int g_supplicant_mesh_peer_get_disconnect_reason(GSupplicantMeshPeer *mesh_peer)
+{
+ if (!mesh_peer)
+ return -EINVAL;
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationSuccess", signal_group_success },
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationFailure", signal_group_failure },
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupStarted", signal_group_started },
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupFinished", signal_group_finished },
- { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationRequest", signal_group_request },
+ return mesh_peer->disconnect_reason;
+}
- { SUPPLICANT_INTERFACE ".Group", "PeerJoined", signal_group_peer_joined },
- { SUPPLICANT_INTERFACE ".Group", "PeerDisconnected", signal_group_peer_disconnected },
+static void callback_mesh_group_started(GSupplicantInterface *interface)
+{
+ if (!callbacks_pointer)
+ return;
- { }
-};
+ if (!callbacks_pointer->mesh_group_started)
+ return;
-static DBusHandlerResult g_supplicant_filter(DBusConnection *conn,
- DBusMessage *message, void *data)
+ callbacks_pointer->mesh_group_started(interface);
+}
+
+static void callback_mesh_group_removed(GSupplicantInterface *interface)
{
- DBusMessageIter iter;
- const char *path;
- int i;
+ if (!callbacks_pointer)
+ return;
- path = dbus_message_get_path(message);
- if (!path)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ if (!callbacks_pointer->mesh_group_removed)
+ return;
- if (!dbus_message_iter_init(message, &iter))
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ callbacks_pointer->mesh_group_removed(interface);
+}
- for (i = 0; signal_map[i].interface; i++) {
- if (!dbus_message_has_interface(message, signal_map[i].interface))
- continue;
+static void mesh_group_info(const char *key, DBusMessageIter *iter,
+ void *user_data)
+{
+ GSupplicantInterface *interface = user_data;
+ if (!key)
+ return;
+
+ if (g_strcmp0(key, "SSID") == 0) {
+ DBusMessageIter array;
+ unsigned char *ssid;
+ int ssid_len;
+
+ dbus_message_iter_recurse(iter, &array);
+ dbus_message_iter_get_fixed_array(&array, &ssid, &ssid_len);
+
+ if (ssid_len > 0 && ssid_len < 33) {
+ memcpy(interface->group_info.ssid, ssid, ssid_len);
+ interface->group_info.ssid_len = ssid_len;
+ } else {
+ memset(interface->group_info.ssid, 0, 32);
+ interface->group_info.ssid_len = 0;
+ }
+ } else if (g_strcmp0(key, "DisconnectReason") == 0) {
+ int disconnect_reason = 0;
+ dbus_message_iter_get_basic(iter, &disconnect_reason);
+ interface->group_info.disconnect_reason = disconnect_reason;
+ }
+}
+
+static void signal_mesh_group_started(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ supplicant_dbus_property_foreach(iter, mesh_group_info, interface);
+
+ callback_mesh_group_started(interface);
+}
+
+static void signal_mesh_group_removed(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ supplicant_dbus_property_foreach(iter, mesh_group_info, interface);
+
+ callback_mesh_group_removed(interface);
+}
+
+static void callback_mesh_peer_connected(GSupplicantMeshPeer *mesh_peer)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->mesh_peer_connected)
+ return;
+
+ callbacks_pointer->mesh_peer_connected(mesh_peer);
+}
+
+static void callback_mesh_peer_disconnected(GSupplicantMeshPeer *mesh_peer)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->mesh_peer_disconnected)
+ return;
+
+ callbacks_pointer->mesh_peer_disconnected(mesh_peer);
+}
+
+static void mesh_peer_info(const char *key, DBusMessageIter *iter,
+ void *user_data)
+{
+ GSupplicantMeshPeer *mesh_peer = user_data;
+ if (!key)
+ return;
+
+ if (g_strcmp0(key, "PeerAddress") == 0) {
+ DBusMessageIter array;
+ unsigned char *addr;
+ int addr_len;
+
+ dbus_message_iter_recurse(iter, &array);
+ dbus_message_iter_get_fixed_array(&array, &addr, &addr_len);
+
+ if (addr_len == 6) {
+ mesh_peer->peer_address = g_malloc0(19);
+ snprintf(mesh_peer->peer_address, 19,
+ "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1],
+ addr[2], addr[3], addr[4], addr[5]);
+ }
+ } else if (g_strcmp0(key, "DisconnectReason") == 0) {
+ int disconnect_reason = 0;
+ dbus_message_iter_get_basic(iter, &disconnect_reason);
+ mesh_peer->disconnect_reason = disconnect_reason;
+ }
+}
+
+static void signal_mesh_peer_connected(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ GSupplicantMeshPeer *mesh_peer;
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ mesh_peer = dbus_malloc0(sizeof(GSupplicantMeshPeer));
+ mesh_peer->interface = interface;
+
+ supplicant_dbus_property_foreach(iter, mesh_peer_info, mesh_peer);
+
+ callback_mesh_peer_connected(mesh_peer);
+ g_free(mesh_peer->peer_address);
+ g_free(mesh_peer);
+}
+
+static void signal_mesh_peer_disconnected(const char *path,
+ DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ GSupplicantMeshPeer *mesh_peer;
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ mesh_peer = dbus_malloc0(sizeof(GSupplicantMeshPeer));
+ mesh_peer->interface = interface;
+
+ supplicant_dbus_property_foreach(iter, mesh_peer_info, mesh_peer);
+
+ callback_mesh_peer_disconnected(mesh_peer);
+ g_free(mesh_peer->peer_address);
+ g_free(mesh_peer);
+}
+#endif
+
+static struct {
+ const char *interface;
+ const char *member;
+ void (*function) (const char *path, DBusMessageIter *iter);
+} signal_map[] = {
+ { DBUS_INTERFACE_DBUS, "NameOwnerChanged", signal_name_owner_changed },
+
+ { SUPPLICANT_INTERFACE, "PropertiesChanged", signal_properties_changed },
+ { SUPPLICANT_INTERFACE, "InterfaceAdded", signal_interface_added },
+ { SUPPLICANT_INTERFACE, "InterfaceCreated", signal_interface_added },
+ { SUPPLICANT_INTERFACE, "InterfaceRemoved", signal_interface_removed },
+
+ { SUPPLICANT_INTERFACE ".Interface", "PropertiesChanged", signal_interface_changed },
+ { SUPPLICANT_INTERFACE ".Interface", "ScanDone", signal_scan_done },
+ { SUPPLICANT_INTERFACE ".Interface", "BSSAdded", signal_bss_added },
+ { SUPPLICANT_INTERFACE ".Interface", "BSSRemoved", signal_bss_removed },
+ { SUPPLICANT_INTERFACE ".Interface", "NetworkAdded", signal_network_added },
+ { SUPPLICANT_INTERFACE ".Interface", "NetworkRemoved", signal_network_removed },
+
+ { SUPPLICANT_INTERFACE ".BSS", "PropertiesChanged", signal_bss_changed },
+
+ { SUPPLICANT_INTERFACE ".Interface.WPS", "Credentials", signal_wps_credentials },
+ { SUPPLICANT_INTERFACE ".Interface.WPS", "Event", signal_wps_event },
+#if defined TIZEN_EXT
+ { "org.tizen.system.deviced.PowerOff", "ChangeState", signal_power_off },
+#endif
+
+ { SUPPLICANT_INTERFACE".Interface", "StaAuthorized", signal_station_connected },
+ { SUPPLICANT_INTERFACE".Interface", "StaDeauthorized", signal_station_disconnected },
+
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", signal_peer_found },
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost", signal_peer_lost },
+
+ { SUPPLICANT_INTERFACE ".Peer", "PropertiesChanged", signal_peer_changed },
+
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationSuccess", signal_group_success },
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationFailure", signal_group_failure },
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupStarted", signal_group_started },
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupFinished", signal_group_finished },
+ { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationRequest", signal_group_request },
+
+ { SUPPLICANT_INTERFACE ".Group", "PeerJoined", signal_group_peer_joined },
+ { SUPPLICANT_INTERFACE ".Group", "PeerDisconnected", signal_group_peer_disconnected },
+#if defined TIZEN_EXT_WIFI_MESH
+ { SUPPLICANT_INTERFACE ".Interface.Mesh", "MeshGroupStarted",
+ signal_mesh_group_started },
+ { SUPPLICANT_INTERFACE ".Interface.Mesh", "MeshGroupRemoved",
+ signal_mesh_group_removed },
+ { SUPPLICANT_INTERFACE ".Interface.Mesh", "MeshPeerConnected",
+ signal_mesh_peer_connected },
+ { SUPPLICANT_INTERFACE ".Interface.Mesh", "MeshPeerDisconnected",
+ signal_mesh_peer_disconnected },
+#endif
+
+ { }
+};
+
+static DBusHandlerResult g_supplicant_filter(DBusConnection *conn,
+ DBusMessage *message, void *data)
+{
+ DBusMessageIter iter;
+ const char *path;
+ int i;
+
+ path = dbus_message_get_path(message);
+ if (!path)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (!dbus_message_iter_init(message, &iter))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ for (i = 0; signal_map[i].interface; i++) {
+ if (!dbus_message_has_interface(message, signal_map[i].interface))
+ continue;
if (!dbus_message_has_member(message, signal_map[i].member))
continue;
g_free(data->ifname);
g_free(data->driver);
g_free(data->bridge);
+#if defined TIZEN_EXT_WIFI_MESH
+ g_free(data->parent_ifname);
+#endif
dbus_free(data);
}
#if !defined TIZEN_EXT
callback_p2p_support(interface);
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+ callback_mesh_support(interface);
+#endif
}
interface_create_data_free(data);
DBUS_TYPE_STRING, &config_file);
}
+#if defined TIZEN_EXT_WIFI_MESH
+ if (data->is_mesh_interface) {
+ if (data->parent_ifname)
+ supplicant_dbus_dict_append_basic(&dict, "ParentIfname",
+ DBUS_TYPE_STRING, &data->parent_ifname);
+
+ supplicant_dbus_dict_append_basic(&dict, "IsMeshInterface",
+ DBUS_TYPE_BOOLEAN, &data->is_mesh_interface);
+ }
+#endif
+
supplicant_dbus_dict_close(iter, &dict);
}
#if !defined TIZEN_EXT
callback_p2p_support(interface);
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+ callback_mesh_support(interface);
+#endif
}
interface_create_data_free(data);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &data->ifname);
}
+#if defined TIZEN_EXT_WIFI_MESH
+int g_supplicant_mesh_interface_create(const char *ifname, const char *driver,
+ const char *bridge, const char *parent_ifname,
+ GSupplicantInterfaceCallback callback, void *user_data)
+{
+ struct interface_create_data *data;
+ int ret;
+
+ SUPPLICANT_DBG("ifname %s", ifname);
+
+ if (!ifname || !parent_ifname)
+ return -EINVAL;
+
+ if (!system_available)
+ return -EFAULT;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->ifname = g_strdup(ifname);
+ data->driver = g_strdup(driver);
+ data->bridge = g_strdup(bridge);
+ data->is_mesh_interface = true;
+ data->parent_ifname = g_strdup(parent_ifname);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
+ SUPPLICANT_INTERFACE,
+ "CreateInterface",
+ interface_create_params,
+ interface_create_result, data,
+ NULL);
+ return ret;
+}
+
+struct interface_mesh_peer_data {
+ char *peer_address;
+ char *method;
+ GSupplicantInterface *interface;
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+};
+
+static void interface_mesh_change_peer_params(DBusMessageIter *iter,
+ void *user_data)
+{
+ struct interface_mesh_peer_data *data = user_data;
+
+ SUPPLICANT_DBG("");
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &data->peer_address);
+}
+
+static void interface_mesh_change_peer_result(const char *error,
+ DBusMessageIter *iter, void *user_data)
+{
+ struct interface_mesh_peer_data *data = user_data;
+ int err = 0;
+
+ SUPPLICANT_DBG("%s", data->method);
+
+ if (error) {
+ err = -EIO;
+ SUPPLICANT_DBG("error %s", error);
+ }
+
+ if (data->callback)
+ data->callback(err, data->interface, data->user_data);
+
+ g_free(data->peer_address);
+ g_free(data->method);
+ dbus_free(data);
+}
+
+int g_supplicant_interface_mesh_peer_change_status(
+ GSupplicantInterface *interface,
+ GSupplicantInterfaceCallback callback, const char *peer_address,
+ const char *method, void *user_data)
+{
+ struct interface_mesh_peer_data *data;
+ int ret;
+
+ if (!peer_address)
+ return -EINVAL;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->peer_address = g_strdup(peer_address);
+ data->method = g_strdup(method);
+ data->interface = interface;
+ data->callback = callback;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface.Mesh",
+ method, interface_mesh_change_peer_params,
+ interface_mesh_change_peer_result, data, NULL);
+ if (ret < 0) {
+ g_free(data->peer_address);
+ g_free(data->method);
+ dbus_free(data);
+ }
+
+ return ret;
+}
+#endif
+
int g_supplicant_interface_create(const char *ifname, const char *driver,
const char *bridge,
GSupplicantInterfaceCallback callback,
return 0;
}
+#if defined TIZEN_EXT_WIFI_MESH
+static void interface_abort_scan_result(const char *error,
+ DBusMessageIter *iter, void *user_data)
+{
+ struct interface_scan_data *data = user_data;
+ int err = 0;
+
+ if (error) {
+ SUPPLICANT_DBG("error %s", error);
+ err = -EIO;
+ }
+
+ g_free(data->path);
+
+ if (data->callback)
+ data->callback(err, data->interface, data->user_data);
+
+ dbus_free(data);
+}
+
+int g_supplicant_interface_abort_scan(GSupplicantInterface *interface,
+ GSupplicantInterfaceCallback callback, void *user_data)
+{
+ struct interface_scan_data *data;
+ int ret;
+
+ if (!interface->scanning)
+ return -EEXIST;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->interface = interface;
+ data->path = g_strdup(interface->path);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AbortScan", NULL,
+ interface_abort_scan_result, data, interface);
+
+ if (ret < 0) {
+ g_free(data->path);
+ dbus_free(data);
+ }
+
+ return ret;
+}
+#endif
+
int g_supplicant_interface_scan(GSupplicantInterface *interface,
GSupplicantScanParams *scan_data,
GSupplicantInterfaceCallback callback,
return ret;
}
+#if defined TIZEN_EXT
+static void interface_signalpoll_result(const char *error,
+ DBusMessageIter *iter, void *user_data)
+{
+ struct interface_signalpoll_data *data = user_data;
+ int err = 0;
+ dbus_int32_t maxspeed = 0;
+ DBusMessageIter sub_iter, dict;
+
+ if (error) {
+ err = -EIO;
+ SUPPLICANT_DBG("error: %s", error);
+ goto out;
+ }
+
+ dbus_message_iter_get_arg_type(iter);
+ dbus_message_iter_recurse(iter, &sub_iter);
+ dbus_message_iter_recurse(&sub_iter, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ switch (dbus_message_iter_get_arg_type(&value)) {
+ case DBUS_TYPE_INT32:
+ if (g_strcmp0(key, "linkspeed") == 0) {
+ dbus_message_iter_get_basic(&value, &maxspeed);
+ SUPPLICANT_DBG("linkspeed = %d", maxspeed);
+ break;
+ }
+ }
+ dbus_message_iter_next(&dict);
+ }
+
+out:
+ if(data->callback)
+ data->callback(err, maxspeed, data->user_data);
+
+ g_free(data->path);
+ dbus_free(data);
+}
+
+int g_supplicant_interface_signalpoll(GSupplicantInterface *interface,
+ GSupplicantMaxSpeedCallback callback,
+ void *user_data)
+{
+ struct interface_signalpoll_data *data;
+ int ret;
+
+ if (!interface)
+ return -EINVAL;
+
+ if (!system_available)
+ return -EFAULT;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->interface = interface;
+ data->path = g_strdup(interface->path);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "SignalPoll",
+ NULL, interface_signalpoll_result, data,
+ interface);
+
+ if (ret < 0) {
+ g_free(data->path);
+ dbus_free(data);
+ }
+
+ return ret;
+}
+#endif
+
static int parse_supplicant_error(DBusMessageIter *iter)
{
int err = -ECONNABORTED;
if (data->callback)
data->callback(err, data->interface, data->user_data);
+#if defined TIZEN_EXT
+ g_free(data->ssid->ssid);
+ g_free((char *)data->ssid->passphrase);
+#endif
g_free(data->ssid);
dbus_free(data);
}
dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
&interface->network_path);
#if defined TIZEN_EXT
- dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &ssid->freq);
+ if (!ssid->bssid_for_connect_len)
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &ssid->freq);
#endif
}
SUPPLICANT_DBG("PATH: %s", path);
+#if defined TIZEN_EXT
+ if (interface->network_path)
+ g_free(interface->network_path);
+#endif
interface->network_path = g_strdup(path);
store_network_information(interface, data->ssid);
#if defined TIZEN_EXT
SUPPLICANT_DBG(".Interface.SelectNetworkFreq");
-#endif
+ GSupplicantSSID *ssid = data->ssid;
-#if defined TIZEN_EXT
- supplicant_dbus_method_call(data->interface->path,
- SUPPLICANT_INTERFACE ".Interface", "SelectNetworkFreq",
- interface_select_network_params,
- interface_select_network_result, data,
- interface);
+ if (!ssid->bssid_for_connect_len)
+ supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "SelectNetworkFreq",
+ interface_select_network_params,
+ interface_select_network_result, data,
+ interface);
+ else
+ supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
+ interface_select_network_params,
+ interface_select_network_result, data,
+ interface);
#else
supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
}
g_free(data->path);
+#if defined TIZEN_EXT
+ g_free(data->ssid->ssid);
+ g_free((char *)data->ssid->passphrase);
+#endif
g_free(data->ssid);
g_free(data);
}
DBUS_TYPE_STRING,
&ssid->passphrase);
}
+
+static void add_network_security_fast(DBusMessageIter *dict,
+ GSupplicantSSID *ssid)
+{
+ /*
+ * For FAST, we at least need:
+ * id / password
+ * phase1 (provisiong information)
+ * pac_file
+ */
+
+ /* Allow provisioing both authenticated and unauthenticated */
+ const char *phase1 = "fast_provisioning=2";
+ supplicant_dbus_dict_append_basic(dict, "phase1",
+ DBUS_TYPE_STRING,
+ &phase1);
+
+ SUPPLICANT_DBG("pac_file [%s]", ssid->pac_file);
+ if(ssid->pac_file)
+ supplicant_dbus_dict_append_basic(dict, "pac_file",
+ DBUS_TYPE_STRING,
+ &ssid->pac_file);
+
+ supplicant_dbus_dict_append_basic(dict, "password",
+ DBUS_TYPE_STRING,
+ &ssid->passphrase);
+}
#endif
static void add_network_security_eap(DBusMessageIter *dict,
#if defined TIZEN_EXT
} else if (g_strcmp0(ssid->eap, "sim") == 0 ||
- g_strcmp0(ssid->eap, "aka") == 0) {
+ g_strcmp0(ssid->eap, "aka") == 0 ||
+ g_strcmp0(ssid->eap, "aka'") == 0) {
add_network_security_aka_sim(dict, ssid);
+ } else if (g_strcmp0(ssid->eap, "pwd") == 0) {
+ if(!ssid->passphrase)
+ return;
+ supplicant_dbus_dict_append_basic(dict, "password",
+ DBUS_TYPE_STRING,
+ &ssid->passphrase);
+ } else if (g_strcmp0(ssid->eap, "fast") == 0){
+ if (!ssid->identity || !ssid->passphrase)
+ return;
+
+ add_network_security_fast(dict, ssid);
#endif
} else
return;
g_free(proto);
}
+#if defined TIZEN_EXT
+static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+ if (ssid->security != G_SUPPLICANT_SECURITY_SAE)
+ return;
+
+ supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
+ &ssid->ieee80211w);
+}
+#endif
+
static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
{
char *key_mgmt;
add_network_security_ciphers(dict, ssid);
add_network_security_proto(dict, ssid);
break;
+ case G_SUPPLICANT_SECURITY_SAE:
+ key_mgmt = "SAE";
+ add_network_security_psk(dict, ssid);
+ break;
#endif
}
case G_SUPPLICANT_MODE_MASTER:
mode = 2;
break;
+#if defined TIZEN_EXT_WIFI_MESH
+ case G_SUPPLICANT_MODE_MESH:
+ mode = 5;
+ break;
+#endif
}
supplicant_dbus_dict_append_basic(dict, "mode",
add_network_security(&dict, ssid);
+#if defined TIZEN_EXT
+ add_network_ieee80211w(&dict, ssid);
+#endif
+
supplicant_dbus_dict_append_fixed_array(&dict, "ssid",
DBUS_TYPE_BYTE, &ssid->ssid,
ssid->ssid_len);
supplicant_dbus_dict_close(iter, &dict);
return;
}
- snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+
+ if (ssid->bssid_for_connect_len)
+ snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ ssid->bssid_for_connect[0], ssid->bssid_for_connect[1], ssid->bssid_for_connect[2],
+ ssid->bssid_for_connect[3], ssid->bssid_for_connect[4], ssid->bssid_for_connect[5]);
+ else
+ snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
ssid->bssid[0], ssid->bssid[1], ssid->bssid[2],
ssid->bssid[3], ssid->bssid[4], ssid->bssid[5]);
+
supplicant_dbus_dict_append_basic(&dict, "bssid",
DBUS_TYPE_STRING, &bssid);
g_free(bssid);
DBusMessageIter args;
char *out_data;
int ret;
- static gchar* origin_value = NULL;
struct interface_connect_data *data = user_data;
- g_free(origin_value);
- origin_value = NULL;
-
SUPPLICANT_DBG("");
reply = dbus_pending_call_steal_reply(call);
}
dbus_message_iter_get_basic(&args, &out_data);
-
- origin_value = g_strdup((const gchar *)out_data);
- data->ssid->passphrase = origin_value;
+ data->ssid->passphrase = g_strdup((const gchar *)out_data);
ret = supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
SUPPLICANT_DBG("AddNetwork failed %d", ret);
callback_assoc_failed(decrypt_request_data.data->user_data);
g_free(data->path);
+ g_free(data->ssid->ssid);
+ g_free((char *)data->ssid->passphrase);
g_free(data->ssid);
dbus_free(data);
}
network_remove(intf_data);
} else
#if defined TIZEN_EXT
- if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
+ if (ssid->passphrase &&
+ g_strcmp0(ssid->passphrase, "") != 0 &&
+#if defined TIZEN_EXT_WIFI_MESH
+ ssid->mode != G_SUPPLICANT_MODE_MESH &&
+#endif
+ !ssid->eap) {
ret = send_decryption_request(ssid->passphrase, data);
if (ret < 0)
SUPPLICANT_DBG("Decryption request failed %d", ret);
connect_data->ssid = data->ssid;
connect_data->user_data = data->user_data;
+#if defined TIZEN_EXT
+ int ret;
+ if (data->ssid->passphrase && g_strcmp0(data->ssid->passphrase, "") != 0
+ && !data->ssid->eap) {
+ ret = send_decryption_request(data->ssid->passphrase, connect_data);
+ if (ret < 0) {
+ SUPPLICANT_DBG("Decryption request failed %d", ret);
+ g_free(connect_data->ssid);
+ g_free(connect_data->path);
+ dbus_free(connect_data);
+ }
+ } else
+#endif
supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
interface_add_network_params,
return -EINPROGRESS;
}
-#if defined TIZEN_EXT
-int g_supplicant_interface_remove_network(GSupplicantInterface *interface)
-{
- struct interface_data *data;
-
- SUPPLICANT_DBG("");
-
- if (interface == NULL)
- return -EINVAL;
-
- if (system_available == FALSE)
- return -EFAULT;
-
- data = dbus_malloc0(sizeof(*data));
- if (data == NULL)
- return -ENOMEM;
-
- data->interface = interface;
-
- return network_remove(data);
-}
-#endif
-
static const char *g_supplicant_rule0 = "type=signal,"
"path=" DBUS_PATH_DBUS ","
"sender=" DBUS_SERVICE_DBUS ","
static const char *g_supplicant_rule8 = "type=signal,"
"interface=" SUPPLICANT_INTERFACE ".Group";
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+static const char *g_supplicant_rule9 = "type=signal,"
+ "interface=" SUPPLICANT_INTERFACE ".Interface.Mesh";
+#endif
static void invoke_introspect_method(void)
{
dbus_bus_add_match(connection, g_supplicant_rule7, NULL);
dbus_bus_add_match(connection, g_supplicant_rule8, NULL);
#endif
+#if defined TIZEN_EXT_WIFI_MESH
+ dbus_bus_add_match(connection, g_supplicant_rule9, NULL);
+#endif
dbus_connection_flush(connection);
if (dbus_bus_name_has_owner(connection,
SUPPLICANT_DBG("");
if (connection) {
+#if defined TIZEN_EXT_WIFI_MESH
+ dbus_bus_remove_match(connection, g_supplicant_rule9, NULL);
+#endif
#if !defined TIZEN_EXT
dbus_bus_remove_match(connection, g_supplicant_rule8, NULL);
dbus_bus_remove_match(connection, g_supplicant_rule7, NULL);