#include "dbus.h"
#include "gsupplicant.h"
+#if defined TIZEN_EXT
+#include "setting.h"
+#endif
+
#define IEEE80211_CAP_ESS 0x0001
#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
+
+#if defined TIZEN_EXT
+#define LAST_CONNECTED_TIMEOUT (5 * 60)
+#define ASSOC_REJECT_TIMEOUT 10
+#define FREQ_RANGE_24GHZ_CHANNEL_1 2412
+#define FREQ_RANGE_24GHZ_CHANNEL_14 2484
+#define FREQ_RANGE_5GHZ_CHANNEL_32 5160
+#define FREQ_RANGE_5GHZ_CHANNEL_165 5825
+
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
#define BSS_UNKNOWN_STRENGTH -90
static DBusConnection *connection;
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static GSupplicantCallbacks *callbacks_pointer;
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
static const GSupplicantCallbacks *callbacks_pointer;
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
static dbus_bool_t system_available = FALSE;
static dbus_bool_t system_ready = FALSE;
{ "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_WIFI_MESH
+#if defined TIZEN_EXT
{ "sae", G_SUPPLICANT_KEYMGMT_SAE },
+ { "owe", G_SUPPLICANT_KEYMGMT_OWE },
+ { "dpp", G_SUPPLICANT_KEYMGMT_DPP },
#endif
{ }
};
{ }
};
+#if defined TIZEN_EXT
+struct _GSupplicantINSSettings {
+ GSupplicantINSPreferredFreq preferred_freq_bssid;
+ unsigned int preferred_freq_bssid_score;
+ bool last_connected_bssid;
+ unsigned int last_connected_bssid_score;
+ bool assoc_reject;
+ unsigned int assoc_reject_score;
+ bool signal_bssid;
+ int signal_level3_5ghz;
+ int signal_level3_24ghz;
+};
+
+static struct _GSupplicantINSSettings ins_settings;
+
+static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#endif
+
static GHashTable *interface_table;
static GHashTable *bss_mapping;
static GHashTable *peer_mapping;
GSupplicantSecurity security;
char * passphrase;
char * private_passphrase;
+#if defined TIZEN_EXT
+ char *connector;
+ char *c_sign_key;
+ char *net_access_key;
+#endif
};
#if defined TIZEN_EXT_WIFI_MESH
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
+ unsigned char add_network_bssid[WIFI_BSSID_LEN_MAX];
+ unsigned char connected_bssid[WIFI_BSSID_LEN_MAX];
+#endif
#if defined TIZEN_EXT_WIFI_MESH
bool mesh_support;
struct _GSupplicantMeshGroupInfo group_info;
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_WIFI_MESH
+#if defined TIZEN_EXT
dbus_bool_t sae;
+ dbus_bool_t owe;
+ dbus_bool_t dpp;
+ dbus_bool_t owe_transition_mode;
+ unsigned int transition_mode_ssid_len;
+ unsigned char transition_mode_bssid[6];
+ unsigned char transition_mode_ssid[32];
#endif
};
unsigned int keymgmt;
GSList *vsie_list;
unsigned char country_code[COUNTRY_CODE_LENGTH];
+ GSupplicantPhy_mode phy_mode;
+ dbus_bool_t owe_transition_mode;
+ unsigned int transition_mode_ssid_len;
+ unsigned char transition_mode_bssid[6];
+ unsigned char transition_mode_ssid[32];
+ unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
+ GHashTable *assoc_reject_table;
#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
+ unsigned int mac_addr;
+ unsigned int preassoc_mac_addr;
+ unsigned int random_mac_lifetime;
+#endif /* TIZEN_EXT */
#if defined TIZEN_EXT_WIFI_MESH
char *parent_ifname;
bool is_mesh_interface;
#if defined TIZEN_EXT
struct g_connman_bssids {
- char bssid[18];
+ unsigned char bssid[WIFI_BSSID_LEN_MAX];
uint16_t strength;
uint16_t frequency;
+ uint16_t assoc_reject_cnt;
+ bool is_last_connected;
+#if defined TIZEN_EXT_INS
+ int score_last_connected_bssid;
+ int score_assoc_reject;
+ int score_frequency;
+ int score_strength;
+#endif
+ int ins_score;
+};
+
+struct update_bssid_data {
+ GSupplicantNetwork *network;
+ unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
+ GHashTable *assoc_reject_table;
+ GSList *bssid_list;
+};
+
+struct assoc_reject_data {
+ char *bssid;
+ GSList *reject_time_list;
+};
+
+struct assoc_count_data {
+ time_t ref_time;
+ int assoc_count;
};
+
+static unsigned int last_connected_bss_timeout = 0;
+static bool simplified_log = true;
#endif
static int network_remove(struct interface_data *data);
return "ft_psk";
case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
return "ft_ieee8021x";
-#endif
-#if defined TIZEN_EXT_WIFI_MESH
case G_SUPPLICANT_SECURITY_SAE:
return "sae";
+ case G_SUPPLICANT_SECURITY_OWE:
+ return "owe";
+ case G_SUPPLICANT_SECURITY_DPP:
+ return "dpp";
#endif
}
return FALSE;
}
+#if defined TIZEN_EXT
+ if (interface->network_info.connector &&
+ g_strcmp0(interface->network_info.connector,
+ ssid->connector) != 0) {
+ return FALSE;
+ }
+ if (interface->network_info.c_sign_key &&
+ g_strcmp0(interface->network_info.c_sign_key,
+ ssid->c_sign_key) != 0) {
+ return FALSE;
+ }
+ if (interface->network_info.net_access_key &&
+ g_strcmp0(interface->network_info.net_access_key,
+ ssid->net_access_key) != 0) {
+ return FALSE;
+ }
+#endif
return TRUE;
}
g_free(interface->network_info.ssid);
g_free(interface->network_info.passphrase);
g_free(interface->network_info.private_passphrase);
+#if defined TIZEN_EXT
+ g_free(interface->network_info.connector);
+ g_free(interface->network_info.c_sign_key);
+ g_free(interface->network_info.net_access_key);
+#endif
interface->network_info.ssid = NULL;
interface->network_info.passphrase = NULL;
interface->network_info.private_passphrase = NULL;
+#if defined TIZEN_EXT
+ interface->network_info.connector = NULL;
+ interface->network_info.c_sign_key = NULL;
+ interface->network_info.net_access_key = NULL;
+#endif
}
static int store_network_information(GSupplicantInterface * interface,
callbacks_pointer->assoc_failed(user_data);
}
+
+static void callback_scan_done(GSupplicantInterface *interface)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->scan_done)
+ return;
+
+ callbacks_pointer->scan_done(interface);
+}
#endif
static void callback_network_changed(GSupplicantNetwork *network,
callbacks_pointer->network_associated(network);
}
+static void callback_sta_authorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->sta_authorized)
+ return;
+
+ callbacks_pointer->sta_authorized(interface, addr);
+}
+
+static void callback_sta_deauthorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->sta_deauthorized)
+ return;
+
+ callbacks_pointer->sta_deauthorized(interface, addr);
+}
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static void callback_eap(GSupplicantInterface *interface, bool status)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->eap)
+ return;
+
+ callbacks_pointer->eap(interface, status);
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
static void callback_peer_found(GSupplicantPeer *peer)
{
if (!callbacks_pointer)
callback_network_removed(network);
g_hash_table_destroy(network->config_table);
+#if defined TIZEN_EXT
+ g_hash_table_destroy(network->assoc_reject_table);
+#endif
g_free(network->path);
g_free(network->group);
{
struct g_supplicant_bss *bss = data;
+ supplicant_dbus_property_call_cancel_all(bss);
+
g_free(bss->path);
#if defined TIZEN_EXT
g_slist_free_full(bss->vsie_list, g_free);
g_free(peer);
}
+#if defined TIZEN_EXT
+static void remove_assoc_data(gpointer data)
+{
+ struct assoc_reject_data *assoc_data = data;
+
+ g_free(assoc_data->bssid);
+ g_slist_free(assoc_data->reject_time_list);
+
+ g_free(assoc_data);
+}
+#endif
+
static void debug_strvalmap(const char *label, struct strvalmap *map,
unsigned int val)
{
int i;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
for (i = 0; map[i].str; i++) {
if (val & map[i].val)
SUPPLICANT_DBG("%s: %s", label, map[i].str);
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));
}
+static void set_bss_expiration_age(DBusMessageIter *iter, void *user_data)
+{
+ unsigned int bss_expiration_age = GPOINTER_TO_UINT(user_data);
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
+ &bss_expiration_age);
+}
+
+int g_supplicant_interface_set_bss_expiration_age(GSupplicantInterface *interface,
+ unsigned int bss_expiration_age)
+{
+ return supplicant_dbus_property_set(interface->path,
+ SUPPLICANT_INTERFACE ".Interface",
+ "BSSExpireAge", DBUS_TYPE_UINT32_AS_STRING,
+ set_bss_expiration_age, NULL,
+ GUINT_TO_POINTER(bss_expiration_age), NULL);
+}
+
struct set_apscan_data
{
unsigned int ap_scan;
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 (const unsigned char *)network->best_bss->bssid;
}
+dbus_bool_t g_supplicant_network_get_transition_mode(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return FALSE;
+
+ return network->owe_transition_mode;
+}
+
+
+const unsigned char *g_supplicant_network_get_transition_mode_bssid(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return NULL;
+
+ return (const unsigned char *)network->transition_mode_bssid;
+}
+
+const void *g_supplicant_network_get_transition_mode_ssid(GSupplicantNetwork *network,
+ unsigned int *transition_mode_ssid_len)
+{
+ if (!network) {
+ *transition_mode_ssid_len = 0;
+ return NULL;
+ }
+
+ *transition_mode_ssid_len = network->transition_mode_ssid_len;
+ return network->transition_mode_ssid;
+}
unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network)
{
return NULL;
if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
+#if defined TIZEN_EXT
+ network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_DPP ||
+#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 ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_DPP)
+ 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 vsie_list;
}
-static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
+static bool compare_bssid(unsigned char *bssid_a, unsigned char *bssid_b)
{
- struct g_supplicant_bss *bss = value;
- struct g_connman_bssids *bssids = NULL;
- char buff[18];
- GSList **list = (GSList **)user_data;
+ if (!memcmp(bssid_a, bssid_b, WIFI_BSSID_LEN_MAX))
+ return true;
- bssids = (struct g_connman_bssids *)g_try_malloc0(sizeof(struct g_connman_bssids));
+ return false;
+}
- if (bssids) {
- g_snprintf(buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
- bss->bssid[0], bss->bssid[1], bss->bssid[2], bss->bssid[3],
- bss->bssid[4], bss->bssid[5]);
+static gchar *convert_bssid_to_str(unsigned char *bssid)
+{
+ GString *bssid_str;
+ unsigned int i;
- memcpy(bssids->bssid, buff, 18);
- bssids->bssid[17] = '\0';
- bssids->strength = bss->signal;
- bssids->strength += 120;
+ bssid_str = g_string_sized_new(18);
+ if (!bssid_str)
+ return NULL;
- if (bssids->strength > 100)
- bssids->strength = 100;
+ for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) {
+ g_string_append_printf(bssid_str, "%02x", bssid[i]);
+ if (i < WIFI_BSSID_LEN_MAX - 1)
+ g_string_append(bssid_str, ":");
+ }
- bssids->frequency = bss->frequency;
- *list = g_slist_append(*list, bssids);
- } else
- SUPPLICANT_DBG("Failed to allocate memory");
+ return g_string_free(bssid_str, FALSE);
}
-void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
+static void count_assoc_reject(gpointer data, gpointer user_data)
{
- GSList *bssid_list = NULL;
-
- if (g_hash_table_size(network->bss_table) < 1)
- return NULL;
+ time_t assoc_reject_time = GPOINTER_TO_INT(data);
+ struct assoc_count_data *assoc_count = user_data;
- g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_list);
-
- return bssid_list;
+ if (assoc_reject_time > assoc_count->ref_time)
+ assoc_count->assoc_count++;
}
-#endif
-static void merge_network(GSupplicantNetwork *network)
+static uint16_t get_assoc_reject_cnt(GHashTable *assoc_reject_table, unsigned char *bssid)
{
- GString *str;
- const char *ssid, *mode, *key_mgmt;
-#if defined TIZEN_EXT
- const char *isHS20AP;
- const char *eap, *identity, *phase2;
-#endif
- unsigned int i, ssid_len;
- char *group;
+ gchar *bssid_str;
+ struct assoc_reject_data *assoc_data;
+ struct assoc_count_data assoc_count;
+ time_t curr_time;
+ struct tm* timeinfo;
- ssid = g_hash_table_lookup(network->config_table, "ssid");
- mode = g_hash_table_lookup(network->config_table, "mode");
- key_mgmt = g_hash_table_lookup(network->config_table, "key_mgmt");
-#if defined TIZEN_EXT
- isHS20AP = g_hash_table_lookup(network->config_table, "isHS20AP");
- 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");
-#endif
+ if (g_hash_table_size(assoc_reject_table) < 1)
+ return 0;
- SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
+ if (!bssid)
+ return 0;
- if (ssid)
- ssid_len = strlen(ssid);
- else
- ssid_len = 0;
+ if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX))
+ return 0;
- str = g_string_sized_new((ssid_len * 2) + 24);
- if (!str)
- return;
+ bssid_str = convert_bssid_to_str(bssid);
+ if (!bssid_str)
+ return 0;
- for (i = 0; i < ssid_len; i++)
-#if defined TIZEN_EXT
- {
- if (ssid[i] != '"')
-#endif
- g_string_append_printf(str, "%02x", ssid[i]);
-#if defined TIZEN_EXT
+ assoc_data = g_hash_table_lookup(assoc_reject_table, bssid_str);
+ if (!assoc_data) {
+ g_free(bssid_str);
+ return 0;
}
-#endif
- if (g_strcmp0(mode, "0") == 0)
- 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_slist_length(assoc_data->reject_time_list) < 1) {
+ g_free(bssid_str);
+ return 0;
+ }
- if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
- g_string_append_printf(str, "_psk");
-#if defined TIZEN_EXT
- else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
- g_string_append_printf(str, "_ieee8021x");
- else
- g_string_append_printf(str, "_none");
-#endif
+ /* Only events that occur within one hour are appened. */
+ curr_time = time(NULL);
+ timeinfo = localtime(&curr_time);
+ timeinfo->tm_hour -= 1;
- group = g_string_free(str, FALSE);
+ assoc_count.ref_time = mktime(timeinfo);
+ assoc_count.assoc_count = 0;
- SUPPLICANT_DBG("%s", group);
+ g_slist_foreach(assoc_data->reject_time_list, count_assoc_reject, &assoc_count);
-#if defined TIZEN_EXT
- if (g_strcmp0(isHS20AP, "1") == 0) {
- network->isHS20AP = 1;
- if (network->eap)
- g_free(network->eap);
- network->eap = g_strdup(eap);
+ g_free(bssid_str);
+ return assoc_count.assoc_count;
+}
- if (network->identity)
- g_free(network->identity);
- network->identity = g_strdup(identity);
+static int calculate_score_last_connected_bssid(bool is_last_connected)
+{
+ int score = 0;
- if (network->phase2)
- g_free(network->phase2);
- network->phase2 = g_strdup(phase2);
- } else
- network->isHS20AP = 0;
+ if (ins_settings.last_connected_bssid) {
+ if (is_last_connected)
+ score += ins_settings.last_connected_bssid_score;
+ }
- network->group = g_strdup(group);
- callback_network_merged(network);
- g_free(network->group);
-#endif
+ return score;
+}
- g_free(group);
+static int calculate_score_assoc_reject(uint16_t assoc_reject_cnt)
+{
+ int score = 0;
- g_hash_table_destroy(network->config_table);
+ if (ins_settings.assoc_reject)
+ score -= (assoc_reject_cnt * ins_settings.assoc_reject_score);
- g_free(network->path);
- g_free(network);
+ return score;
}
-static void network_property(const char *key, DBusMessageIter *iter,
- void *user_data)
+static int calculate_score_frequency(dbus_int16_t strength, dbus_uint16_t frequency)
+{
+ int score = 0;
+
+ switch (ins_settings.preferred_freq_bssid) {
+ case G_SUPPLICANT_INS_PREFERRED_FREQ_24GHZ:
+ if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
+ frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
+ (strength > ins_settings.signal_level3_24ghz))
+ score += ins_settings.preferred_freq_bssid_score;
+
+ break;
+ case G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ:
+ if ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
+ frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
+ (strength > ins_settings.signal_level3_5ghz))
+ score += ins_settings.preferred_freq_bssid_score;
+
+ break;
+ default:
+ break;
+ }
+
+ return score;
+}
+
+static int calculate_score_strength(dbus_int16_t strength)
+{
+ int score = 0;
+
+ if (ins_settings.signal_bssid)
+ score += (((strength > -60) ? -60 : strength) + 85);
+
+ return score;
+}
+
+static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
+ dbus_int16_t strength, dbus_uint16_t frequency)
+{
+ int score = 0;
+
+ score += calculate_score_last_connected_bssid(is_last_connected);
+ score += calculate_score_assoc_reject(assoc_reject_cnt);
+ score += calculate_score_frequency(strength, frequency);
+ score += calculate_score_strength(strength);
+
+ return score;
+}
+
+static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
+{
+ struct g_supplicant_bss *bss = value;
+ struct g_connman_bssids *bssids = NULL;
+ struct update_bssid_data *bssid_data = (struct update_bssid_data *)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;
+
+ bssids->assoc_reject_cnt = get_assoc_reject_cnt(bssid_data->assoc_reject_table, bssids->bssid);
+
+ bssids->is_last_connected = compare_bssid(bssids->bssid, bssid_data->last_connected_bssid);
+
+#if defined TIZEN_EXT_INS
+ bssids->score_last_connected_bssid = calculate_score_last_connected_bssid(bssids->is_last_connected);
+ bssids->score_assoc_reject = calculate_score_assoc_reject(bssids->assoc_reject_cnt);
+ bssids->score_frequency = calculate_score_frequency(bss->signal, bssids->frequency);
+ bssids->score_strength = calculate_score_strength(bssids->strength);
+#endif
+
+ bssids->ins_score = calculate_score(bssids->is_last_connected,
+ bssids->assoc_reject_cnt, bssids->frequency, bss->signal);
+
+ bssid_data->bssid_list = g_slist_append(bssid_data->bssid_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->ins_score > entry_b->ins_score)
+ return -1;
+
+ if (entry_a->ins_score < entry_b->ins_score)
+ return 1;
+
+ return 0;
+}
+
+#if defined TIZEN_EXT_INS
+static void print_bssid_sort(gpointer data, gpointer user_data)
+{
+ struct g_connman_bssids *bssids = data;
+
+ SUPPLICANT_DBG("bssid[" MACSTR "] total[%2d] freq[%2d] "
+ "last_conn[%2d] assoc_reject[%2d] strength[%2d]",
+ MAC2STR(bssids->bssid), bssids->ins_score,
+ bssids->score_frequency, bssids->score_last_connected_bssid,
+ bssids->score_assoc_reject, bssids->score_strength);
+}
+#endif
+
+void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
+{
+ struct update_bssid_data bssid_data;
+
+ if (g_hash_table_size(network->bss_table) < 1)
+ return NULL;
+
+ bssid_data.network = network;
+ memset(&bssid_data, 0, sizeof(bssid_data));
+ memcpy(bssid_data.last_connected_bssid, network->last_connected_bssid, WIFI_BSSID_LEN_MAX);
+ bssid_data.assoc_reject_table = network->assoc_reject_table;
+
+ g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_data);
+ bssid_data.bssid_list = g_slist_sort(bssid_data.bssid_list, cmp_bss);
+#if defined TIZEN_EXT_INS
+ g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, NULL);
+#endif
+
+ return bssid_data.bssid_list;
+}
+
+void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid)
+{
+ if (!bssid)
+ return;
+
+ if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX))
+ return;
+
+ memcpy(network->last_connected_bssid, bssid, WIFI_BSSID_LEN_MAX);
+
+ SUPPLICANT_DBG("last connected bssid [" MACSTR "]", MAC2STR(bssid));
+}
+
+const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return NULL;
+
+ return (const unsigned char *)network->last_connected_bssid;
+}
+
+void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface,
+ GSupplicantNetwork *network)
+{
+ struct assoc_reject_data *assoc_data;
+ gchar *bssid_str;
+ time_t curr_time;
+
+ if (!network)
+ return;
+
+ bssid_str = convert_bssid_to_str(interface->add_network_bssid);
+ if (!bssid_str)
+ return;
+
+ assoc_data = g_hash_table_lookup(network->assoc_reject_table, bssid_str);
+ if (!assoc_data) {
+ assoc_data = g_try_new0(struct assoc_reject_data, 1);
+ if (!assoc_data) {
+ g_free(bssid_str);
+ return;
+ }
+
+ assoc_data->bssid = g_strdup(bssid_str);
+ g_hash_table_insert(network->assoc_reject_table, assoc_data->bssid, assoc_data);
+ }
+
+ curr_time = time(NULL);
+ assoc_data->reject_time_list = g_slist_append(assoc_data->reject_time_list, GINT_TO_POINTER(curr_time));
+
+ SUPPLICANT_DBG("bssid [%s] time [%u]", bssid_str, curr_time);
+
+ g_free(bssid_str);
+
+ callback_network_changed(network, "UpdateAssocReject");
+}
+
+GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *network)
+{
+ if (!network)
+ return NULL;
+
+ return network->assoc_reject_table;
+}
+
+GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface,
+ const char *group)
+{
+ if (!interface)
+ return NULL;
+
+ return g_hash_table_lookup(interface->network_table, group);
+}
+#endif
+
+static void merge_network(GSupplicantNetwork *network)
+{
+ GString *str;
+ const char *ssid, *mode, *key_mgmt;
+#if defined TIZEN_EXT
+ const char *isHS20AP;
+ const char *eap, *identity, *phase2;
+#endif
+ unsigned int i, ssid_len;
+ char *group;
+
+ ssid = g_hash_table_lookup(network->config_table, "ssid");
+ mode = g_hash_table_lookup(network->config_table, "mode");
+ key_mgmt = g_hash_table_lookup(network->config_table, "key_mgmt");
+#if defined TIZEN_EXT
+ isHS20AP = g_hash_table_lookup(network->config_table, "isHS20AP");
+ 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");
+#endif
+
+ SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
+
+ if (ssid)
+ ssid_len = strlen(ssid);
+ else
+ ssid_len = 0;
+
+ str = g_string_sized_new((ssid_len * 2) + 24);
+ if (!str)
+ return;
+
+ for (i = 0; i < ssid_len; i++)
+#if defined TIZEN_EXT
+ {
+ if (ssid[i] != '"')
+#endif
+ g_string_append_printf(str, "%02x", ssid[i]);
+#if defined TIZEN_EXT
+ }
+#endif
+
+ if (g_strcmp0(mode, "0") == 0)
+ 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");
+#if defined TIZEN_EXT
+ else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
+ g_string_append_printf(str, "_ieee8021x");
+ else
+ g_string_append_printf(str, "_none");
+#endif
+
+ group = g_string_free(str, FALSE);
+
+ SUPPLICANT_DBG("%s", group);
+
+#if defined TIZEN_EXT
+ if (g_strcmp0(isHS20AP, "1") == 0) {
+ network->isHS20AP = 1;
+ if (network->eap)
+ g_free(network->eap);
+ network->eap = g_strdup(eap);
+
+ if (network->identity)
+ g_free(network->identity);
+ network->identity = g_strdup(identity);
+
+ if (network->phase2)
+ g_free(network->phase2);
+ network->phase2 = g_strdup(phase2);
+ } else
+ network->isHS20AP = 0;
+
+ network->group = g_strdup(group);
+ callback_network_merged(network);
+ g_free(network->group);
+#endif
+
+ g_free(group);
+
+ g_hash_table_destroy(network->config_table);
+
+ g_free(network->path);
+ g_free(network);
+}
+
+static void network_property(const char *key, DBusMessageIter *iter,
+ void *user_data)
{
GSupplicantNetwork *network = user_data;
static void interface_network_removed(DBusMessageIter *iter, void *user_data)
{
SUPPLICANT_DBG("");
- return;
}
static char *create_name(unsigned char *ssid, int ssid_len)
return g_string_free(str, FALSE);
}
+#if defined TIZEN_EXT
+static void update_network_with_best_bss(GSupplicantNetwork *network,
+ struct g_supplicant_bss *best_bss)
+{
+ network->signal = best_bss->signal;
+ network->frequency = best_bss->frequency;
+ network->best_bss = best_bss;
+}
+
+static bool update_best_bss(GSupplicantNetwork *network,
+ struct g_supplicant_bss *bss, struct g_supplicant_bss *best_bss)
+{
+ int score_new;
+ int score_best;
+
+ if (network->best_bss == NULL) {
+ update_network_with_best_bss(network, bss);
+ return true;
+ }
+
+ score_new = calculate_score(
+ compare_bssid(bss->bssid, network->last_connected_bssid),
+ get_assoc_reject_cnt(network->assoc_reject_table, bss->bssid),
+ bss->frequency, bss->signal);
+ score_best = calculate_score(
+ compare_bssid(network->best_bss->bssid, network->last_connected_bssid),
+ get_assoc_reject_cnt(network->assoc_reject_table, network->best_bss->bssid),
+ network->best_bss->frequency, network->best_bss->signal);
+
+ if (score_new > score_best) {
+ SUPPLICANT_DBG("new[" MACSTR "][%u] : best[" MACSTR "][%u]",
+ MAC2STR(bss->bssid), score_new,
+ MAC2STR(network->best_bss->bssid), score_best);
+
+ update_network_with_best_bss(network, bss);
+
+ SUPPLICANT_DBG("Update best BSS for %s", network->name);
+
+ return true;
+ }
+
+ return false;
+}
+#endif
static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
{
GSupplicantInterface *interface = bss->interface;
GSupplicantNetwork *network;
char *group;
+ bool is_new_network;
group = create_group(bss);
SUPPLICANT_DBG("New group created: %s", group);
if (network) {
g_free(group);
SUPPLICANT_DBG("Network %s already exist", network->name);
+ is_new_network = false;
goto done;
}
+ is_new_network = true;
+
network = g_try_new0(GSupplicantNetwork, 1);
if (!network) {
g_free(group);
network->frequency = bss->frequency;
network->best_bss = bss;
+ if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
+ network->wps = TRUE;
+ network->wps_capabilities = bss->wps_capabilities;
+ }
+
#if defined TIZEN_EXT
+ network->owe_transition_mode = bss->owe_transition_mode;
+ memcpy(network->transition_mode_ssid, bss->transition_mode_ssid, bss->transition_mode_ssid_len);
+ memcpy(network->transition_mode_bssid, bss->transition_mode_bssid, WIFI_BSSID_LEN_MAX);
+
network->keymgmt = bss->keymgmt;
if (g_slist_length(bss->vsie_list) > 0) {
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);
network->config_table = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
+#if defined TIZEN_EXT
+ network->assoc_reject_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, remove_assoc_data);
+#endif
+
g_hash_table_replace(interface->network_table,
network->group, network);
/* We update network's WPS properties if only bss provides WPS. */
if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
network->wps = TRUE;
- network->wps_capabilities |= bss->wps_capabilities;
+ network->wps_capabilities = bss->wps_capabilities;
+
+ if (!is_new_network)
+ callback_network_changed(network, "WPSCapabilities");
}
/*
* Do not change best BSS if we are connected. It will be done through
* CurrentBSS property in case of misalignment with wpa_s or roaming.
*/
+#if defined TIZEN_EXT
+ if (network != interface->current_network) {
+ if (update_best_bss(network, bss, network->best_bss))
+ callback_network_changed(network, "Signal");
+ }
+#else
if (network != interface->current_network &&
bss->signal > network->signal) {
network->signal = bss->signal;
network->best_bss = bss;
callback_network_changed(network, "Signal");
}
+#endif
g_hash_table_replace(interface->bss_mapping, bss->path, network);
g_hash_table_replace(network->bss_table, bss->path, bss);
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;
DBusMessageIter array;
unsigned int value;
int ie_len;
+#if defined TIZEN_EXT
+ const unsigned char OWE_WFA_OUI[] = { 0x50, 0x6f, 0x9a, 0x1c };
+ 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
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
- unsigned char *vsie;
- int vsie_len = 0;
+ for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
+ ie += ie[1] + 2) {
+#if defined TIZEN_EXT
+ unsigned char *vsie;
+ int vsie_len = 0;
+
+ if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, OWE_WFA_OUI, sizeof(OWE_WFA_OUI)) == 0) {
+ SUPPLICANT_DBG("IE: match vendor specific data : OWE Transition Mode");
+
+/*
+ Tag: Vendor Specific: Wi-Fi Alliance: OWE Transition Mode
+ Tag Number: Vendor Specific (221) -> ie[0]
+ Tag length: 26 -> ie[1]
+ OUI: 50:6f:9a (Wi-Fi Alliance) -> ie[2]
+ Vendor Specific OUI Type: 28 -> ie[5]
+ BSSID: 92:fd:f0:20:2b:09 -> ie[6]
+ SSID length: 15 -> ie[12]
+ SSID: Wi-Fi-5.2.3-owe -> ie[13]
+
+0000 dd 1a 50 6f 9a 1c 92 fd f0 20 2b 09 0f 57 69 2d ..Po..... +..Wi-
+0010 46 69 2d 35 2e 32 2e 33 2d 6f 77 65 Fi-5.2.3-owe
+
+*/
+ bss->owe_transition_mode = TRUE;
+ if (ie[1] >= 11) { // Tag length is at least up to ssid length position.
+ memcpy(bss->transition_mode_bssid, ie+6, WIFI_BSSID_LEN_MAX);
+ if (ie[12] > 0 && ie[12] < 32) {
+ memcpy(bss->transition_mode_ssid, ie+13, ie[12]);
+ bss->transition_mode_ssid_len = ie[12];
+ } else
+ bss->transition_mode_ssid_len = 0;
+ } else
+ bss->owe_transition_mode = FALSE;
+ continue;
+ }
+
if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
- SUPPLICANT_DBG("IE: match vendor specific data");
+
+ if (!simplified_log)
+ 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);
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 ||
memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0)
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_WIFI_MESH
+#if defined TIZEN_EXT
if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
bss->sae = TRUE;
+ if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_OWE)
+ bss->owe = TRUE;
+ if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_DPP)
+ bss->dpp = TRUE;
#endif
if (bss->ieee8021x)
bss->security = G_SUPPLICANT_SECURITY_FT_PSK;
else if (bss->ft_ieee8021x == TRUE)
bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
-#endif
-#if defined TIZEN_EXT_WIFI_MESH
else if (bss->sae)
bss->security = G_SUPPLICANT_SECURITY_SAE;
+ else if (bss->owe || bss->owe_transition_mode)
+ bss->security = G_SUPPLICANT_SECURITY_OWE;
+ else if (bss->dpp)
+ bss->security = G_SUPPLICANT_SECURITY_DPP;
#endif
else if (bss->privacy)
bss->security = G_SUPPLICANT_SECURITY_WEP;
if (!bss->interface)
return;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("key %s", key);
if (!key)
GSupplicantNetwork *network;
struct g_supplicant_bss *bss;
const char *path = NULL;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
dbus_message_iter_get_basic(iter, &path);
if (g_strcmp0(path, "/") == 0)
return NULL;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("%s", path);
network = g_hash_table_lookup(interface->bss_mapping, path);
void *user_data)
{
struct g_supplicant_bss *bss;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
bss = interface_bss_added(iter, user_data);
dbus_message_iter_next(iter);
if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_INVALID)
+#if defined TIZEN_EXT
+ {
+ g_free(bss->path);
+ g_free(bss);
return;
+ }
+#else
+ return;
+#endif
supplicant_dbus_property_foreach(iter, bss_property, bss);
void *user_data)
{
struct g_supplicant_bss *bss;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
bss = interface_bss_added(iter, user_data);
supplicant_dbus_property_get_all(bss->path,
SUPPLICANT_INTERFACE ".BSS",
- bss_property, bss, NULL);
+ bss_property, bss, bss);
bss_compute_security(bss);
if (add_or_replace_bss_to_network(bss) < 0)
struct g_supplicant_bss *bss = value;
GSupplicantNetwork *network = user_data;
+#if defined TIZEN_EXT
+ if (!network->best_bss || (network->best_bss == bss)) {
+ if (bss->signal > network->signal) {
+ network->signal = bss->signal;
+ network->best_bss = bss;
+ }
+ return;
+ }
+
+ update_best_bss(network, bss, network->best_bss);
+#else
if (bss->signal > network->signal) {
network->signal = bss->signal;
network->best_bss = bss;
}
+#endif
}
static void update_network_signal(GSupplicantNetwork *network)
SUPPLICANT_DBG("New network signal %d", network->signal);
}
+#if defined TIZEN_EXT
+static gboolean last_connected_timeout(gpointer data)
+{
+ GSupplicantInterface *interface = data;
+ GSupplicantNetwork *current_network = interface->current_network;
+
+ SUPPLICANT_DBG("Timeout last connected bss");
+
+ if (current_network && current_network->best_bss) {
+ if (compare_bssid(current_network->best_bss->bssid, interface->connected_bssid)) {
+ g_supplicant_network_set_last_connected_bssid(current_network, interface->connected_bssid);
+ callback_network_changed(current_network, "LastConnectedBSSID");
+ }
+ }
+
+ last_connected_bss_timeout = 0;
+ return FALSE;
+}
+
+static void add_timer_for_last_connected(GSupplicantInterface *interface)
+{
+ GSupplicantNetwork *current_network = interface->current_network;
+
+ if (interface->state == G_SUPPLICANT_STATE_COMPLETED) {
+ if (current_network) {
+ struct g_supplicant_bss *best_bss = current_network->best_bss;
+
+ memcpy(interface->connected_bssid, best_bss->bssid, WIFI_BSSID_LEN_MAX);
+
+ if (last_connected_bss_timeout)
+ g_source_remove(last_connected_bss_timeout);
+
+ last_connected_bss_timeout = g_timeout_add_seconds(LAST_CONNECTED_TIMEOUT,
+ last_connected_timeout, interface);
+
+ SUPPLICANT_DBG("Add timer for last connected bssid [" MACSTR "]",
+ MAC2STR(best_bss->bssid));
+ }
+ }
+}
+
+static void remove_timer_for_last_connected(GSupplicantInterface *interface)
+{
+ if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED) {
+ if (last_connected_bss_timeout != 0) {
+ g_source_remove(last_connected_bss_timeout);
+ last_connected_bss_timeout = 0;
+ SUPPLICANT_DBG("Remove timer for last connected bss");
+ }
+ }
+}
+#endif
+
static void interface_current_bss(GSupplicantInterface *interface,
DBusMessageIter *iter)
{
return;
interface->current_network = network;
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG("current network [%p]", interface->current_network);
+#endif
if (bss != network->best_bss) {
/*
case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
case G_SUPPLICANT_STATE_COMPLETED:
callback_network_associated(network);
+#if defined TIZEN_EXT
+ add_timer_for_last_connected(interface);
+#endif
break;
}
}
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)
return;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("key: %s", key);
if (g_strcmp0(key, "ConfigMethods") == 0) {
}
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+void g_supplicant_replace_config_file(const char *ifname, const char *config_file)
+{
+ if (!ifname)
+ return;
+
+ if (!config_file)
+ return;
+
+ SUPPLICANT_DBG("New {%s, %s}", ifname, config_file);
+ g_hash_table_replace(config_file_table,
+ g_strdup(ifname), g_strdup(config_file));
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
static void interface_property(const char *key, DBusMessageIter *iter,
void *user_data)
{
if (!interface)
return;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("%s", key);
if (!key) {
interface->state = string2state(str);
callback_interface_state(interface);
}
-
+#if defined TIZEN_EXT
+ switch (interface->state) {
+ case G_SUPPLICANT_STATE_COMPLETED:
+ add_timer_for_last_connected(interface);
+ break;
+ case G_SUPPLICANT_STATE_DISCONNECTED:
+ remove_timer_for_last_connected(interface);
+ break;
+ default:
+ break;
+ }
+#endif
if (interface->ap_create_in_progress) {
if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED)
callback_ap_create_fail(interface);
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
dbus_message_iter_get_basic(iter, &reason_code);
callback_disconnect_reason_code(interface, reason_code);
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG("reason code (%d)", reason_code);
+#endif
}
} else if (g_strcmp0(key, "AssocStatusCode") == 0) {
int status_code;
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
dbus_message_iter_get_basic(iter, &status_code);
callback_assoc_status_code(interface, status_code);
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG("status code (%d)", status_code);
+#endif
}
} else {
SUPPLICANT_DBG("key %s type %c",
/*Fixed : stucking in scanning state when scan failed*/
#if defined TIZEN_EXT
- GSupplicantInterfaceCallback scan_callback;
+ GSupplicantInterfaceCallback scan_callback;
+ SUPPLICANT_DBG("");
#endif
if (iter)
interface);
#if defined TIZEN_EXT
- scan_callback = interface->scan_callback;
+ scan_callback = interface->scan_callback;
+ callback_scan_done(interface);
#endif
if (interface->scan_callback)
interface->scan_callback(0, interface, interface->scan_data);
#if defined TIZEN_EXT
- if (interface->scan_callback == scan_callback) {
+ if (interface->scan_callback == scan_callback) {
#endif
interface->scan_callback = NULL;
interface->scan_data = NULL;
static void signal_interface_changed(const char *path, DBusMessageIter *iter)
{
GSupplicantInterface *interface;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
interface = g_hash_table_lookup(interface_table, path);
static void signal_bss_added(const char *path, DBusMessageIter *iter)
{
GSupplicantInterface *interface;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
interface = g_hash_table_lookup(interface_table, path);
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_sta_authorized(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ const char *addr = NULL;
+
+ SUPPLICANT_DBG("");
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ dbus_message_iter_get_basic(iter, &addr);
+ if (!addr)
+ return;
+
+ callback_sta_authorized(interface, addr);
+}
+
+static void signal_sta_deauthorized(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ const char *addr = NULL;
+
+ SUPPLICANT_DBG("");
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ dbus_message_iter_get_basic(iter, &addr);
+ if (!addr)
+ return;
+
+ callback_sta_deauthorized(interface, addr);
+}
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static void signal_eap(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ const char *str = NULL;
+
+ SUPPLICANT_DBG("EAPOL_DEBUG callback eap signal");
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ // TODO: Identify EAP fail condition, currently timeout is used for failure.
+
+ dbus_message_iter_get_basic(iter, &str);
+ if (!str)
+ return;
+
+ if (g_strcmp0("completion", str))
+ return;
+
+ dbus_message_iter_next(iter);
+
+ dbus_message_iter_get_basic(iter, &str);
+ if (!str)
+ return;
+
+ if (!g_strcmp0("success", str))
+ callback_eap(interface, true);
+ else
+ callback_eap(interface, false);
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
static void signal_bss_changed(const char *path, DBusMessageIter *iter)
{
GSupplicantInterface *interface;
GSupplicantNetwork *network;
GSupplicantSecurity old_security;
+ unsigned int old_wps_capabilities;
struct g_supplicant_bss *bss;
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
interface = g_hash_table_lookup(bss_mapping, path);
return;
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);
if (old_security != bss->security) {
struct g_supplicant_bss *new_bss;
- SUPPLICANT_DBG("New network security for %s", bss->ssid);
+ SUPPLICANT_DBG("New network security for %s with path %s",
+ bss->ssid, bss->path);
- /* Security change policy:
- * - we first copy the current bss into a new one with
- * its own pointer (path)
- * - we remove the current bss related network which will
- * tell the plugin about such removal. This is done due
- * to the fact that a security change means a group change
- * so a complete network change.
- * (current bss becomes invalid as well)
- * - we add the new bss: it adds new network and tell the
- * plugin about it. */
+ /*
+ * Security change policy:
+ * - We first copy the current bss into a new one with
+ * its own pointer (path)
+ * - Clear the old bss pointer and remove the network completely
+ * if there are no more BSSs in the bss table.
+ * - The new bss will be added either to an existing network
+ * or an additional network will be created
+ */
new_bss = g_try_new0(struct g_supplicant_bss, 1);
if (!new_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 = NULL;
+ 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);
+ if (network->best_bss == bss) {
+ network->best_bss = NULL;
+ network->signal = BSS_UNKNOWN_STRENGTH;
+ }
+
+ g_hash_table_remove(bss_mapping, path);
+
+ g_hash_table_remove(interface->bss_mapping, path);
+ g_hash_table_remove(network->bss_table, path);
+
+ update_network_signal(network);
+
+ if (g_hash_table_size(network->bss_table) == 0)
+ g_hash_table_remove(interface->network_table,
+ network->group);
if (add_or_replace_bss_to_network(new_bss) < 0) {
- /* Remove entries in hash tables to handle the
- * failure in add_or_replace_bss_to_network
+ /*
+ * Prevent a memory leak on failure in
+ * add_or_replace_bss_to_network
*/
- g_hash_table_remove(bss_mapping, path);
- g_hash_table_remove(interface->bss_mapping, path);
- g_hash_table_remove(network->bss_table, path);
+ SUPPLICANT_DBG("Failed to add bss %s to network table",
+ new_bss->path);
+ g_free(new_bss->path);
+ g_free(new_bss);
}
return;
}
+ old_wps_capabilities = network->wps_capabilities;
+
+ if (old_wps_capabilities != bss->wps_capabilities) {
+ network->wps_capabilities = bss->wps_capabilities;
+ callback_network_changed(network, "WPSCapabilities");
+ }
+
#if defined TIZEN_EXT
if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
network->wps = TRUE;
* If the new signal is lower than the SSID signal, we need
* to check for the new maximum.
*/
- if (bss->signal < network->signal) {
- if (bss != network->best_bss)
-#ifndef TIZEN_EXT
- return;
-#else
- {
+#if defined TIZEN_EXT
+ if (!update_best_bss(network, bss, network->best_bss)) {
+ if (bss != network->best_bss) {
callback_network_changed(network, "");
return;
}
-#endif
+
+ network->signal = bss->signal;
+ update_network_signal(network);
+ }
+#else
+ if (bss->signal < network->signal) {
+ if (bss != network->best_bss)
+ return;
+
network->signal = bss->signal;
update_network_signal(network);
} else {
network->signal = bss->signal;
network->best_bss = bss;
}
+#endif
SUPPLICANT_DBG("New network signal for %s %d dBm", network->ssid,
network->signal);
if (g_strcmp0(name, "success") == 0)
interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
- else if (g_strcmp0(name, "failed") == 0)
+ else if (g_strcmp0(name, "fail") == 0)
interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
else
interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
#if defined TIZEN_EXT
static void signal_power_off(const char *path, DBusMessageIter *iter)
{
- int poweroff_state = 0;
-
- dbus_message_iter_get_basic(iter, &poweroff_state);
-
- SUPPLICANT_DBG("poweroff_state(%d)", poweroff_state);
-
- /* POWER_OFF_DIRECT 2 && POWER_OFF_RESTART 3 */
- if (poweroff_state != 2 && poweroff_state != 3)
- return;
-
- if (callbacks_pointer == NULL)
- return;
-
- if (callbacks_pointer->system_power_off == NULL)
- return;
-
- callbacks_pointer->system_power_off();
-}
-#endif
-
-static void signal_station_connected(const char *path, DBusMessageIter *iter)
-{
- GSupplicantInterface *interface;
- const char *sta_mac = NULL;
-
- SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
-
- if (callbacks_pointer->add_station == NULL)
- return;
-
- if (g_strcmp0(path, "/") == 0)
- return;
-
- interface = g_hash_table_lookup(interface_table, path);
- if (interface == NULL)
- return;
-
- dbus_message_iter_get_basic(iter, &sta_mac);
- if (sta_mac == NULL)
- return;
-
- SUPPLICANT_DBG("New station %s connected", sta_mac);
- callbacks_pointer->add_station(sta_mac);
-}
-
-static void signal_station_disconnected(const char *path, DBusMessageIter *iter)
-{
- GSupplicantInterface *interface;
- const char *sta_mac = NULL;
+ int poweroff_state = 0;
- SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
+ dbus_message_iter_get_basic(iter, &poweroff_state);
- if (callbacks_pointer->remove_station == NULL)
- return;
+ SUPPLICANT_DBG("poweroff_state(%d)", poweroff_state);
- if (g_strcmp0(path, "/") == 0)
+ /* POWER_OFF_DIRECT 2 && POWER_OFF_RESTART 3 */
+ if (poweroff_state != 2 && poweroff_state != 3)
return;
- interface = g_hash_table_lookup(interface_table, path);
- if (interface == NULL)
+ if (callbacks_pointer == NULL)
return;
- dbus_message_iter_get_basic(iter, &sta_mac);
- if (sta_mac == NULL)
+ if (callbacks_pointer->system_power_off == NULL)
return;
- SUPPLICANT_DBG("Station %s disconnected", sta_mac);
- callbacks_pointer->remove_station(sta_mac);
+ callbacks_pointer->system_power_off();
}
+#endif
static void create_peer_identifier(GSupplicantPeer *peer)
{
{ SUPPLICANT_INTERFACE ".Interface", "BSSRemoved", signal_bss_removed },
{ SUPPLICANT_INTERFACE ".Interface", "NetworkAdded", signal_network_added },
{ SUPPLICANT_INTERFACE ".Interface", "NetworkRemoved", signal_network_removed },
+ { SUPPLICANT_INTERFACE ".Interface", "StaAuthorized", signal_sta_authorized },
+ { SUPPLICANT_INTERFACE ".Interface", "StaDeauthorized", signal_sta_deauthorized },
{ SUPPLICANT_INTERFACE ".BSS", "PropertiesChanged", signal_bss_changed },
{ "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 },
signal_mesh_peer_disconnected },
#endif
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ { SUPPLICANT_INTERFACE ".Interface", "EAP", signal_eap },
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
{ }
};
regdom->callback(result, regdom->alpha2,
(void *) regdom->user_data);
- g_free(regdom);
+ dbus_free(regdom);
}
static void country_params(DBusMessageIter *iter, void *user_data)
SUPPLICANT_DBG("");
if (error) {
- g_warning("error %s", error);
+ g_message("error %s", error);
err = -EIO;
goto done;
}
DBUS_TYPE_STRING, &config_file);
}
+#ifdef TIZEN_EXT
+ if (!g_strcmp0(data->driver, "wifi")) {
+ supplicant_dbus_dict_append_basic(&dict, "MacAddr",
+ DBUS_TYPE_UINT32, &data->mac_addr);
+
+ supplicant_dbus_dict_append_basic(&dict, "PreassocMacAddr",
+ DBUS_TYPE_UINT32, &data->preassoc_mac_addr);
+
+ supplicant_dbus_dict_append_basic(&dict, "RandAddrLifetime",
+ DBUS_TYPE_UINT32, &data->random_mac_lifetime);
+ }
+#endif /* TIZEN_EXT */
+
#if defined TIZEN_EXT_WIFI_MESH
if (data->is_mesh_interface) {
if (data->parent_ifname)
supplicant_dbus_dict_close(iter, &dict);
}
+#if defined TIZEN_EXT
+static void interface_get_state(const char *key, DBusMessageIter *iter,
+ void *user_data)
+{
+ struct interface_create_data *data = user_data;
+ GSupplicantInterface *interface = NULL;
+ const char *str = NULL;
+
+ SUPPLICANT_DBG("key[%s]", key);
+
+ if (!data) {
+ SUPPLICANT_DBG("data is NULL");
+ return;
+ }
+
+ interface = data->interface;
+ if (!interface) {
+ SUPPLICANT_DBG("interface is NULL");
+ return;
+ }
+
+ if (iter)
+ dbus_message_iter_get_basic(iter, &str);
+
+ if (str) {
+ if (string2state(str) != interface->state)
+ interface->state = string2state(str);
+ }
+
+ if (interface->state == G_SUPPLICANT_STATE_DISABLED)
+ interface->ready = FALSE;
+ else
+ interface->ready = TRUE;
+
+ SUPPLICANT_DBG("state %s (%d)", str, interface->state);
+
+ if (data->callback) {
+ data->callback(0, interface, data->user_data);
+#if defined TIZEN_EXT_WIFI_MESH
+ callback_mesh_support(interface);
+#endif
+ }
+
+ interface_create_data_free(data);
+}
+#endif
+
static void interface_get_result(const char *error,
DBusMessageIter *iter, void *user_data)
{
const char *path = NULL;
int err;
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
if (error) {
goto done;
}
+#if defined TIZEN_EXT
+ data->interface = interface;
+ err = supplicant_dbus_property_get(path,
+ SUPPLICANT_INTERFACE ".Interface",
+ "State", interface_get_state, data, NULL);
+
+ if (err == 0)
+ return;
+#endif
+
if (data->callback) {
data->callback(0, interface, data->user_data);
#if !defined TIZEN_EXT
static void interface_get_params(DBusMessageIter *iter, void *user_data)
{
struct interface_create_data *data = user_data;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
SUPPLICANT_DBG("");
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &data->ifname);
};
static void interface_mesh_change_peer_params(DBusMessageIter *iter,
- void *user_data)
+ void *user_data)
{
struct interface_mesh_peer_data *data = user_data;
&data->interface->path);
}
-
int g_supplicant_interface_remove(GSupplicantInterface *interface,
GSupplicantInterfaceCallback callback,
void *user_data)
DBUS_TYPE_STRING, &type);
#if defined TIZEN_EXT
- SUPPLICANT_DBG("[specific_scan] num_ssids %d", data->scan_params->num_ssids);
- if (data->scan_params->num_ssids != 0)
+ SUPPLICANT_DBG("[specific_scan] num_ssids %d",
+ data->scan_params->num_ssids);
#endif
- supplicant_dbus_dict_append_array(&dict, "SSIDs",
- DBUS_TYPE_STRING,
- append_ssids,
- data->scan_params);
+ if (data->scan_params->ssids) {
+ supplicant_dbus_dict_append_array(&dict, "SSIDs",
+ DBUS_TYPE_STRING,
+ append_ssids,
+ data->scan_params);
+ }
supplicant_add_scan_frequency(&dict, add_scan_frequencies,
data->scan_params);
} else
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;
+ dbus_int32_t strength = 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;
+ } else if (g_strcmp0(key, "rssi") == 0) {
+ dbus_message_iter_get_basic(&value, &strength);
+ SUPPLICANT_DBG("Strength = %d", strength);
+ break;
+ }
+ }
+ dbus_message_iter_next(&dict);
+ }
+
+out:
+ if(data->callback)
+ data->callback(err, maxspeed, strength, 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 defined TIZEN_EXT
g_free(data->ssid->ssid);
g_free((char *)data->ssid->passphrase);
+ g_free((char *)data->ssid->connector);
+ g_free((char *)data->ssid->c_sign_key);
+ g_free((char *)data->ssid->net_access_key);
#endif
g_free(data->ssid);
dbus_free(data);
#if defined TIZEN_EXT
g_free(data->ssid->ssid);
g_free((char *)data->ssid->passphrase);
+ g_free((char *)data->ssid->connector);
+ g_free((char *)data->ssid->c_sign_key);
+ g_free((char *)data->ssid->net_access_key);
#endif
g_free(data->ssid);
g_free(data);
}
- if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) {
+ if(g_strcmp0(ssid->phase2_auth, "GTC") == 0 && g_strcmp0(ssid->eap, "ttls") == 0)
+ phase2_auth = g_strdup_printf("autheap=%s", ssid->phase2_auth);
+ else if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) {
phase2_auth = g_strdup_printf("autheap=%s",
ssid->phase2_auth + strlen("EAP-"));
} else
g_free(proto);
}
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid)
{
- if (ssid->security != G_SUPPLICANT_SECURITY_SAE)
+ if (ssid->security != G_SUPPLICANT_SECURITY_SAE
+ && ssid->security != G_SUPPLICANT_SECURITY_OWE
+ && ssid->security != G_SUPPLICANT_SECURITY_DPP)
return;
supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
&ssid->ieee80211w);
}
+
+static void add_network_security_connector(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+ if (ssid->connector && strlen(ssid->connector) > 0) {
+ const char *key = "dpp_connector";
+
+ supplicant_dbus_dict_append_basic(dict,
+ key, DBUS_TYPE_STRING,
+ &ssid->connector);
+ }
+}
+
+static size_t convert_hexstr_to_bin(const char *hex_str, unsigned char **bin)
+{
+ unsigned char *bin_res = NULL;
+ unsigned int i, j, hex;
+ size_t hex_str_len;
+
+ if (!hex_str || strlen(hex_str) == 0)
+ return 0;
+
+ hex_str_len = strlen(hex_str);
+ bin_res = g_try_malloc0(hex_str_len / 2);
+ if (!bin_res)
+ return 0;
+
+ j = 0;
+ for (i = 0; i < hex_str_len; i+=2) {
+ sscanf(hex_str + i, "%02x", &hex);
+ bin_res[j++] = hex;
+ }
+
+ *bin = bin_res;
+ return hex_str_len / 2;
+}
+
+static void add_network_security_c_sign_key(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+ if (ssid->c_sign_key && strlen(ssid->c_sign_key) > 0) {
+ const char *key = "dpp_csign";
+ unsigned char *bin_csign = NULL;
+ size_t bin_csign_len = convert_hexstr_to_bin(ssid->c_sign_key, &bin_csign);
+ if (bin_csign_len != 0)
+ supplicant_dbus_dict_append_fixed_array(dict,
+ key, DBUS_TYPE_BYTE,
+ &bin_csign, bin_csign_len);
+ g_free(bin_csign);
+ }
+}
+
+static void add_network_security_net_access_key(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+ if (ssid->net_access_key && strlen(ssid->net_access_key) > 0) {
+ const char *key = "dpp_netaccesskey";
+ unsigned char *bin_netaccesskey = NULL;
+ size_t bin_netaccesskey_len = convert_hexstr_to_bin(ssid->net_access_key, &bin_netaccesskey);
+ if (bin_netaccesskey_len != 0)
+ supplicant_dbus_dict_append_fixed_array(dict,
+ key, DBUS_TYPE_BYTE,
+ &bin_netaccesskey, bin_netaccesskey_len);
+ g_free(bin_netaccesskey);
+ }
+}
+
#endif
static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
add_network_security_ciphers(dict, ssid);
add_network_security_proto(dict, ssid);
break;
-#endif
-#if defined TIZEN_EXT_WIFI_MESH
case G_SUPPLICANT_SECURITY_SAE:
- key_mgmt = "SAE";
+ if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
+ key_mgmt = "SAE WPA-PSK"; // WFA (WPA3 & WPA2 Mixed -> WPA2 only)
+ else
+ key_mgmt = "SAE";
add_network_security_psk(dict, ssid);
break;
+ case G_SUPPLICANT_SECURITY_OWE:
+ key_mgmt = "OWE";
+ add_network_security_ciphers(dict, ssid);
+ add_network_security_proto(dict, ssid);
+ break;
+ case G_SUPPLICANT_SECURITY_DPP:
+ key_mgmt = "DPP";
+ add_network_security_connector(dict, ssid);
+ add_network_security_c_sign_key(dict, ssid);
+ add_network_security_net_access_key(dict, ssid);
+ break;
#endif
}
DBusMessageIter dict;
struct interface_connect_data *data = user_data;
GSupplicantSSID *ssid = data->ssid;
+#if defined TIZEN_EXT
+ GSupplicantInterface *interface = data->interface;
+#endif
supplicant_dbus_dict_open(iter, &dict);
add_network_security(&dict, ssid);
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
add_network_ieee80211w(&dict, ssid);
#endif
DBUS_TYPE_BYTE, &ssid->ssid,
ssid->ssid_len);
- supplicant_dbus_dict_append_basic(&dict, "ignore_broadcast_ssid",
- DBUS_TYPE_INT32,
- &ssid->ignore_broadcast_ssid);
-
#if defined TIZEN_EXT
- if (ssid->bssid) {
+ bool owe_transition_mode = FALSE;
+ if ((ssid->security == G_SUPPLICANT_SECURITY_OWE) && !(ssid->keymgmt & G_SUPPLICANT_KEYMGMT_OWE))
+ owe_transition_mode = TRUE;
+
+ if (ssid->bssid && !owe_transition_mode) {
char *bssid = NULL;
bssid = g_try_malloc0(18);
if (bssid == NULL) {
return;
}
- 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]);
+ if (ssid->bssid_for_connect_len) {
+ snprintf(bssid, 18, MACSTR, MAC2STR(ssid->bssid_for_connect));
+ memcpy(interface->add_network_bssid, ssid->bssid_for_connect, WIFI_BSSID_LEN_MAX);
+ } else {
+ snprintf(bssid, 18, MACSTR, MAC2STR(ssid->bssid));
+ memcpy(interface->add_network_bssid, ssid->bssid, WIFI_BSSID_LEN_MAX);
+ }
+
+ SUPPLICANT_DBG("bssid [" MACSTR "]", MAC2STR(interface->add_network_bssid));
supplicant_dbus_dict_append_basic(&dict, "bssid",
DBUS_TYPE_STRING, &bssid);
dbus_free(data);
return;
}
+
#if defined TIZEN_EXT
GSupplicantSSID *ssid = data->ssid;
if (ssid->pin_wps != NULL) {
interface_wps_start_result, data, NULL);
}
-static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
+static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
+{
+ dbus_bool_t credentials = TRUE;
+
+ SUPPLICANT_DBG("");
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
+}
+
+
+#if defined TIZEN_EXT
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
+#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
+
+struct dec_method_call_data {
+ struct interface_connect_data *data;
+ DBusPendingCall *pending_call;
+};
+
+static struct dec_method_call_data decrypt_request_data;
+
+static void crypt_method_call_cancel(void)
+{
+ if (decrypt_request_data.pending_call) {
+ dbus_pending_call_cancel(decrypt_request_data.pending_call);
+ dbus_pending_call_unref(decrypt_request_data.pending_call);
+ decrypt_request_data.pending_call = NULL;
+ }
+
+ g_free(decrypt_request_data.data->path);
+ g_free(decrypt_request_data.data->ssid);
+ dbus_free(decrypt_request_data.data);
+ decrypt_request_data.data = NULL;
+}
+
+static void decryption_request_reply(DBusPendingCall *call,
+ void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args;
+ char *out_data;
+ int ret;
+ struct interface_connect_data *data = user_data;
+
+ SUPPLICANT_DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+ if (dbus_set_error_from_message(&error, reply)) {
+ SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
+ dbus_error_free(&error);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (dbus_message_iter_init(reply, &args) == FALSE) {
+ SUPPLICANT_DBG("dbus_message_iter_init() failed");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ dbus_message_iter_get_basic(&args, &out_data);
+ data->ssid->passphrase = g_strdup((const gchar *)out_data);
+
+ ret = supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, data,
+ data->interface);
+
+done:
+ if (ret < 0) {
+ 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((char *)data->ssid->connector);
+ g_free((char *)data->ssid->c_sign_key);
+ g_free((char *)data->ssid->net_access_key);
+ g_free(data->ssid);
+ dbus_free(data);
+ }
+
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+
+ decrypt_request_data.pending_call = NULL;
+ decrypt_request_data.data = NULL;
+}
+
+static int send_decryption_request(const char *passphrase,
+ struct interface_connect_data *data)
{
- dbus_bool_t credentials = TRUE;
+ DBusMessage *msg = NULL;
+ DBusPendingCall *call;
- SUPPLICANT_DBG("");
+ SUPPLICANT_DBG("Decryption request");
- dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
-}
+ if (!passphrase) {
+ SUPPLICANT_DBG("Invalid parameter");
+ return -EINVAL;
+ }
+ if (!connection)
+ return -EINVAL;
-#if defined TIZEN_EXT
-#define NETCONFIG_SERVICE "net.netconfig"
-#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
-#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
+ msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
+ NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase");
+ if (!msg)
+ return -EINVAL;
-struct dec_method_call_data {
- struct interface_connect_data *data;
- DBusPendingCall *pending_call;
-};
+#if defined TIZEN_EXT
+ if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+ DBUS_TYPE_INVALID)) {
+ SUPPLICANT_DBG("Could not fulfill decryption request");
+ return -ENOMEM;
+ }
+#else
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+ DBUS_TYPE_INVALID);
+#endif
-static struct dec_method_call_data decrypt_request_data;
+ if (!dbus_connection_send_with_reply(connection, msg,
+ &call, DBUS_TIMEOUT_USE_DEFAULT)) {
+ dbus_message_unref(msg);
+ return -EIO;
+ }
-static void crypt_method_call_cancel(void)
-{
- if (decrypt_request_data.pending_call) {
- dbus_pending_call_cancel(decrypt_request_data.pending_call);
- dbus_pending_call_unref(decrypt_request_data.pending_call);
- decrypt_request_data.pending_call = NULL;
+ if (!call) {
+ dbus_message_unref(msg);
+ return -EIO;
}
- g_free(decrypt_request_data.data->path);
- g_free(decrypt_request_data.data->ssid);
- dbus_free(decrypt_request_data.data);
- decrypt_request_data.data = NULL;
+ decrypt_request_data.pending_call = call;
+ decrypt_request_data.data = data;
+
+ dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL);
+ dbus_message_unref(msg);
+
+ SUPPLICANT_DBG("Decryption request succeeded");
+
+ return 0;
}
-static void decryption_request_reply(DBusPendingCall *call,
+static void decrypt_conf_obj_reply(DBusPendingCall *call,
void *user_data)
{
DBusMessage *reply;
DBusError error;
- DBusMessageIter args;
+ DBusMessageIter iter, dict;
char *out_data;
int ret;
struct interface_connect_data *data = user_data;
- SUPPLICANT_DBG("");
-
reply = dbus_pending_call_steal_reply(call);
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, reply)) {
- SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
+ SUPPLICANT_DBG("decryption_conf_obj_reply() %s %s", error.name, error.message);
dbus_error_free(&error);
ret = -EINVAL;
goto done;
}
- if (dbus_message_iter_init(reply, &args) == FALSE) {
+ if (dbus_message_iter_init(reply, &iter) == FALSE) {
SUPPLICANT_DBG("dbus_message_iter_init() failed");
ret = -EINVAL;
goto done;
}
- dbus_message_iter_get_basic(&args, &out_data);
- data->ssid->passphrase = g_strdup((const gchar *)out_data);
+ dbus_message_iter_recurse(&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);
+ if (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) {
+ if (g_strcmp0(key, "connector") == 0) {
+ dbus_message_iter_get_basic(&value, &out_data);
+ data->ssid->connector = g_strdup((const gchar *)out_data);
+ SUPPLICANT_DBG("connector %s", data->ssid->connector);
+ } else if (g_strcmp0(key, "c_sign_key") == 0) {
+ dbus_message_iter_get_basic(&value, &out_data);
+ data->ssid->c_sign_key = g_strdup((const gchar *)out_data);
+ SUPPLICANT_DBG("c_sign_key %s", data->ssid->c_sign_key);
+ } else if (g_strcmp0(key, "net_access_key") == 0) {
+ dbus_message_iter_get_basic(&value, &out_data);
+ data->ssid->net_access_key = g_strdup((const gchar *)out_data);
+ SUPPLICANT_DBG("net_access_key %s", data->ssid->net_access_key);
+ }
+ }
+ dbus_message_iter_next(&dict);
+ }
ret = supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
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((char *)data->ssid->connector);
+ g_free((char *)data->ssid->c_sign_key);
+ g_free((char *)data->ssid->net_access_key);
g_free(data->ssid);
dbus_free(data);
}
decrypt_request_data.data = NULL;
}
-static int send_decryption_request(const char *passphrase,
+static int send_decryption_conf_obj_request(GSupplicantSSID *ssid,
struct interface_connect_data *data)
{
DBusMessage *msg = NULL;
DBusPendingCall *call;
- SUPPLICANT_DBG("Decryption request");
+ SUPPLICANT_DBG("Decryption configuration object request");
- if (!passphrase) {
+ if (!ssid) {
SUPPLICANT_DBG("Invalid parameter");
return -EINVAL;
}
return -EINVAL;
msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
- NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase");
+ NETCONFIG_WIFI_INTERFACE, "DecryptConfObj");
if (!msg)
return -EINVAL;
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->connector,
+ DBUS_TYPE_INVALID);
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->c_sign_key,
+ DBUS_TYPE_INVALID);
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->net_access_key,
DBUS_TYPE_INVALID);
if (!dbus_connection_send_with_reply(connection, msg,
decrypt_request_data.pending_call = call;
decrypt_request_data.data = data;
- dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL);
+ dbus_pending_call_set_notify(call, decrypt_conf_obj_reply, data, NULL);
dbus_message_unref(msg);
- SUPPLICANT_DBG("Decryption request succeeded");
+ SUPPLICANT_DBG("Decrypt Conf Obj request succeeded");
return 0;
}
+
+static bool is_valid_config_object(GSupplicantSSID *ssid)
+{
+ return ((ssid->connector &&
+ g_strcmp0(ssid->connector, "") != 0) &&
+ (ssid->c_sign_key &&
+ g_strcmp0(ssid->c_sign_key, "") != 0) &&
+ (ssid->net_access_key &&
+ g_strcmp0(ssid->net_access_key, "") != 0));
+}
#endif
int g_supplicant_interface_connect(GSupplicantInterface *interface,
intf_data->user_data = user_data;
intf_data->network_remove_in_progress = TRUE;
network_remove(intf_data);
- } else
+ } else {
#if defined TIZEN_EXT
if (ssid->passphrase &&
g_strcmp0(ssid->passphrase, "") != 0 &&
ret = send_decryption_request(ssid->passphrase, data);
if (ret < 0)
SUPPLICANT_DBG("Decryption request failed %d", ret);
+ } else if (is_valid_config_object(ssid)) {
+ ret = send_decryption_conf_obj_request(ssid, data);
+ if (ret < 0)
+ SUPPLICANT_DBG("Decryption Conf Obj request failed %d", ret);
+
} else
#endif
- ret = supplicant_dbus_method_call(interface->path,
- SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
- interface_add_network_params,
- interface_add_network_result, data,
- interface);
- }
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, data,
+ interface);
+ }
+ }
if (ret < 0) {
g_free(data->path);
g_free(connect_data->path);
dbus_free(connect_data);
}
+ } else if (is_valid_config_object(data->ssid)) {
+ ret = send_decryption_conf_obj_request(data->ssid, connect_data);
+ if (ret < 0) {
+ SUPPLICANT_DBG("Decryption Conf Obj 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,
return -EINPROGRESS;
}
+
static const char *g_supplicant_rule0 = "type=signal,"
"path=" DBUS_PATH_DBUS ","
"sender=" DBUS_SERVICE_DBUS ","
dbus_message_unref(message);
}
+#if defined TIZEN_EXT
+void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bssid,
+ bool last_connected_bssid, bool assoc_reject, bool signal_bssid,
+ unsigned int preferred_freq_bssid_score, unsigned int last_connected_bssid_score,
+ unsigned int assoc_reject_score, int signal_level3_5ghz, int signal_level3_24ghz)
+{
+ ins_settings.preferred_freq_bssid = preferred_freq_bssid;
+ ins_settings.last_connected_bssid = last_connected_bssid;
+ ins_settings.assoc_reject = assoc_reject;
+ ins_settings.signal_bssid = signal_bssid;
+ ins_settings.preferred_freq_bssid_score = preferred_freq_bssid_score;
+ ins_settings.last_connected_bssid_score = last_connected_bssid_score;
+ ins_settings.assoc_reject_score = assoc_reject_score;
+ ins_settings.signal_level3_5ghz = signal_level3_5ghz;
+ ins_settings.signal_level3_24ghz = signal_level3_24ghz;
+
+ SUPPLICANT_DBG("preferred_freq_bssid [%s]", preferred_freq_bssid ? "true" : "false");
+ SUPPLICANT_DBG("preferred_freq_bssid_score [%d]", preferred_freq_bssid_score);
+ SUPPLICANT_DBG("last_connected_bssid [%s]", last_connected_bssid ? "true" : "false");
+ SUPPLICANT_DBG("last_connected_bssid_score [%d]", last_connected_bssid_score);
+ SUPPLICANT_DBG("assoc_reject [%s]", assoc_reject ? "true" : "false");
+ SUPPLICANT_DBG("assoc_reject_score [%d]", assoc_reject_score);
+ SUPPLICANT_DBG("signal_bssid [%s]", signal_bssid ? "true" : "false");
+ SUPPLICANT_DBG("signal_level3_5ghz [%d]", signal_level3_5ghz);
+ SUPPLICANT_DBG("signal_level3_24ghz [%d]", signal_level3_24ghz);
+}
+#endif
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+void g_supplicant_register_eap_callback(g_supplicant_eap_callback cb)
+{
+ SUPPLICANT_DBG("g_supplicant_register_eap_callback %p", cb);
+
+ if (!callbacks_pointer) {
+ SUPPLICANT_DBG("callbacks_pointer is NULL");
+ return;
+ }
+
+ callbacks_pointer->eap = cb;
+}
+
+void g_supplicant_unregister_eap_callback(void)
+{
+ SUPPLICANT_DBG("g_supplicant_unregister_eap_callback");
+
+ if (!callbacks_pointer) {
+ SUPPLICANT_DBG("callbacks_pointer is NULL");
+ return;
+ }
+
+ callbacks_pointer->eap = NULL;
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+int g_supplicant_register(GSupplicantCallbacks *callbacks)
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
int g_supplicant_register(const GSupplicantCallbacks *callbacks)
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
{
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
if (!connection)
connection = NULL;
return -EIO;
}
-
+#if defined TIZEN_EXT
+ simplified_log = connman_setting_get_bool("SimplifiedLog");
+#endif
callbacks_pointer = callbacks;
eap_methods = 0;
} else
invoke_introspect_method();
+ SUPPLICANT_DBG("supplicant dbus setup completed");
return 0;
}
callbacks_pointer = NULL;
eap_methods = 0;
}
+
+#ifdef TIZEN_EXT
+struct supplicant_mac_policy {
+ GSupplicantMacPolicyCallback callback;
+ dbus_uint32_t policy;
+ const void *user_data;
+};
+
+static void mac_policy_result(const char *error,
+ DBusMessageIter *iter, void *user_data)
+{
+ struct supplicant_mac_policy *data = user_data;
+ int result = 0;
+
+ if (!user_data)
+ return;
+
+ if (error) {
+ SUPPLICANT_DBG("Mac policy setting failure %s", error);
+ result = -EINVAL;
+ }
+
+ if (data->callback)
+ data->callback(result, data->policy,
+ (void *) data->user_data);
+
+ dbus_free(data);
+}
+
+static void mac_policy_params(DBusMessageIter *iter, void *user_data)
+{
+ struct supplicant_mac_policy *data = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(data->policy));
+}
+
+int g_supplicant_interface_set_mac_policy(GSupplicantInterface *interface,
+ GSupplicantMacPolicyCallback callback,
+ unsigned int policy,
+ void *user_data)
+{
+ struct supplicant_mac_policy *data = NULL;
+ int ret;
+
+ if (!system_available)
+ return -EFAULT;
+
+ if (!interface)
+ return -EINVAL;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->callback = callback;
+ data->policy = policy;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_property_set(interface->path,
+ SUPPLICANT_INTERFACE ".Interface",
+ "MacAddr", DBUS_TYPE_INT32_AS_STRING,
+ mac_policy_params, mac_policy_result, data, NULL);
+ if (ret < 0) {
+ SUPPLICANT_DBG("Unable to set MacAddr configuration");
+ dbus_free(data);
+ }
+
+ return ret;
+}
+
+int g_supplicant_interface_set_preassoc_mac_policy(GSupplicantInterface *interface,
+ GSupplicantMacPolicyCallback callback,
+ unsigned int policy,
+ void *user_data)
+{
+ struct supplicant_mac_policy *data;
+ int ret;
+
+ if (!system_available)
+ return -EFAULT;
+
+ if (!interface)
+ return -EINVAL;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->callback = callback;
+ data->policy = policy;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_property_set(interface->path,
+ SUPPLICANT_INTERFACE ".Interface",
+ "PreassocMacAddr", DBUS_TYPE_INT32_AS_STRING,
+ mac_policy_params, mac_policy_result, data, NULL);
+ if (ret < 0) {
+ SUPPLICANT_DBG("Unable to set PreassocMacAddr configuration");
+ dbus_free(data);
+ }
+
+ return ret;
+}
+
+struct supplicant_random_mac_lifetime {
+ GSupplicantRandomMaclifetimeCallback callback;
+ dbus_uint32_t lifetime;
+ const void *user_data;
+};
+
+static void random_mac_lifetime_result(const char *error,
+ DBusMessageIter *iter, void *user_data)
+{
+ struct supplicant_random_mac_lifetime *data = user_data;
+ int result = 0;
+
+ if (!user_data)
+ return;
+
+ if (error) {
+ SUPPLICANT_DBG("Random Mac lifetime setting failure %s", error);
+ result = -EINVAL;
+ }
+
+ if (data->callback)
+ data->callback(result, data->lifetime,
+ (void *) data->user_data);
+
+ dbus_free(data);
+}
+
+static void random_mac_lifetime_params(DBusMessageIter *iter, void *user_data)
+{
+ struct supplicant_random_mac_lifetime *data = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &(data->lifetime));
+}
+
+int g_supplicant_interface_set_random_mac_lifetime(GSupplicantInterface *interface,
+ GSupplicantRandomMaclifetimeCallback callback,
+ unsigned int lifetime,
+ void *user_data)
+{
+ struct supplicant_random_mac_lifetime *data;
+ int ret;
+
+ if (!system_available)
+ return -EFAULT;
+
+ if (!interface)
+ return -EINVAL;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->callback = callback;
+ data->lifetime = lifetime;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_property_set(interface->path,
+ SUPPLICANT_INTERFACE ".Interface",
+ "RandAddrLifetime", DBUS_TYPE_UINT32_AS_STRING,
+ random_mac_lifetime_params, random_mac_lifetime_result,
+ data, NULL);
+ if (ret < 0) {
+ SUPPLICANT_DBG("Unable to set RandAddrLifetime configuration");
+ dbus_free(data);
+ }
+
+ return ret;
+}
+#endif