static int wpa_driver_wext_flush_pmkid(void *priv);
static int wpa_driver_wext_get_range(void *priv);
static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
+static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv);
static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
req.ifinfo.ifi_change = 0;
if (linkmode != -1) {
- rta = (struct rtattr *)
- ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+ rta = aliasing_hide_typecast(
+ ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
+ struct rtattr);
rta->rta_type = IFLA_LINKMODE;
rta->rta_len = RTA_LENGTH(sizeof(char));
*((char *) RTA_DATA(rta)) = linkmode;
drv->assoc_req_ies = NULL;
os_free(drv->assoc_resp_ies);
drv->assoc_resp_ies = NULL;
- wpa_supplicant_event(ctx, EVENT_DISASSOC,
+#ifdef ANDROID
+ if (!drv->skip_disconnect) {
+ drv->skip_disconnect = 1;
+#endif
+ wpa_supplicant_event(ctx, EVENT_DISASSOC,
NULL);
+#ifdef ANDROID
+ }
+#endif
} else {
+#ifdef ANDROID
+ drv->skip_disconnect = 0;
+#endif
wpa_driver_wext_event_assoc_ies(drv);
wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
}
drv->event_sock = s;
drv->mlme_sock = -1;
-
+#ifdef ANDROID
drv->errors = 0;
-
+ drv->driver_is_loaded = TRUE;
+ drv->skip_disconnect = 0;
+#endif
wpa_driver_wext_finish_drv_init(drv);
return drv;
wpa_driver_wext_get_range(drv);
+ /*
+ * Unlock the driver's BSSID and force to a random SSID to clear any
+ * previous association the driver might have when the supplicant
+ * starts up.
+ */
+ wpa_driver_wext_disconnect(drv);
+
drv->ifindex = if_nametoindex(drv->ifname);
if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
* Clear possibly configured driver parameters in order to make it
* easier to use the driver after wpa_supplicant has been terminated.
*/
- (void) wpa_driver_wext_set_bssid(drv,
- (u8 *) "\x00\x00\x00\x00\x00\x00");
+ wpa_driver_wext_disconnect(drv);
wpa_driver_wext_send_oper_ifla(priv, 0, IF_OPER_UP);
drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+ drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
+ WPA_DRIVER_AUTH_SHARED |
+ WPA_DRIVER_AUTH_LEAP;
wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x "
"flags 0x%x",
static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
{
+ struct iwreq iwr;
const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
u8 ssid[32];
int i;
/*
- * Clear the BSSID selection and set a random SSID to make sure the
- * driver will not be trying to associate with something even if it
- * does not understand SIOCSIWMLME commands (or tries to associate
- * automatically after deauth/disassoc).
+ * Only force-disconnect when the card is in infrastructure mode,
+ * otherwise the driver might interpret the cleared BSSID and random
+ * SSID as an attempt to create a new ad-hoc network.
*/
- wpa_driver_wext_set_bssid(drv, null_bssid);
+ os_memset(&iwr, 0, sizeof(iwr));
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
+ perror("ioctl[SIOCGIWMODE]");
+ iwr.u.mode = IW_MODE_INFRA;
+ }
+
+ if (iwr.u.mode == IW_MODE_INFRA) {
+ /*
+ * Clear the BSSID selection and set a random SSID to make sure
+ * the driver will not be trying to associate with something
+ * even if it does not understand SIOCSIWMLME commands (or
+ * tries to associate automatically after deauth/disassoc).
+ */
+ wpa_driver_wext_set_bssid(drv, null_bssid);
- for (i = 0; i < 32; i++)
- ssid[i] = rand() & 0xFF;
- wpa_driver_wext_set_ssid(drv, ssid, 32);
+ for (i = 0; i < 32; i++)
+ ssid[i] = rand() & 0xFF;
+ wpa_driver_wext_set_ssid(drv, ssid, 32);
+ }
}
struct wpa_driver_wext_data *drv = priv;
int ret;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
- wpa_driver_wext_disconnect(drv);
ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
+ wpa_driver_wext_disconnect(drv);
return ret;
}
wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
+ if (!drv->driver_is_loaded && (os_strcasecmp(cmd, "START") != 0)) {
+ wpa_printf(MSG_ERROR,"WEXT: Driver not initialized yet");
+ return -1;
+ }
+
if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
os_strncpy(cmd, "RSSI", MAX_DRV_CMD_SIZE);
}
}
if (ret < 0) {
- wpa_printf(MSG_ERROR, "%s failed", __func__);
+ wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd);
drv->errors++;
if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) {
drv->errors = 0;
(os_strcasecmp(cmd, "MACADDR") == 0)) {
ret = strlen(buf);
}
-/* else if (os_strcasecmp(cmd, "START") == 0) {
- os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
- wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+ else if (os_strcasecmp(cmd, "START") == 0) {
+ drv->driver_is_loaded = TRUE;
+ /* os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
+ wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); */
}
else if (os_strcasecmp(cmd, "STOP") == 0) {
- wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
- }*/
+ drv->driver_is_loaded = FALSE;
+ /* wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); */
+ }
wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
}
return ret;