#include <connman/service.h>
#include <connman/peer.h>
#include <connman/log.h>
-#include <connman/option.h>
#include <connman/storage.h>
#include <include/setting.h>
#include <connman/provision.h>
#define BGSCAN_DEFAULT "simple:30:-65:300"
#define AUTOSCAN_EXPONENTIAL "exponential:3:300"
#define AUTOSCAN_SINGLE "single:3"
+#define SCAN_MAX_DURATION 10
#define P2P_FIND_TIMEOUT 30
#define P2P_CONNECTION_TIMEOUT 100
#define P2P_LISTEN_PERIOD 500
#define P2P_LISTEN_INTERVAL 2000
+#define ASSOC_STATUS_AUTH_TIMEOUT 16
#define ASSOC_STATUS_NO_CLIENT 17
#if defined TIZEN_EXT
#define LOAD_SHAPING_MAX_RETRIES 7
#endif
};
+struct disconnect_data {
+ struct wifi_data *wifi;
+ struct connman_network *network;
+};
+
#if defined TIZEN_EXT
#include "connman.h"
#include "dbus.h"
static unsigned char buff_bssid[WIFI_BSSID_LEN_MAX] = { 0, };
#endif
-
static GList *iface_list = NULL;
static GList *pending_wifi_device = NULL;
if (version > 0) {
params->version = version;
- params->service = g_memdup(spec, spec_length);
+ if (spec_length > 0) {
+ params->service = g_malloc(spec_length);
+ memcpy(params->service, spec, spec_length);
+ }
} else if (query_length > 0 && spec_length > 0) {
- params->query = g_memdup(query, query_length);
+ params->query = g_malloc(query_length);
+ memcpy(params->query, query, query_length);
params->query_length = query_length;
- params->response = g_memdup(spec, spec_length);
+ params->response = g_malloc(spec_length);
+ memcpy(params->response, spec, spec_length);
params->response_length = spec_length;
} else {
- params->wfd_ies = g_memdup(spec, spec_length);
+ if (spec_length > 0) {
+ params->wfd_ies = g_malloc(spec_length);
+ memcpy(params->wfd_ies, spec, spec_length);
+ }
params->wfd_ies_length = spec_length;
}
}
if ((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
- if (flags & IFF_LOWER_UP) {
+ if (flags & IFF_LOWER_UP)
DBG("carrier on");
-
- handle_tethering(wifi);
- } else
+ else
DBG("carrier off");
}
+ if (flags & IFF_LOWER_UP)
+ handle_tethering(wifi);
+
wifi->flags = flags;
}
scan_params->num_ssids = i;
scan_params->ssids = g_slist_reverse(scan_params->ssids);
- scan_params->freqs = g_memdup(orig_params->freqs,
- sizeof(uint16_t) * orig_params->num_freqs);
- if (!scan_params->freqs)
+ if (orig_params->num_freqs <= 0)
goto err;
+ scan_params->freqs =
+ g_malloc(sizeof(uint16_t) * orig_params->num_freqs);
+ memcpy(scan_params->freqs, orig_params->freqs,
+ sizeof(uint16_t) *orig_params->num_freqs);
+
scan_params->num_freqs = orig_params->num_freqs;
} else
void *user_data)
{
struct wifi_data *wifi = user_data;
+ char *bgscan_range_max;
+ long value;
DBG("result %d ifname %s, wifi %p", result,
g_supplicant_interface_get_ifname(interface),
wifi->interface_ready = true;
finalize_interface_creation(wifi);
}
+
+ /*
+ * Set the BSS expiration age to match the long scanning
+ * interval to avoid the loss of unconnected networks between
+ * two scans.
+ */
+ bgscan_range_max = strrchr(BGSCAN_DEFAULT, ':');
+ if (!bgscan_range_max || strlen(bgscan_range_max) < 1)
+ return;
+
+ value = strtol(bgscan_range_max + 1, NULL, 10);
+ if (value <= 0 || errno == ERANGE)
+ return;
+
+ if (g_supplicant_interface_set_bss_expiration_age(interface,
+ value + SCAN_MAX_DURATION) < 0) {
+ connman_warn("Failed to set bss expiration age");
+ }
}
static int wifi_enable(struct connman_device *device)
struct wifi_data *wifi = connman_device_get_data(device);
int index;
char *interface;
- const char *driver = connman_option_get_string("wifi");
+ const char *driver = connman_setting_get_string("wifi");
int ret;
DBG("device %p %p", device, wifi);
static void disconnect_callback(int result, GSupplicantInterface *interface,
void *user_data)
{
+ struct disconnect_data *dd = user_data;
+ struct connman_network *network = dd->network;
#if defined TIZEN_EXT
GList *list;
struct wifi_data *wifi;
- struct connman_network *network = user_data;
+ g_free(dd);
DBG("network %p result %d", network, result);
for (list = iface_list; list; list = list->next) {
found:
#else
- struct wifi_data *wifi = user_data;
+ struct wifi_data *wifi = dd->wifi;
+ g_free(dd);
#endif
- DBG("result %d supplicant interface %p wifi %p",
- result, interface, wifi);
+ DBG("result %d supplicant interface %p wifi %p networks: current %p "
+ "pending %p disconnected %p", result, interface, wifi,
+ wifi->network, wifi->pending_network, network);
if (result == -ECONNABORTED) {
DBG("wifi interface no longer available");
(wifi->network != wifi->pending_network ||
connman_network_get_bool(wifi->network, "WiFi.Roaming")))
#else
- if (wifi->network && wifi->network != wifi->pending_network)
+ if (g_slist_find(wifi->networks, network))
#endif
- connman_network_set_connected(wifi->network, false);
- wifi->network = NULL;
+ connman_network_set_connected(network, false);
wifi->disconnecting = false;
+
+ if (network != wifi->network) {
+ if (network == wifi->pending_network)
+ wifi->pending_network = NULL;
+ DBG("current wifi network has changed since disconnection");
+ return;
+ }
+
+ wifi->network = NULL;
+
wifi->connected = false;
if (wifi->pending_network) {
static int network_disconnect(struct connman_network *network)
{
struct connman_device *device = connman_network_get_device(network);
+ struct disconnect_data *dd;
struct wifi_data *wifi;
int err;
#if defined TIZEN_EXT
wifi->disconnecting = true;
-#if defined TIZEN_EXT
- err = g_supplicant_interface_disconnect(wifi->interface,
- disconnect_callback, network);
-#else
- err = g_supplicant_interface_disconnect(wifi->interface,
- disconnect_callback, wifi);
-#endif
+ dd = g_malloc0(sizeof(*dd));
+ dd->wifi = wifi;
+ dd->network = network;
- if (err < 0)
+ err = g_supplicant_interface_disconnect(wifi->interface,
+ disconnect_callback, dd);
+ if (err < 0) {
wifi->disconnecting = false;
+ g_free(dd);
+ }
return err;
}
if (wps) {
const unsigned char *ssid, *wps_ssid;
unsigned int ssid_len, wps_ssid_len;
+ struct disconnect_data *dd;
const char *wps_key;
/* Checking if we got associated with requested
if (!wps_ssid || wps_ssid_len != ssid_len ||
memcmp(ssid, wps_ssid, ssid_len) != 0) {
+ dd = g_malloc0(sizeof(*dd));
+ dd->wifi = wifi;
+ dd->network = network;
+
connman_network_set_associating(network, false);
-#if defined TIZEN_EXT
g_supplicant_interface_disconnect(wifi->interface,
- disconnect_callback, wifi->network);
-
+ disconnect_callback, dd);
+#if defined TIZEN_EXT
connman_network_set_bool(network, "WiFi.UseWPS", false);
connman_network_set_string(network, "WiFi.PinWPS", NULL);
-#else
- g_supplicant_interface_disconnect(wifi->interface,
- disconnect_callback, wifi);
#endif
return false;
}
struct connman_network *network,
struct wifi_data *wifi)
{
-#if defined TIZEN_EXT
- const char *security;
struct connman_service *service;
+#if defined TIZEN_EXT
+ const char *security;
if (wifi->connected)
return false;
if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
return false;
#else
- struct connman_service *service;
-
- if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
+ if ((wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE) &&
+ !((wifi->state == G_SUPPLICANT_STATE_ASSOCIATING) &&
+ (wifi->assoc_code == ASSOC_STATUS_AUTH_TIMEOUT)))
return false;
if (wifi->connected)
/* See table 8-36 Reason codes in IEEE Std 802.11 */
switch (wifi->disconnect_code) {
+#if defined TIZEN_EXT
case 1: /* Unspecified reason */
/* Let's assume it's because we got blocked */
-
+#endif
case 6: /* Class 2 frame received from nonauthenticated STA */
connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_BLOCKED);
void *user_data)
{
struct wifi_tethering_info *info = user_data;
- const char *driver = connman_option_get_string("wifi");
+ const char *driver = connman_setting_get_string("wifi");
DBG("ifname %s result %d ", info->ifname, result);
const char *string;
GSupplicantINSPreferredFreq preferred_freq;
- string = connman_option_get_string("INSPreferredFreqBSSID");
+ string = connman_setting_get_string("INSPreferredFreqBSSID");
if (g_strcmp0(string, "5GHz") == 0)
preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ;
else if (g_strcmp0(string, "2.4GHz") == 0)