/* * Wireless Handler : get scan results */ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct iw_point *wrq = &wrqu->data; int ii; int jj; int kk; struct vnt_private *pDevice = netdev_priv(dev); struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; PKnownBSS pBSS; PWLAN_IE_SSID pItemSSID; PWLAN_IE_SUPP_RATES pSuppRates; PWLAN_IE_SUPP_RATES pExtSuppRates; char *current_ev = extra; char *end_buf = extra + IW_SCAN_MAX_DATA; char *current_val = NULL; struct iw_event iwe; long ldBm; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n"); if (pMgmt == NULL) return -EFAULT; if (pMgmt->eScanState == WMAC_IS_SCANNING) { // In scanning.. return -EAGAIN; } pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { if (current_ev >= end_buf) break; pBSS = &(pMgmt->sBSSList[jj]); if (pBSS->bActive) { // ADD mac address memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); // ADD ssid memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWESSID; pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; iwe.u.data.length = pItemSSID->len; iwe.u.data.flags = 1; current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); // ADD mode memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) iwe.u.mode = IW_MODE_INFRA; else iwe.u.mode = IW_MODE_ADHOC; iwe.len = IW_EV_UINT_LEN; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); // ADD frequency pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; iwe.u.freq.m = pBSS->uChannel; iwe.u.freq.e = 0; iwe.u.freq.i = 0; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); { int f = (int)pBSS->uChannel - 1; if (f < 0) f = 0; iwe.u.freq.m = frequency_list[f] * 100000; iwe.u.freq.e = 1; } current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); // ADD quality memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; RFvRSSITodBm(pDevice, (u8)(pBSS->uRSSI), &ldBm); iwe.u.qual.level = ldBm; iwe.u.qual.noise = 0; if (-ldBm < 50) iwe.u.qual.qual = 100; else if (-ldBm > 90) iwe.u.qual.qual = 0; else iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40; iwe.u.qual.updated = 7; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); // ADD encryption memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; iwe.u.data.length = 0; if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else iwe.u.data.flags = IW_ENCODE_DISABLED; current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWRATE; iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; current_val = current_ev + IW_EV_LCP_LEN; for (kk = 0; kk < 12; kk++) { if (pSuppRates->abyRates[kk] == 0) break; // Bit rate given in 500 kb/s units (+ 0x80) iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } for (kk = 0; kk < 8; kk++) { if (pExtSuppRates->abyRates[kk] == 0) break; // Bit rate given in 500 kb/s units (+ 0x80) iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } if ((current_val - current_ev) > IW_EV_LCP_LEN) current_ev = current_val; if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVGENIE; iwe.u.data.length = pBSS->wWPALen; current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE); } if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVGENIE; iwe.u.data.length = pBSS->wRSNLen; current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE); } } } // for wrq->length = current_ev - extra; return 0; }
static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ; tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); tSirBssDescription *descriptor = &scan_result->BssDescriptor; struct iw_event event; char *current_event = scanInfo->start; char *end = scanInfo->end; char *last_event; char *current_pad; v_U16_t ie_length = 0; v_U16_t capabilityInfo; char *modestr; int error; char custom[MAX_CUSTOM_LEN]; char *p; hddLog( LOG1, "hdd_IndicateScanResult %02x:%02x:%02x:%02x:%02x:%02x", descriptor->bssId[0], descriptor->bssId[1], descriptor->bssId[2], descriptor->bssId[3], descriptor->bssId[4], descriptor->bssId[5]); error = 0; last_event = current_event; vos_mem_zero(&event, sizeof (event)); event.cmd = SIOCGIWAP; event.u.ap_addr.sa_family = ARPHRD_ETHER; vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId, sizeof (descriptor->bssId)); current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_ADDR_LEN); if (last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP "); return -E2BIG; } last_event = current_event; vos_mem_zero(&event, sizeof (struct iw_event)); event.cmd = SIOCGIWNAME; switch (descriptor->nwType) { case eSIR_11A_NW_TYPE: modestr = "a"; break; case eSIR_11B_NW_TYPE: modestr = "b"; break; case eSIR_11G_NW_TYPE: modestr = "g"; break; case eSIR_11N_NW_TYPE: modestr = "n"; break; default: hddLog( LOGW, "%s: Unknown network type [%d]", __func__, descriptor->nwType); modestr = "?"; break; } snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr); current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_CHAR_LEN); if (last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME"); return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); event.cmd = SIOCGIWFREQ; event.u.freq.m = descriptor->channelId; event.u.freq.e = 0; event.u.freq.i = 0; current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_FREQ_LEN); if (last_event == current_event) { return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); event.cmd = SIOCGIWMODE; capabilityInfo = descriptor->capabilityInfo; if (SIR_MAC_GET_ESS(capabilityInfo)) { event.u.mode = IW_MODE_INFRA; } else if (SIR_MAC_GET_IBSS(capabilityInfo)) { event.u.mode = IW_MODE_ADHOC; } else { event.u.mode = IW_MODE_AUTO; } current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_UINT_LEN); if (last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE"); return -E2BIG; } ie_length = GET_IE_LEN_IN_BSS( descriptor->length ); if (ie_length > 0) { static tDot11fBeaconIEs dot11BeaconIEs; tDot11fIESSID *pDot11SSID; tDot11fIESuppRates *pDot11SuppRates; tDot11fIEExtSuppRates *pDot11ExtSuppRates; tDot11fIEHTCaps *pDot11IEHTCaps; int numBasicRates = 0; int maxNumRates = 0; pDot11IEHTCaps = NULL; dot11fUnpackBeaconIEs ((tpAniSirGlobal) hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs); pDot11SSID = &dot11BeaconIEs.SSID; if (pDot11SSID->present ) { last_event = current_event; vos_mem_zero (&event, sizeof (struct iw_event)); event.cmd = SIOCGIWESSID; event.u.data.flags = 1; event.u.data.length = scan_result->ssId.length; current_event = iwe_stream_add_point (scanInfo->info,current_event, end, &event, (char *)scan_result->ssId.ssId); if(last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } } if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, ¤t_event, scanInfo ) < 0 ) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } last_event = current_event; current_pad = current_event + IW_EV_LCP_LEN; vos_mem_zero( &event, sizeof (struct iw_event)); event.cmd = SIOCGIWRATE; pDot11SuppRates = &dot11BeaconIEs.SuppRates; if (pDot11SuppRates->present ) { int i; numBasicRates = pDot11SuppRates->num_rates; for (i=0; i<pDot11SuppRates->num_rates; i++) { if (0 != (pDot11SuppRates->rates[i] & 0x7F)) { event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( &pDot11SuppRates->rates[i]); current_pad = iwe_stream_add_value (scanInfo->info,current_event, current_pad, end, &event, IW_EV_PARAM_LEN); } } } pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates; if (pDot11ExtSuppRates->present ) { int i,no_of_rates; maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates; maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES); if((maxNumRates - numBasicRates) > MAX_RATES) { no_of_rates = MAX_RATES; hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates "); } else { no_of_rates = maxNumRates - numBasicRates; } for ( i=0; i< no_of_rates ; i++ ) { if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F)) { event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( &pDot11ExtSuppRates->rates[i]); current_pad = iwe_stream_add_value (scanInfo->info,current_event, current_pad, end, &event, IW_EV_PARAM_LEN); } } } if ((current_pad - current_event) >= IW_EV_LCP_LEN) { current_event = current_pad; } else { if (last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWRATE"); return -E2BIG; } } last_event = current_event; vos_mem_zero (&event, sizeof (struct iw_event)); event.cmd = SIOCGIWENCODE; if (SIR_MAC_GET_PRIVACY(capabilityInfo)) { event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; } else { event.u.data.flags = IW_ENCODE_DISABLED; } event.u.data.length = 0; current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid); if(last_event == current_event) { return -E2BIG; } } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); event.cmd = IWEVQUAL; event.u.qual.qual = descriptor->rssi; event.u.qual.noise = descriptor->sinr; if (( eConnectionState_Associated == pAdapter->sessionCtx.station.conn_info.connState ) && ( VOS_TRUE == vos_mem_compare(descriptor->bssId, pAdapter->sessionCtx.station.conn_info.bssId, WNI_CFG_BSSID_LEN))) { event.u.qual.level = pAdapter->rssi; } else { event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0); } event.u.qual.updated = IW_QUAL_ALL_UPDATED; current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_QUAL_LEN); if(last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL"); return -E2BIG; } event.cmd = IWEVCUSTOM; p = custom; p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu", vos_timer_get_system_ticks() - descriptor->nReceivedTime); event.u.data.length = p - custom; current_event = iwe_stream_add_point (scanInfo->info,current_event, end, &event, custom); if(last_event == current_event) { hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); return -E2BIG; } scanInfo->start = current_event; return 0; }
static int wlcompat_get_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { wl_scan_results_t *results = (wl_scan_results_t *) buf; wl_bss_info_t *bss_info; char *info_ptr; char *current_ev = extra; char *current_val; char *end_buf = extra + IW_SCAN_MAX_DATA; struct iw_event iwe; int i, j; if (wl_ioctl(dev, WLC_SCAN_RESULTS, buf, WLC_IOCTL_MAXLEN) < 0) return -EAGAIN; bss_info = &(results->bss_info[0]); info_ptr = (char *) bss_info; for (i = 0; i < results->count; i++) { /* send the cell address (must be sent first) */ iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(&iwe.u.ap_addr.sa_data, &bss_info->BSSID, sizeof(bss_info->BSSID)); current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); /* send the ESSID */ iwe.cmd = SIOCGIWESSID; iwe.u.data.length = bss_info->SSID_len; if (iwe.u.data.length > IW_ESSID_MAX_SIZE) iwe.u.data.length = IW_ESSID_MAX_SIZE; iwe.u.data.flags = 1; current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss_info->SSID); /* send frequency/channel info */ iwe.cmd = SIOCGIWFREQ; iwe.u.freq.e = 0; iwe.u.freq.m = bss_info->channel; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); /* add quality statistics */ iwe.cmd = IWEVQUAL; iwe.u.qual.level = bss_info->RSSI; iwe.u.qual.noise = bss_info->phy_noise; iwe.u.qual.qual = 0; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); /* send rate information */ iwe.cmd = SIOCGIWRATE; current_val = current_ev + IW_EV_LCP_LEN; iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; for(j = 0 ; j < bss_info->rateset.count ; j++) { iwe.u.bitrate.value = ((bss_info->rateset.rates[j] & 0x7f) * 500000); current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } if((current_val - current_ev) > IW_EV_LCP_LEN) current_ev = current_val; info_ptr += sizeof(wl_bss_info_t); if (bss_info->ie_length % 4) info_ptr += bss_info->ie_length + 4 - (bss_info->ie_length % 4); else info_ptr += bss_info->ie_length; bss_info = (wl_bss_info_t *) info_ptr; } wrqu->data.length = (current_ev - extra); wrqu->data.flags = 0; return 0; }
static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ; tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); tSirBssDescription *descriptor = &scan_result->BssDescriptor; struct iw_event event; char *current_event = scanInfo->start; char *end = scanInfo->end; char *last_event; char *current_pad; v_U16_t ie_length = 0; v_U16_t capabilityInfo; char *modestr; int error; char custom[MAX_CUSTOM_LEN]; char *p; hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(descriptor->bssId)); error = 0; last_event = current_event; vos_mem_zero(&event, sizeof (event)); /* BSSID */ event.cmd = SIOCGIWAP; event.u.ap_addr.sa_family = ARPHRD_ETHER; vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId, sizeof (descriptor->bssId)); current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_ADDR_LEN); if (last_event == current_event) { /* no space to add event */ /* Error code may be E2BIG */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWAP "); return -E2BIG; } last_event = current_event; vos_mem_zero(&event, sizeof (struct iw_event)); /* Protocol Name */ event.cmd = SIOCGIWNAME; switch (descriptor->nwType) { case eSIR_11A_NW_TYPE: modestr = "a"; break; case eSIR_11B_NW_TYPE: modestr = "b"; break; case eSIR_11G_NW_TYPE: modestr = "g"; break; case eSIR_11N_NW_TYPE: modestr = "n"; break; default: hddLog( LOGW, "%s: Unknown network type [%d]", __func__, descriptor->nwType); modestr = "?"; break; } snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr); current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_CHAR_LEN); if (last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWNAME"); /* Error code, may be E2BIG */ return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); /*Freq*/ event.cmd = SIOCGIWFREQ; event.u.freq.m = descriptor->channelId; event.u.freq.e = 0; event.u.freq.i = 0; current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_FREQ_LEN); if (last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWFREQ"); return -E2BIG; } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); /* BSS Mode */ event.cmd = SIOCGIWMODE; capabilityInfo = descriptor->capabilityInfo; if (SIR_MAC_GET_ESS(capabilityInfo)) { event.u.mode = IW_MODE_MASTER; } else if (SIR_MAC_GET_IBSS(capabilityInfo)) { event.u.mode = IW_MODE_ADHOC; } else { /* neither ESS or IBSS */ event.u.mode = IW_MODE_AUTO; } current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_UINT_LEN); if (last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWMODE"); return -E2BIG; } /* To extract SSID */ ie_length = GET_IE_LEN_IN_BSS( descriptor->length ); if (ie_length > 0) { /* dot11BeaconIEs is a large struct, so we make it static to avoid stack overflow. This API is only invoked via ioctl, so it is serialized by the kernel rtnl_lock and hence does not need to be reentrant */ static tDot11fBeaconIEs dot11BeaconIEs; tDot11fIESSID *pDot11SSID; tDot11fIESuppRates *pDot11SuppRates; tDot11fIEExtSuppRates *pDot11ExtSuppRates; tDot11fIEHTCaps *pDot11IEHTCaps; int numBasicRates = 0; int maxNumRates = 0; pDot11IEHTCaps = NULL; dot11fUnpackBeaconIEs ((tpAniSirGlobal) hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs); pDot11SSID = &dot11BeaconIEs.SSID; if (pDot11SSID->present ) { last_event = current_event; vos_mem_zero (&event, sizeof (struct iw_event)); event.cmd = SIOCGIWESSID; event.u.data.flags = 1; event.u.data.length = scan_result->ssId.length; current_event = iwe_stream_add_point (scanInfo->info,current_event, end, &event, (char *)scan_result->ssId.ssId); if(last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } } if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, ¤t_event, scanInfo ) < 0 ) { hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); return -E2BIG; } last_event = current_event; current_pad = current_event + IW_EV_LCP_LEN; vos_mem_zero( &event, sizeof (struct iw_event)); /*Rates*/ event.cmd = SIOCGIWRATE; pDot11SuppRates = &dot11BeaconIEs.SuppRates; if (pDot11SuppRates->present ) { int i; numBasicRates = pDot11SuppRates->num_rates; for (i=0; i<pDot11SuppRates->num_rates; i++) { if (0 != (pDot11SuppRates->rates[i] & 0x7F)) { event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( &pDot11SuppRates->rates[i]); current_pad = iwe_stream_add_value (scanInfo->info,current_event, current_pad, end, &event, IW_EV_PARAM_LEN); } } } pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates; if (pDot11ExtSuppRates->present ) { int i,no_of_rates; maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates; /* Check to make sure the total number of rates doesn't exceed IW_MAX_BITRATES */ maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES); if((maxNumRates - numBasicRates) > MAX_RATES) { no_of_rates = MAX_RATES; hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates "); } else { no_of_rates = maxNumRates - numBasicRates; } for ( i=0; i< no_of_rates ; i++ ) { if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F)) { event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( &pDot11ExtSuppRates->rates[i]); current_pad = iwe_stream_add_value (scanInfo->info,current_event, current_pad, end, &event, IW_EV_PARAM_LEN); } } } if ((current_pad - current_event) >= IW_EV_LCP_LEN) { current_event = current_pad; } else { if (last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWRATE"); return -E2BIG; } } last_event = current_event; vos_mem_zero (&event, sizeof (struct iw_event)); event.cmd = SIOCGIWENCODE; if (SIR_MAC_GET_PRIVACY(capabilityInfo)) { event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; } else { event.u.data.flags = IW_ENCODE_DISABLED; } event.u.data.length = 0; current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid); if(last_event == current_event) { /* no space to add event Error code, may be E2BIG */ hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWENCODE"); return -E2BIG; } } last_event = current_event; vos_mem_zero( &event, sizeof (struct iw_event)); /*RSSI*/ event.cmd = IWEVQUAL; event.u.qual.qual = descriptor->rssi; event.u.qual.noise = descriptor->sinr; /*To keep the rssi icon of the connected AP in the scan window *and the rssi icon of the wireless networks in sync */ if (( eConnectionState_Associated == pAdapter->sessionCtx.station.conn_info.connState ) && ( VOS_TRUE == vos_mem_compare(descriptor->bssId, pAdapter->sessionCtx.station.conn_info.bssId, VOS_MAC_ADDR_SIZE))) { event.u.qual.level = pAdapter->rssi; } else { event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0); } event.u.qual.updated = IW_QUAL_ALL_UPDATED; current_event = iwe_stream_add_event(scanInfo->info,current_event, end, &event, IW_EV_QUAL_LEN); if(last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVQUAL"); return -E2BIG; } /* AGE */ event.cmd = IWEVCUSTOM; p = custom; p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu", vos_timer_get_system_ticks() - descriptor->nReceivedTime); event.u.data.length = p - custom; current_event = iwe_stream_add_point (scanInfo->info,current_event, end, &event, custom); if(last_event == current_event) { /* no space to add event */ hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); return -E2BIG; } scanInfo->start = current_event; return 0; }
int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { int ii, jj, kk; PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PKnownBSS pBSS; PWLAN_IE_SSID pItemSSID; PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; char *current_ev = extra; char *end_buf = extra + IW_SCAN_MAX_DATA; char *current_val = NULL; struct iw_event iwe; long ldBm; char buf[MAX_WPA_IE_LEN * 2 + 30]; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n"); if (pMgmt->eScanState == WMAC_IS_SCANNING) { return -EAGAIN; } pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { if (current_ev >= end_buf) break; pBSS = &(pMgmt->sBSSList[jj]); if (pBSS->bActive) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWESSID; pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; iwe.u.data.length = pItemSSID->len; iwe.u.data.flags = 1; current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { iwe.u.mode = IW_MODE_INFRA; } else { iwe.u.mode = IW_MODE_ADHOC; } iwe.len = IW_EV_UINT_LEN; current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; iwe.u.freq.m = pBSS->uChannel; iwe.u.freq.e = 0; iwe.u.freq.i = 0; current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); { int f = (int)pBSS->uChannel - 1; if(f < 0)f = 0; iwe.u.freq.m = frequency_list[f] * 100000; iwe.u.freq.e = 1; } current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); iwe.u.qual.level = ldBm; iwe.u.qual.noise = 0; if(-ldBm<50){ iwe.u.qual.qual = 100; }else if(-ldBm > 90) { iwe.u.qual.qual = 0; }else { iwe.u.qual.qual=(40-(-ldBm-50))*100/40; } iwe.u.qual.updated=7; current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; iwe.u.data.length = 0; if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; }else { iwe.u.data.flags = IW_ENCODE_DISABLED; } current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWRATE; iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; current_val = current_ev + IW_EV_LCP_LEN; for (kk = 0 ; kk < 12 ; kk++) { if (pSuppRates->abyRates[kk] == 0) break; iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } for (kk = 0 ; kk < 8 ; kk++) { if (pExtSuppRates->abyRates[kk] == 0) break; iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } if((current_val - current_ev) > IW_EV_LCP_LEN) current_ev = current_val; memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); iwe.u.data.length = strlen(buf); current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf); if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVGENIE; iwe.u.data.length = pBSS->wWPALen; current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE); } if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVGENIE; iwe.u.data.length = pBSS->wRSNLen; current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE); } } } wrq->length = current_ev - extra; return 0; }