int android_ioctl_siwpriv(struct net_device *dev, struct iw_request_info *__info, struct iw_point *data, char *__extra) { char cmd[384]; /* assume that android command will not excess 384 */ char buf[512]; int len = sizeof(cmd)-1; AR_SOFTC_DEV_T *arPriv = (AR_SOFTC_DEV_T *)ar6k_priv(dev); AR_SOFTC_STA_T *arSta = &arPriv->arSta; if (!data->pointer) { return -EOPNOTSUPP; } if (data->length < len) { len = data->length; } if (copy_from_user(cmd, data->pointer, len)) { return -EIO; } cmd[len] = 0; if (strcasecmp(cmd, "RSSI")==0 || strcasecmp(cmd, "RSSI-APPROX") == 0) { int rssi = -200; struct iw_statistics *iwStats; struct iw_statistics* (*get_iwstats)(struct net_device *); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) get_iwstats = dev->get_wireless_stats; #else get_iwstats = dev->wireless_handlers->get_wireless_stats; #endif if (get_iwstats && arPriv->arConnected) { iwStats = get_iwstats(dev); if (iwStats) { rssi = iwStats->qual.qual; if (rssi == 255) rssi = -200; else rssi += (161 - 256); } } len = snprintf(buf, data->length, "SSID rssi %d\n", rssi) + 1; return (copy_to_user(data->pointer, buf, len)==0) ? len : -1; } else if (strcasecmp(cmd, "LINKSPEED")==0) { /* We skip to use SIOCGIWRATE since Android always asked LINKSPEED just after RSSI*/ unsigned int speed_mbps; if (arPriv->arConnected) { speed_mbps = arPriv->arTargetStats.tx_unicast_rate / 1000; } else { speed_mbps = 1; } len = snprintf(buf, data->length, "LinkSpeed %u\n", speed_mbps) + 1; return (copy_to_user(data->pointer, buf, len)==0) ? len : -1; } else if (memcmp(cmd, "CSCAN S\x01\x00\x00S\x00", 12)==0) { int iocmd = SIOCSIWSCAN - SIOCSIWCOMMIT; const iw_handler setScan = dev->wireless_handlers->standard[iocmd]; A_INT32 home_dwell=0, pas_dwell=0, act_dwell=0; A_UCHAR ssid[IW_ESSID_MAX_SIZE+1] = { 0 }; A_INT32 ssid_len = 0, ie_len; A_UINT8 index = 1; /* reserve index 0 for wext */ A_INT32 ch = 0; A_CHAR nprobe, scantype; struct iw_freq chList[IW_MAX_FREQUENCIES]; A_UCHAR *scanBuf = (A_UCHAR*)(cmd + 12); A_UCHAR *scanEnd = (A_UCHAR*)(cmd + len); A_BOOL broadcastSsid = FALSE; while ( scanBuf < scanEnd ) { A_UCHAR *sp = scanBuf; switch (*scanBuf) { case 'S': /* SSID section */ if (ssid_len > 0 && index < MAX_PROBED_SSID_INDEX) { /* setup the last parsed ssid, reserve index 0 for wext */ if (wmi_probedSsid_cmd(arPriv->arWmi, index, SPECIFIC_SSID_FLAG, ssid_len, ssid) == A_OK) { ++index; if (arSta->scanSpecificSsid<index) { arSta->scanSpecificSsid = index; } } } ie_len = ((scanBuf + 1) < scanEnd) ? ((A_INT32)*(scanBuf+1) + 1) : 0; if ((scanBuf+ie_len) < scanEnd ) { ssid_len = *(scanBuf+1); if (ssid_len == 0) { broadcastSsid = TRUE; } else { A_MEMCPY(ssid, scanBuf+2, ssid_len); ssid[ssid_len] = '\0'; } } scanBuf += 1 + ie_len; break; case 'C': /* Channel section */ if (scanBuf+1 < scanEnd) { int value = *(scanBuf+1); if (value == 0) { ch = 0; /* scan for all channels */ } else if (ch < IW_MAX_FREQUENCIES) { if (value>1000) { chList[ch].e = 1; chList[ch].m = value * 100000; } else { chList[ch].e = 0; chList[ch].m = value; } ++ch; } } scanBuf += 2; break; case 'P': /* Passive dwell section */ if (scanBuf+2 < scanEnd) { pas_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8); } scanBuf += 3; break; case 'H': /* Home dwell section */ if (scanBuf+2 < scanEnd) { home_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8); } scanBuf += 3; break; case 'N': /* Number of probe section */ if (scanBuf+1 < scanEnd) { nprobe = *(scanBuf+1); } scanBuf += 2; break; case 'A': /* Active dwell section */ if (scanBuf+2 < scanEnd) { act_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8); } scanBuf += 3; break; case 'T': /* Scan active type section */ if (scanBuf+1 < scanEnd) { scantype = *(scanBuf+1); } scanBuf += 2; break; default: break; } if (sp == scanBuf) { return -1; /* parsing error */ } } if (ssid_len>0) { A_UINT8 idx; /* Clean up the last specific scan items */ for (idx=index; idx<arSta->scanSpecificSsid; ++idx) { wmi_probedSsid_cmd(arPriv->arWmi, idx, DISABLE_SSID_FLAG, 0, NULL); } arSta->scanSpecificSsid = index; /* * There is no way to know when we need to send broadcast probe in current Android wpa_supplicant_6 * combo scan implemenation. Always force to sent it here uniti future Android version will set * the broadcast flags for combo scan. */ #if 0 if (broadcastSsid) #endif { /* setup the last index as broadcast SSID for combo scan */ ++arSta->scanSpecificSsid; wmi_probedSsid_cmd(arPriv->arWmi, index, ANY_SSID_FLAG, 0, NULL); } } if (pas_dwell>0) { /* TODO: Should we change our passive dwell? There may be some impact for bt-coex */ } if (home_dwell>0) { /* TODO: Should we adjust home_dwell? How to pass it to wext handler? */ } if (setScan) { union iwreq_data miwr; struct iw_request_info minfo; struct iw_scan_req scanreq, *pScanReq = NULL; A_MEMZERO(&minfo, sizeof(minfo)); A_MEMZERO(&miwr, sizeof(miwr)); A_MEMZERO(&scanreq, sizeof(scanreq)); if (ssid_len > 0) { pScanReq = &scanreq; memcpy(scanreq.essid, ssid, ssid_len); scanreq.essid_len = ssid_len; miwr.data.flags |= IW_SCAN_THIS_ESSID; } if (ch > 0) { pScanReq = &scanreq; scanreq.num_channels = ch; memcpy(scanreq.channel_list, chList, ch * sizeof(chList[0])); miwr.data.flags |= IW_SCAN_THIS_FREQ; } if (pScanReq) { miwr.data.pointer = (__force void __user *)&scanreq; miwr.data.length = sizeof(scanreq); } minfo.cmd = SIOCSIWSCAN; return setScan(dev, &minfo, &miwr, (char*)pScanReq); } return -1; } else if (strcasecmp(cmd, "MACADDR")==0) { /* reply comes back in the form "Macaddr = XX:XX:XX:XX:XX:XX" where XX */ A_UCHAR *mac = dev->dev_addr; len = snprintf(buf, data->length, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) + 1; return (copy_to_user(data->pointer, buf, len)==0) ? len : -1; } else if (strcasecmp(cmd, "SCAN-ACTIVE")==0) { return 0; /* unsupport function. Suppress the error */ } else if (strcasecmp(cmd, "SCAN-PASSIVE")==0) { return 0; /* unsupport function. Suppress the error */ } else if (strcasecmp(cmd, "START")==0 || strcasecmp(cmd, "STOP")==0) { struct ifreq ifr; char userBuf[16]; int ex_arg = (strcasecmp(cmd, "START")==0) ? WLAN_ENABLED : WLAN_DISABLED; int ret; A_MEMZERO(userBuf, sizeof(userBuf)); ((int *)userBuf)[0] = AR6000_XIOCTRL_WMI_SET_WLAN_STATE; ((int *)userBuf)[1] = ex_arg; ret = android_do_ioctl_direct(dev, AR6000_IOCTL_EXTENDED, &ifr, userBuf); if (ret==0) { /* Send wireless event which need by android supplicant */ union iwreq_data wrqu; A_MEMZERO(&wrqu, sizeof(wrqu)); wrqu.data.length = strlen(cmd); wireless_send_event(dev, IWEVCUSTOM, &wrqu, cmd); } return ret; } else if (strncasecmp(cmd, "POWERMODE ", 10)==0) { int mode; if (sscanf(cmd, "%*s %d", &mode) == 1) { int iocmd = SIOCSIWPOWER - SIOCSIWCOMMIT; iw_handler setPower = dev->wireless_handlers->standard[iocmd]; if (setPower) { union iwreq_data miwr; struct iw_request_info minfo; A_MEMZERO(&minfo, sizeof(minfo)); A_MEMZERO(&miwr, sizeof(miwr)); minfo.cmd = SIOCSIWPOWER; if (mode == 0 /* auto */) miwr.power.disabled = 0; else if (mode == 1 /* active */) miwr.power.disabled = 1; else return -1; return setPower(dev, &minfo, &miwr, NULL); } } return -1; } else if (strcasecmp(cmd, "GETPOWER")==0) { struct ifreq ifr; int userBuf[2]; A_MEMZERO(userBuf, sizeof(userBuf)); ((int *)userBuf)[0] = AR6000_XIOCTRL_WMI_GET_POWER_MODE; if (android_do_ioctl_direct(dev, AR6000_IOCTL_EXTENDED, &ifr, userBuf)>=0) { WMI_POWER_MODE_CMD *getPowerMode = (WMI_POWER_MODE_CMD *)userBuf; len = snprintf(buf, data->length, "powermode = %u\n", (getPowerMode->powerMode==MAX_PERF_POWER) ? 1/*active*/ : 0/*auto*/) + 1; return (copy_to_user(data->pointer, buf, len)==0) ? len : -1; } return -1; } else if (strncasecmp(cmd, "SETSUSPENDOPT ", 14)==0) { int enable; if (sscanf(cmd, "%*s %d", &enable)==1) { /* * We set our suspend mode by wlan_config.h now. * Should we follow Android command?? TODO */ return 0; } return -1; } else if (strcasecmp(cmd, "SCAN-CHANNELS")==0) { // reply comes back in the form "Scan-Channels = X" where X is the number of channels int iocmd = SIOCGIWRANGE - SIOCSIWCOMMIT; iw_handler getRange = dev->wireless_handlers->standard[iocmd]; if (getRange) { union iwreq_data miwr; struct iw_request_info minfo; struct iw_range range; A_MEMZERO(&minfo, sizeof(minfo)); A_MEMZERO(&miwr, sizeof(miwr)); A_MEMZERO(&range, sizeof(range)); minfo.cmd = SIOCGIWRANGE; miwr.data.pointer = (__force void __user *) ⦥ miwr.data.length = sizeof(range); getRange(dev, &minfo, &miwr, (char*)&range); } if (arSta->arNumChannels!=-1) { len = snprintf(buf, data->length, "Scan-Channels = %d\n", arSta->arNumChannels) + 1; return (copy_to_user(data->pointer, buf, len)==0) ? len : -1; } return -1; } else if (strncasecmp(cmd, "SCAN-CHANNELS ", 14)==0 || strncasecmp(cmd, "COUNTRY ", 8)==0) { /* * Set the available channels with WMI_SET_CHANNELPARAMS cmd * However, the channels will be limited by the eeprom regulator domain * Try to use a regulator domain which will not limited the channels range. */ int i; int chan = 0; A_UINT16 *clist; struct ifreq ifr; char ioBuf[256]; WMI_CHANNEL_PARAMS_CMD *chParamCmd = (WMI_CHANNEL_PARAMS_CMD *)ioBuf; if (strncasecmp(cmd, "COUNTRY ", 8)==0) { char *country = cmd + 8; if (strcasecmp(country, "US")==0) { chan = 11; } else if (strcasecmp(country, "JP")==0) { chan = 14; } else if (strcasecmp(country, "EU")==0) { chan = 13; } } else if (sscanf(cmd, "%*s %d", &chan) != 1) { return -1; } if ( (chan != 11) && (chan != 13) && (chan != 14)) { return -1; } if (arPriv->arNextMode == AP_NETWORK) { return -1; } A_MEMZERO(&ifr, sizeof(ifr)); A_MEMZERO(ioBuf, sizeof(ioBuf)); chParamCmd->phyMode = WMI_11G_MODE; clist = chParamCmd->channelList; chParamCmd->numChannels = chan; chParamCmd->scanParam = 1; for (i = 0; i < chan; i++) { clist[i] = wlan_ieee2freq(i + 1); } return android_do_ioctl_direct(dev, AR6000_IOCTL_WMI_SET_CHANNELPARAMS, &ifr, ioBuf); } else if (strncasecmp(cmd, "BTCOEXMODE ", 11)==0) { int mode; if (sscanf(cmd, "%*s %d", &mode)==1) { /* * Android disable BT-COEX when obtaining dhcp packet except there is headset is connected * It enable the BT-COEX after dhcp process is finished * We ignore since we have our way to do bt-coex during dhcp obtaining. */ switch (mode) { case 1: /* Disable*/ break; case 0: /* Enable */ /* fall through */ case 2: /* Sense*/ /* fall through */ default: break; } return 0; /* ignore it */ } return -1; } else if (strcasecmp(cmd, "BTCOEXSCAN-START")==0) { /* Android enable or disable Bluetooth coexistence scan mode. When this mode is on, * some of the low-level scan parameters used by the driver are changed to * reduce interference with A2DP streaming. */ return 0; /* ignore it since we have btfilter */ } else if (strcasecmp(cmd, "BTCOEXSCAN-STOP")==0) { return 0; /* ignore it since we have btfilter */ } else if (strncasecmp(cmd, "RXFILTER-ADD ", 13)==0) { return 0; /* ignore it */ } else if (strncasecmp(cmd, "RXFILTER-REMOVE ", 16)==0) { return 0; /* ignoret it */ } else if (strcasecmp(cmd, "RXFILTER-START")==0 || strcasecmp(cmd, "RXFILTER-STOP")==0) { unsigned int flags = dev->flags; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) int mc_count = dev->mc_count; #else int mc_count = netdev_mc_count(dev); #endif if (strcasecmp(cmd, "RXFILTER-START")==0) { if (mc_count > 0 || (flags & IFF_MULTICAST) ) { flags &= ~IFF_MULTICAST; } } else { flags |= IFF_MULTICAST; } if (flags != dev->flags) { dev_change_flags(dev, flags); } return 0; } return -EOPNOTSUPP; }
void CAR6KMini::WMIDisconnectIndication(A_UINT8 reason) { #ifdef NO_BCAST_PROBE_IN_CONNECT wmi_probedSsid_cmd((struct wmi_t *)m_pWMI, 0, ANY_SSID_FLAG, 0,NULL); #endif do { // // Ignore pyxis specific reason during IEEE Mode // if (m_Connected) { if (reason == NO_NETWORK_AVAIL) { // remove the current associated bssid node wmi_free_node ((wmi_t *)m_pWMI, m_PeerBSSID); // // In case any other same SSID nodes are present // remove it, since those nodes also not available now // IterateNodeAndRemoveSSID (&m_SSID); SendWMIDisconnectCommand (); } // Flush any pending NDIS packets FlushNdisPacketTransmitQueue(); #ifdef OS_ROAM_MANAGEMENT if (FALSE == m_osRoamControl) { #endif m_RSSIlevel = 0; if (m_Config.hostAssistedRoaming) { A_UNTIMEOUT(&m_rssiScanTimer); } NdisMIndicateStatus(m_MiniportAdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, 0, 0); NdisMIndicateStatusComplete(m_MiniportAdapterHandle); #ifdef OS_ROAM_MANAGEMENT } else { A_UNTIMEOUT(&m_disconnectIndicationTimer); A_TIMEOUT_MS(&m_disconnectIndicationTimer, m_Config.discTimeout*1000, 0); } #endif // // Reset Chanel and BSSID info // m_Connected = FALSE; m_ChannelHint = 0; m_ConnectedChannel = 0; memset (m_PeerBSSID, 0, ETHERNET_MAC_ADDRESS_LENGTH); } if (m_bIsSwitchAPtoSTA) { m_bIsSwitchAPtoSTA = FALSE; NdisMIndicateStatus(m_MiniportAdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, 0, 0); NdisMIndicateStatusComplete(m_MiniportAdapterHandle); // configTargetParams(); m_WantToBeConnected = TRUE; } { // // no need to send WMIConnect when target reply disconnect // reason other than DISCONNECT_CMD // if (DISCONNECT_CMD == reason) { m_ConnectInProgress = FALSE; if (m_WantToBeConnected) { SendWMIConnectCommand (&m_SSID); } } } } while (FALSE); NdisSetEvent (&m_SuspendEvent); }
static int ar6000_cscan(struct net_device *dev, struct iw_point *data, char *cmdbuf) { char *ptr = cmdbuf; int iocmd = SIOCSIWSCAN - SIOCSIWCOMMIT; const iw_handler setScan = dev->wireless_handlers->standard[iocmd]; A_INT32 home_dwell=0, pas_dwell=0, act_dwell=0; A_UCHAR ssid[IW_ESSID_MAX_SIZE+1] = { 0 }; A_INT32 ssid_len = 0, ie_len; A_UINT8 index = 1; /* reserve index 0 for wext */ A_INT32 ch = 0,len=data->length ; A_CHAR nprobe, scantype; struct iw_freq chList[IW_MAX_FREQUENCIES]; A_UCHAR *scanBuf = (A_UCHAR*)(ptr+ 12); A_UCHAR *scanEnd = (A_UCHAR*)(ptr + len); A_BOOL broadcastSsid = FALSE; AR_SOFTC_DEV_T *arPriv = (AR_SOFTC_DEV_T *)ar6k_priv(dev); AR_SOFTC_STA_T *arSta = &arPriv->arSta; while ( scanBuf < scanEnd ) { A_UCHAR *sp = scanBuf; switch (*scanBuf) { case 'S': /* SSID section */ if (ssid_len > 0 && index < MAX_PROBED_SSID_INDEX) { /* setup the last parsed ssid, reserve index 0 for wext */ if (wmi_probedSsid_cmd(arPriv->arWmi, index, SPECIFIC_SSID_FLAG, ssid_len, ssid) == A_OK) { ++index; if (arSta->scanSpecificSsid<index) { arSta->scanSpecificSsid = index; } } } ie_len = ((scanBuf + 1) < scanEnd) ? ((A_INT32)*(scanBuf+1) + 1) : 0; if ((scanBuf+ie_len) < scanEnd ) { ssid_len = *(scanBuf+1); if (ssid_len == 0) { broadcastSsid = TRUE; } else { A_MEMCPY(ssid, scanBuf+2, ssid_len); ssid[ssid_len] = '\0'; } } scanBuf += 1 + ie_len; break; case 'C': /* Channel section */ if (scanBuf+1 < scanEnd) { int value = *(scanBuf+1); if (value == 0) { ch = 0; /* scan for all channels */ } else if (ch < IW_MAX_FREQUENCIES) { if (value>1000) { chList[ch].e = 1; chList[ch].m = value * 100000; } else { chList[ch].e = 0; chList[ch].m = value; } ++ch; } } scanBuf += 2; break; case 'P': /* Passive dwell section */ if (scanBuf+2 < scanEnd) { pas_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8); } scanBuf += 3; break; case 'H': /* Home dwell section */ if (scanBuf+2 < scanEnd) { home_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8); } scanBuf += 3; break; case 'N': /* Number of probe section */ if (scanBuf+1 < scanEnd) { nprobe = *(scanBuf+1); } scanBuf += 2; break; case 'A': /* Active dwell section */ if (scanBuf+2 < scanEnd) { act_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8); } scanBuf += 3; break; case 'T': /* Scan active type section */ if (scanBuf+1 < scanEnd) { scantype = *(scanBuf+1); } scanBuf += 2; break; default: break; } /* switch */ if (sp == scanBuf) { return -1; /* parsing error */ } }/* while */ if (ssid_len>0) { A_UINT8 idx; /* Clean up the last specific scan items */ for (idx=index; idx<arSta->scanSpecificSsid; ++idx) { wmi_probedSsid_cmd(arPriv->arWmi, idx, DISABLE_SSID_FLAG, 0, NULL); } arSta->scanSpecificSsid = index; /* * There is no way to know when we need to send broadcast probe in current Android wpa_supplicant_6 * combo scan implemenation. Always force to sent it here uniti future Android version will set * the broadcast flags for combo scan. */ #if 0 if (broadcastSsid) #endif { /* setup the last index as broadcast SSID for combo scan */ ++arSta->scanSpecificSsid; wmi_probedSsid_cmd(arPriv->arWmi, index, ANY_SSID_FLAG, 0, NULL); } } if (pas_dwell>0) { /* TODO: Should we change our passive dwell? There may be some impact for bt-coex */ } if (home_dwell>0) { /* TODO: Should we adjust home_dwell? How to pass it to wext handler? */ } if (setScan) { union iwreq_data miwr; struct iw_request_info minfo; struct iw_scan_req scanreq, *pScanReq = NULL; A_MEMZERO(&minfo, sizeof(minfo)); A_MEMZERO(&miwr, sizeof(miwr)); A_MEMZERO(&scanreq, sizeof(scanreq)); if (ssid_len > 0) { pScanReq = &scanreq; memcpy(scanreq.essid, ssid, ssid_len); scanreq.essid_len = ssid_len; miwr.data.flags |= IW_SCAN_THIS_ESSID; } if (ch > 0) { pScanReq = &scanreq; scanreq.num_channels = ch; memcpy(scanreq.channel_list, chList, ch * sizeof(chList[0])); miwr.data.flags |= IW_SCAN_THIS_FREQ; } if (pScanReq) { miwr.data.pointer = (__force void __user *)&scanreq; miwr.data.length = sizeof(scanreq); } minfo.cmd = SIOCSIWSCAN; return setScan(dev, &minfo, &miwr, (char*)pScanReq); } return -1; }
void CAR6KMini::WMIConnectIndication( IN USHORT Channel, IN PBYTE PeerBSSID, IN USHORT listenInterval, IN BYTE assocReqLen, IN BYTE assocRespLen, IN PBYTE assocInfo, IN BYTE beaconIeLen, IN USHORT beaconInterval, NETWORK_TYPE networkType) { BYTE len = 0; int i = 0; PBYTE pAssocReq; PBYTE pAssocReqEnd; PBYTE pBeaconIE; BYTE byKeyType = 0; #ifdef OS_ROAM_MANAGEMENT A_UNTIMEOUT(&m_disconnectIndicationTimer); #endif #ifdef NO_BCAST_PROBE_IN_CONNECT wmi_probedSsid_cmd((struct wmi_t *)m_pWMI, 0, ANY_SSID_FLAG, 0,NULL); #endif memcpy(m_PeerBSSID, PeerBSSID, ETHERNET_MAC_ADDRESS_LENGTH); m_ConnectedChannel = Channel; m_ConnectInProgress = FALSE; m_AssocReqLen = assocReqLen; m_AssocRespLen = assocRespLen; m_BeaconIeLen = beaconIeLen; m_BeaconInterval = beaconInterval; m_WantToBeConnected = FALSE; if (m_pAssocInfo != NULL) { A_FREE(m_pAssocInfo); } m_pAssocInfo = (PBYTE)A_MALLOC(m_AssocReqLen + m_AssocRespLen + m_BeaconIeLen); if (m_pAssocInfo) { memcpy(m_pAssocInfo, assocInfo, m_AssocReqLen + m_AssocRespLen + m_BeaconIeLen); //Get network type in use if (m_ConnectedChannel >= 2412 && m_ConnectedChannel <= 2484) { PBYTE pAssocRsp = m_pAssocInfo + m_BeaconIeLen + m_AssocReqLen; PBYTE pAssocRspEnd = pAssocRsp + m_AssocRespLen; m_NetworkTypeInUse = Ndis802_11DS; //Skip capability, status code and assoc. ID pAssocRsp += 6; if ((pAssocRsp + 2) < pAssocRspEnd && IEEE80211_ELEMID_RATES == pAssocRsp[0]) { pAssocRsp += (pAssocRsp[1] + 2); if ((pAssocRsp + 2) < pAssocRspEnd && IEEE80211_ELEMID_XRATES == pAssocRsp[0]) { m_NetworkTypeInUse = Ndis802_11OFDM24; } } } else { m_NetworkTypeInUse = Ndis802_11OFDM5; } // Update the group wise crypto type from the ie info #define RSN_MULTICAST_CIPHER_OFFSET 7 #define WPA_MULTICAST_CIPHER_OFFSET 11 pBeaconIE = m_pAssocInfo; if (m_BeaconIeLen) { if ((m_AuthenticationMode == Ndis802_11AuthModeWPA2) || (m_AuthenticationMode == Ndis802_11AuthModeWPA2PSK)) { if (m_BeaconIeLen <= RSN_MULTICAST_CIPHER_OFFSET) { // Default to AES if cipher suite not present m_GrpwiseCryptoType = AES_CRYPT; } else { byKeyType = *(pBeaconIE + RSN_MULTICAST_CIPHER_OFFSET); switch (byKeyType) { case RSN_CSE_WEP40: case RSN_CSE_WEP104: m_GrpwiseCryptoType = WEP_CRYPT; break; case RSN_CSE_TKIP: m_GrpwiseCryptoType = TKIP_CRYPT; break; case RSN_CSE_CCMP: m_GrpwiseCryptoType = AES_CRYPT; break; } } } else if ((m_AuthenticationMode == Ndis802_11AuthModeWPA) || (m_AuthenticationMode == Ndis802_11AuthModeWPAPSK)) { if (m_BeaconIeLen <= WPA_MULTICAST_CIPHER_OFFSET) { // Default to TKIP if cipher suite not present m_GrpwiseCryptoType = TKIP_CRYPT; } else { byKeyType = *(pBeaconIE + WPA_MULTICAST_CIPHER_OFFSET); switch (byKeyType) { case WPA_CSE_WEP40: case WPA_CSE_WEP104: m_GrpwiseCryptoType = WEP_CRYPT; break; case WPA_CSE_TKIP: m_GrpwiseCryptoType = TKIP_CRYPT; break; case WPA_CSE_CCMP: m_GrpwiseCryptoType = AES_CRYPT; break; } } } } // Get supported basic rates pAssocReq = m_pAssocInfo + m_BeaconIeLen; pAssocReqEnd = pAssocReq + m_AssocReqLen; // skip capability and listen interval pAssocReq += 4; if (((pAssocReq + 2) < pAssocReqEnd) && (IEEE80211_ELEMID_SSID == pAssocReq[0])) { // Skip SSID pAssocReq += (pAssocReq[1] + 2); if ((pAssocReq + 2) < pAssocReqEnd && IEEE80211_ELEMID_RATES == pAssocReq[0] && (pAssocReq + pAssocReq[1] + 2) <= pAssocReqEnd) { // Get rates memset (m_pSupportedRates, 0, sizeof(NDIS_802_11_RATES)); memcpy(m_pSupportedRates, &pAssocReq[2], (pAssocReq[1] < sizeof(NDIS_802_11_RATES)) ? pAssocReq[1] : sizeof(NDIS_802_11_RATES)); } } } #ifdef OS_ROAM_MANAGEMENT m_RateInfo.TxDataFrames = 0; m_RateInfo.RxDataFrames = 0; #endif // Indicate MEDIA_CONNECT to Ndis ConnectIndicationPostProc (); if (networkType == INFRA_NETWORK){ m_Connected = TRUE; m_ConnectInProgress = FALSE; NdisMIndicateStatus (m_MiniportAdapterHandle, NDIS_STATUS_MEDIA_CONNECT, 0, 0); NdisMIndicateStatusComplete (m_MiniportAdapterHandle); }else{ m_Connected = FALSE; } m_RSSIlevel = 0; if (m_Config.hostAssistedRoaming) { A_UNTIMEOUT(&m_rssiScanTimer); A_TIMEOUT_MS(&m_rssiScanTimer, 1000, 0); } return; }