| /* |
| * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| /* |
| * This file limScanResultUtils.cc contains the utility functions |
| * LIM uses for maintaining and accessing scan results on STA. |
| * Author: Chandra Modumudi |
| * Date: 02/13/02 |
| * History:- |
| * Date Modified by Modification Information |
| * -------------------------------------------------------------------- |
| */ |
| |
| #include "limTypes.h" |
| #include "limUtils.h" |
| #include "limSerDesUtils.h" |
| #include "limApi.h" |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| #include "limFTDefs.h" |
| #endif |
| #include "limSession.h" |
| #if defined WLAN_FEATURE_VOWIFI |
| #include "rrmApi.h" |
| #endif |
| #include "vos_utils.h" |
| |
| #ifdef WLAN_FEATURE_FILS_SK |
| /** |
| * lim_update_bss_with_fils_data: update fils data to bss descriptor |
| * if available in probe/beacon. |
| * @pr: probe response/beacon |
| * @bss_descr: pointer to bss descriptor |
| * |
| * @Return: None |
| */ |
| static void lim_update_bss_with_fils_data(tpSirProbeRespBeacon pr, |
| tSirBssDescription *bss_descr) |
| { |
| if (!pr->fils_ind.is_present) |
| return; |
| |
| if (pr->fils_ind.realm_identifier.realm_cnt > SIR_MAX_REALM_COUNT) |
| pr->fils_ind.realm_identifier.realm_cnt = SIR_MAX_REALM_COUNT; |
| |
| bss_descr->fils_info_element.realm_cnt = |
| pr->fils_ind.realm_identifier.realm_cnt; |
| vos_mem_copy(bss_descr->fils_info_element.realm, |
| pr->fils_ind.realm_identifier.realm, |
| bss_descr->fils_info_element.realm_cnt * SIR_REALM_LEN); |
| if (pr->fils_ind.cache_identifier.is_present) { |
| bss_descr->fils_info_element.is_cache_id_present = true; |
| vos_mem_copy(bss_descr->fils_info_element.cache_id, |
| pr->fils_ind.cache_identifier.identifier, CACHE_ID_LEN); |
| } |
| if (pr->fils_ind.is_fils_sk_auth_supported) |
| bss_descr->fils_info_element.is_fils_sk_supported = true; |
| } |
| #else |
| static inline void lim_update_bss_with_fils_data(tpSirProbeRespBeacon pr, |
| tSirBssDescription *bss_descr) |
| { |
| } |
| #endif |
| |
| /** |
| * limDeactiveMinChannelTimerDuringScan() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to deactivate MIN channel |
| * timer if running. |
| * |
| * This function should be called only when pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * |
| * @return eSIR_SUCCESS in case of success |
| */ |
| |
| tANI_U32 |
| limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal pMac) |
| { |
| if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE)) |
| { |
| /** |
| * Beacon/Probe Response is received during active scanning. |
| * Deactivate MIN channel timer if running. |
| */ |
| |
| limDeactivateAndChangeTimer(pMac,eLIM_MIN_CHANNEL_TIMER); |
| if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) |
| == TX_TIMER_ERROR) |
| { |
| /// Could not activate max channel timer. |
| // Log error |
| limLog(pMac,LOGP, FL("could not activate max channel timer")); |
| |
| limCompleteMlmScan(pMac, eSIR_SME_RESOURCES_UNAVAILABLE); |
| return TX_TIMER_ERROR; |
| } |
| } |
| return eSIR_SUCCESS; |
| } /*** end limDeactivateMinChannelTimerDuringScan() ***/ |
| |
| /** |
| * lim_check_and_change_cc: indicate upper layer country code changed |
| * @mac_ptr: Pointer to Global MAC structure |
| * @beacon_ptr: pointer to beacon |
| * @session_ptr: pointer to session |
| * |
| * @Return: None |
| */ |
| void |
| lim_check_and_change_cc(tpAniSirGlobal mac_ptr, |
| tpSirProbeRespBeacon beacon_ptr, |
| tpPESession session_ptr) |
| { |
| |
| tSirMsgQ mmh_msg; |
| tANI_U16 msg_len = 0; |
| struct sme_change_country_code_ind *change_cc_ind_ptr = NULL; |
| v_BOOL_t country_code_not_changed; |
| |
| limLog(mac_ptr, LOG1, FL("enter new cc %c%c old cc: %c%c"), |
| beacon_ptr->countryInfoParam.countryString[0], |
| beacon_ptr->countryInfoParam.countryString[1], |
| mac_ptr->scan.countryCodeCurrent[0], |
| mac_ptr->scan.countryCodeCurrent[1]); |
| |
| country_code_not_changed = |
| vos_mem_compare(beacon_ptr->countryInfoParam.countryString, |
| mac_ptr->scan.countryCodeCurrent, |
| VOS_COUNTRY_CODE_LEN); |
| if (FALSE == country_code_not_changed) { |
| msg_len = sizeof(*change_cc_ind_ptr); |
| change_cc_ind_ptr = vos_mem_malloc(msg_len); |
| if (NULL == change_cc_ind_ptr) { |
| limLog(mac_ptr, LOGE, FL("Mem alloc failed")); |
| return; |
| } |
| |
| change_cc_ind_ptr->message_type = eWNI_SME_CC_CHANGE_IND; |
| change_cc_ind_ptr->msg_len = msg_len; |
| change_cc_ind_ptr->session_id = session_ptr->smeSessionId; |
| memcpy(change_cc_ind_ptr->country_code, |
| beacon_ptr->countryInfoParam.countryString, |
| VOS_COUNTRY_CODE_LEN); |
| |
| mmh_msg.type = eWNI_SME_CC_CHANGE_IND; |
| mmh_msg.bodyptr = change_cc_ind_ptr; |
| mmh_msg.bodyval = 0; |
| limSysProcessMmhMsgApi(mac_ptr, &mmh_msg, ePROT); |
| |
| return; |
| } |
| } |
| |
| /** |
| * limCollectBssDescription() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to check if the received |
| * frame matches scan criteria, collect BSS description |
| * and add it to cached scan results. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBPR - Pointer to parsed Beacon/Probe Response structure |
| * @param pRxPacketInfo - Pointer to Received frame's BD |
| * ---------if defined WLAN_FEATURE_VOWIFI------ |
| * @param fScanning - flag to indicate if it is during scan. |
| * --------------------------------------------- |
| * |
| * @return None |
| */ |
| #if defined WLAN_FEATURE_VOWIFI |
| void |
| limCollectBssDescription(tpAniSirGlobal pMac, |
| tSirBssDescription *pBssDescr, |
| tpSirProbeRespBeacon pBPR, |
| tANI_U8 *pRxPacketInfo, |
| tANI_U8 fScanning) |
| #else |
| void |
| limCollectBssDescription(tpAniSirGlobal pMac, |
| tSirBssDescription *pBssDescr, |
| tpSirProbeRespBeacon pBPR, |
| tANI_U8 *pRxPacketInfo) |
| #endif |
| { |
| tANI_U8 *pBody; |
| tANI_U32 ieLen = 0; |
| tpSirMacMgmtHdr pHdr; |
| tANI_U8 channelNum; |
| tANI_U8 rxChannel; |
| tANI_U8 rfBand = 0; |
| |
| pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); |
| |
| if (SIR_MAC_B_PR_SSID_OFFSET > WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)) |
| { |
| VOS_ASSERT(WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >= SIR_MAC_B_PR_SSID_OFFSET); |
| return; |
| } |
| ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET; |
| rxChannel = WDA_GET_RX_CH(pRxPacketInfo); |
| pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); |
| rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); |
| |
| /** |
| * Length of BSS desription is without length of |
| * length itself and length of pointer |
| * that holds ieFields |
| * |
| * tSirBssDescription |
| * +--------+---------------------------------+---------------+ |
| * | length | other fields | pointer to IEs| |
| * +--------+---------------------------------+---------------+ |
| * ^ |
| * ieFields |
| */ |
| pBssDescr->length = (tANI_U16)(offsetof(tSirBssDescription, ieFields[0]) - |
| sizeof(pBssDescr->length) + ieLen); |
| |
| // Copy BSS Id |
| vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, |
| (tANI_U8 *) pHdr->bssId, |
| sizeof(tSirMacAddr)); |
| |
| // Copy Timestamp, Beacon Interval and Capability Info |
| pBssDescr->scansystimensec = vos_get_bootbased_boottime_ns(); |
| |
| pBssDescr->timeStamp[0] = pBPR->timeStamp[0]; |
| pBssDescr->timeStamp[1] = pBPR->timeStamp[1]; |
| pBssDescr->beaconInterval = pBPR->beaconInterval; |
| pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo); |
| |
| if(!pBssDescr->beaconInterval ) |
| { |
| limLog(pMac, LOGW, |
| FL("Beacon Interval is ZERO, making it to default 100 " |
| MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->bssId)); |
| pBssDescr->beaconInterval= 100; |
| } |
| /* |
| * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut |
| * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz |
| * band, so not relying on the 'last Scanned Channel' stored in LIM. |
| * Instead use the value returned by RXP in BD. This the the same value which HAL programs into |
| * RXP before every channel switch. |
| * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from |
| * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen. |
| * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it |
| * is not present in the beacon, we go for the channel info present in RXP. |
| * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel. |
| * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices. |
| */ |
| pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR); |
| |
| if (pBssDescr->channelId == 0) |
| { |
| /* If the channel Id is not retrieved from Beacon, extract the channel from BD */ |
| /* Unmapped the channel.This We have to do since we have done mapping in the hal to |
| overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/ |
| if ((!rfBand) || IS_5G_BAND(rfBand)) |
| { |
| rxChannel = limUnmapChannel(rxChannel); |
| } |
| if (!rxChannel) |
| { |
| rxChannel = pMac->lim.gLimCurrentScanChannelId; |
| } |
| pBssDescr->channelId = rxChannel; |
| } |
| |
| pBssDescr->channelIdSelf = pBssDescr->channelId; |
| //set the network type in bss description |
| channelNum = pBssDescr->channelId; |
| pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR); |
| |
| // Copy RSSI & SINR from BD |
| |
| PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** "); |
| sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 ); |
| sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );) |
| |
| pBssDescr->rssi = (tANI_S8)WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); |
| pBssDescr->rssi_raw = (tANI_S8)WDA_GET_RX_RSSI_RAW(pRxPacketInfo); |
| |
| //SINR no longer reported by HW |
| pBssDescr->sinr = 0; |
| pBssDescr->nReceivedTime = vos_timer_get_system_time(); |
| pBssDescr->tsf_delta = WDA_GET_RX_TSF_DELTA(pRxPacketInfo); |
| |
| limLog(pMac, LOG1, |
| FL("BSSID: "MAC_ADDRESS_STR " rssi: normalized = %d, absolute = %d tsf_delta = %u seq %d"), |
| MAC_ADDR_ARRAY(pHdr->bssId), pBssDescr->rssi, pBssDescr->rssi_raw, |
| pBssDescr->tsf_delta, ((pHdr->seqControl.seqNumHi << 4) | |
| (pHdr->seqControl.seqNumLo))); |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| if( fScanning ) |
| { |
| rrmGetStartTSF( pMac, pBssDescr->startTSF ); |
| pBssDescr->parentTSF = WDA_GET_RX_TIMESTAMP(pRxPacketInfo); |
| } |
| #endif |
| |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| // MobilityDomain |
| pBssDescr->mdie[0] = 0; |
| pBssDescr->mdie[1] = 0; |
| pBssDescr->mdie[2] = 0; |
| pBssDescr->mdiePresent = FALSE; |
| // If mdie is present in the probe resp we |
| // fill it in the bss description |
| if( pBPR->mdiePresent) |
| { |
| pBssDescr->mdiePresent = TRUE; |
| pBssDescr->mdie[0] = pBPR->mdie[0]; |
| pBssDescr->mdie[1] = pBPR->mdie[1]; |
| pBssDescr->mdie[2] = pBPR->mdie[2]; |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_ESE |
| pBssDescr->QBSSLoad_present = FALSE; |
| pBssDescr->QBSSLoad_avail = 0; |
| if( pBPR->QBSSLoad.present) |
| { |
| pBssDescr->QBSSLoad_present = TRUE; |
| pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail; |
| } |
| #endif |
| #ifdef WLAN_FEATURE_FILS_SK |
| lim_update_bss_with_fils_data(pBPR, pBssDescr); |
| #endif |
| // Copy IE fields |
| vos_mem_copy((tANI_U8 *) &pBssDescr->ieFields, |
| pBody + SIR_MAC_B_PR_SSID_OFFSET, |
| ieLen); |
| |
| /*set channel number in beacon in case it is not present*/ |
| pBPR->channelNumber = pBssDescr->channelId; |
| |
| limLog( pMac, LOG3, |
| FL("Collected BSS Description for Channel(%1d), length(%u), IE Fields(%u)"), |
| pBssDescr->channelId, |
| pBssDescr->length, |
| ieLen ); |
| |
| return; |
| } /*** end limCollectBssDescription() ***/ |
| |
| /** |
| * limIsScanRequestedSSID() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to check if the received |
| * SSID is present in the list of requested SSIDs in scan |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param ssId - SSID Received in beacons/Probe responses that is compared against the |
| requeusted SSID in scan list |
| * --------------------------------------------- |
| * |
| * @return boolean - TRUE if SSID is present in requested list, FALSE otherwise |
| */ |
| |
| tANI_BOOLEAN limIsScanRequestedSSID(tpAniSirGlobal pMac, tSirMacSSid *ssId) |
| { |
| tANI_U8 i = 0; |
| |
| for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++) |
| { |
| if ( eANI_BOOLEAN_TRUE == vos_mem_compare((tANI_U8 *) ssId, |
| (tANI_U8 *) &pMac->lim.gpLimMlmScanReq->ssId[i], |
| (tANI_U8) (pMac->lim.gpLimMlmScanReq->ssId[i].length + 1))) |
| { |
| return eANI_BOOLEAN_TRUE; |
| } |
| } |
| return eANI_BOOLEAN_FALSE; |
| } |
| |
| /** |
| * limCheckAndAddBssDescription() |
| * |
| *FUNCTION: |
| * This function is called during scan upon receiving |
| * Beacon/Probe Response frame to check if the received |
| * frame matches scan criteria, collect BSS description |
| * and add it to cached scan results. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBPR - Pointer to parsed Beacon/Probe Response structure |
| * @param pRxPacketInfo - Pointer to Received frame's BD |
| * @param fScanning - boolean to indicate whether the BSS is from current scan or just happen to receive a beacon |
| * |
| * @return None |
| */ |
| |
| void |
| limCheckAndAddBssDescription(tpAniSirGlobal pMac, |
| tpSirProbeRespBeacon pBPR, |
| tANI_U8 *pRxPacketInfo, |
| tANI_BOOLEAN fScanning, |
| tANI_U8 fProbeRsp) |
| { |
| tLimScanResultNode *pBssDescr; |
| tANI_U32 frameLen, ieLen = 0; |
| tANI_U8 rxChannelInBeacon = 0; |
| eHalStatus status; |
| tANI_U8 dontUpdateAll = 0; |
| tANI_U8 rfBand = 0; |
| tANI_U8 rxChannelInBD = 0; |
| |
| tSirMacAddr bssid = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
| tSirMacAddr bssid_zero = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; |
| tANI_BOOLEAN fFound = FALSE; |
| tpSirMacDataHdr3a pHdr; |
| |
| pHdr = WDA_GET_RX_MPDUHEADER3A((tANI_U8 *)pRxPacketInfo); |
| |
| // Check For Null BSSID; Skip in case of P2P. |
| if (vos_mem_compare(bssid_zero, &pHdr->addr3, 6)) |
| { |
| return ; |
| } |
| |
| //Checking if scanning for a particular BSSID |
| if ((fScanning) && (pMac->lim.gpLimMlmScanReq)) |
| { |
| fFound = vos_mem_compare(pHdr->addr3, &pMac->lim.gpLimMlmScanReq->bssId, 6); |
| if (!fFound) |
| { |
| if ((pMac->lim.gpLimMlmScanReq->p2pSearch) && |
| (vos_mem_compare(pBPR->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, |
| &pMac->lim.gpLimMlmScanReq->bssId, 6))) |
| { |
| fFound = eANI_BOOLEAN_TRUE; |
| } |
| } |
| } |
| |
| /** |
| * Compare SSID with the one sent in |
| * Probe Request frame, if any. |
| * If they don't match, ignore the |
| * Beacon frame. |
| * pMac->lim.gLimMlmScanReq->ssId.length == 0 |
| * indicates Broadcast SSID. |
| * When gLimReturnAfterFirstMatch is set, it means the scan has to match |
| * a SSID (if it is also set). Ignore the other BSS in that case. |
| */ |
| |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) |
| { |
| #endif |
| if ((pMac->lim.gpLimMlmScanReq) && |
| (((fScanning) && |
| ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) && |
| (pMac->lim.gpLimMlmScanReq->numSsid) && |
| !limIsScanRequestedSSID(pMac, &pBPR->ssId)) || |
| (!fFound && (pMac->lim.gpLimMlmScanReq) && |
| !vos_mem_compare(bssid, |
| &pMac->lim.gpLimMlmScanReq->bssId, 6)))) |
| { |
| /** |
| * Received SSID does not match with |
| * the one we're scanning for. |
| * Ignore received Beacon frame |
| */ |
| |
| return; |
| } |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| } |
| #endif |
| |
| /* There is no point in caching & reporting the scan results for APs |
| * which are in the process of switching the channel. So, we are not |
| * caching the scan results for APs which are adverzing the channel-switch |
| * element in their beacons and probe responses. |
| */ |
| if(pBPR->channelSwitchPresent) |
| { |
| return; |
| } |
| |
| /* If beacon/probe resp DS param channel does not match with |
| * RX BD channel then don't save the results. It might be a beacon |
| * from another channel heard as noise on the current scanning channel |
| */ |
| |
| if ((pBPR->dsParamsPresent) || (pBPR->HTInfo.present)) |
| { |
| /* This means that we are in 2.4GHz mode or 5GHz 11n mode */ |
| rxChannelInBeacon = limGetChannelFromBeacon(pMac, pBPR); |
| rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); |
| rxChannelInBD = WDA_GET_RX_CH(pRxPacketInfo); |
| |
| if ((!rfBand) || IS_5G_BAND(rfBand)) |
| { |
| rxChannelInBD = limUnmapChannel(rxChannelInBD); |
| } |
| |
| if(rxChannelInBD != rxChannelInBeacon) |
| { |
| /* BCAST Frame, if CH do not match, Drop */ |
| if(WDA_IS_RX_BCAST(pRxPacketInfo)) |
| { |
| limLog(pMac, LOG3, FL("Beacon/Probe Rsp dropped. Channel in BD %d. " |
| "Channel in beacon" " %d"), |
| WDA_GET_RX_CH(pRxPacketInfo),limGetChannelFromBeacon(pMac, pBPR)); |
| return; |
| } |
| /* Unit cast frame, Probe RSP, do not drop */ |
| else |
| { |
| dontUpdateAll = 1; |
| limLog(pMac, LOG3, FL("SSID %s, CH in ProbeRsp %d, CH in BD %d, miss-match, Do Not Drop"), |
| pBPR->ssId.ssId, |
| rxChannelInBeacon, |
| WDA_GET_RX_CH(pRxPacketInfo)); |
| WDA_GET_RX_CH(pRxPacketInfo) = rxChannelInBeacon; |
| } |
| } |
| } |
| |
| /** |
| * Allocate buffer to hold BSS description from |
| * received Beacon frame. |
| * Include size of fixed fields and IEs length |
| */ |
| |
| ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); |
| if (ieLen <= SIR_MAC_B_PR_SSID_OFFSET) |
| { |
| limLog(pMac, LOGP, |
| FL("RX packet has invalid length %d"), ieLen); |
| return; |
| } |
| |
| ieLen -= SIR_MAC_B_PR_SSID_OFFSET; |
| |
| frameLen = sizeof(tLimScanResultNode) + ieLen - sizeof(tANI_U32); //Sizeof(tANI_U32) is for ieFields[1] |
| |
| pBssDescr = vos_mem_malloc(frameLen); |
| if ( NULL == pBssDescr ) |
| { |
| // Log error |
| limLog(pMac, LOGP, |
| FL("call for AllocateMemory failed for storing BSS description")); |
| |
| return; |
| } |
| |
| vos_mem_zero(pBssDescr, frameLen); |
| |
| // In scan state, store scan result. |
| #if defined WLAN_FEATURE_VOWIFI |
| limCollectBssDescription(pMac, &pBssDescr->bssDescription, |
| pBPR, pRxPacketInfo, fScanning); |
| #else |
| limCollectBssDescription(pMac, &pBssDescr->bssDescription, |
| pBPR, pRxPacketInfo); |
| #endif |
| pBssDescr->bssDescription.fProbeRsp = fProbeRsp; |
| |
| pBssDescr->next = NULL; |
| |
| /** |
| * Depending on whether to store unique or all |
| * scan results, pass hash update/add parameter |
| * For LFR candidates just add them on it's own cache |
| */ |
| |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) |
| { |
| limLog(pMac, LOG1, FL(" pHdr->addr1:"MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pHdr->addr1)); |
| limLog(pMac, LOG1, FL(" pHdr->addr2:"MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pHdr->addr2)); |
| limLog(pMac, LOG1, FL(" pHdr->addr3:"MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pHdr->addr3)); |
| limLog( pMac, LOG1, FL("Save this entry in LFR cache")); |
| status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); |
| } |
| else |
| #endif |
| //If it is not scanning, only save unique results |
| if (pMac->lim.gLimReturnUniqueResults || (!fScanning)) |
| { |
| status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, dontUpdateAll); |
| } |
| else |
| { |
| status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); |
| } |
| |
| if(fScanning) |
| { |
| if ((pBssDescr->bssDescription.channelId <= 14) && |
| (pMac->lim.gLimReturnAfterFirstMatch & 0x40) && |
| pBPR->countryInfoPresent) |
| pMac->lim.gLim24Band11dScanDone = 1; |
| |
| if ((pBssDescr->bssDescription.channelId > 14) && |
| (pMac->lim.gLimReturnAfterFirstMatch & 0x80) && |
| pBPR->countryInfoPresent) |
| pMac->lim.gLim50Band11dScanDone = 1; |
| |
| if ( ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) || |
| ( pMac->lim.gLim24Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x40 ) ) || |
| ( pMac->lim.gLim50Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x80 ) ) || |
| fFound ) |
| { |
| /** |
| * Stop scanning and return the BSS description(s) |
| * collected so far. |
| */ |
| limLog(pMac, |
| LOGW, |
| FL("Completed scan: 24Band11dScan = %d, 50Band11dScan = %d BSS id"), |
| pMac->lim.gLim24Band11dScanDone, |
| pMac->lim.gLim50Band11dScanDone); |
| |
| //Need to disable the timers. If they fire, they will send END_SCAN |
| //while we already send FINISH_SCAN here. This may mess up the gLimHalScanState |
| limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); |
| limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); |
| //Set the resume channel to Any valid channel (invalid). |
| //This will instruct HAL to set it to any previous valid channel. |
| peSetResumeChannel(pMac, 0, 0); |
| limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); |
| //limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); |
| } |
| }//(eANI_BOOLEAN_TRUE == fScanning) |
| |
| if( eHAL_STATUS_SUCCESS != status ) |
| { |
| vos_mem_free( pBssDescr ); |
| } |
| } /****** end limCheckAndAddBssDescription() ******/ |
| |
| |
| |
| /** |
| * limScanHashFunction() |
| * |
| *FUNCTION: |
| * This function is called during scan hash entry operations |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param bssId - Received BSSid |
| * |
| * @return Hash index |
| */ |
| |
| tANI_U8 |
| limScanHashFunction(tSirMacAddr bssId) |
| { |
| tANI_U16 i, hash = 0; |
| |
| for (i = 0; i < sizeof(tSirMacAddr); i++) |
| hash += bssId[i]; |
| |
| return hash % LIM_MAX_NUM_OF_SCAN_RESULTS; |
| } /****** end limScanHashFunction() ******/ |
| |
| |
| |
| /** |
| * limInitHashTable() |
| * |
| *FUNCTION: |
| * This function is called upon receiving SME_START_REQ |
| * to initialize global cached scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limInitHashTable(tpAniSirGlobal pMac) |
| { |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| pMac->lim.gLimCachedScanHashTable[i] = NULL; |
| } /****** end limInitHashTable() ******/ |
| |
| |
| |
| /** |
| * limLookupNaddHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon receiving a Beacon or |
| * Probe Response frame during scan phase to store |
| * received BSS description into scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBssDescr - Pointer to BSS description to be |
| * added to the scan result hash table. |
| * @param action - Indicates action to be performed |
| * when same BSS description is found. This is |
| * dependent on whether unique scan result to |
| * be stored or not. |
| * |
| * @return None |
| */ |
| |
| eHalStatus |
| limLookupNaddHashEntry(tpAniSirGlobal pMac, |
| tLimScanResultNode *pBssDescr, tANI_U8 action, |
| tANI_U8 dontUpdateAll) |
| { |
| tANI_U8 index, ssidLen = 0; |
| tANI_U8 found = false; |
| tLimScanResultNode *ptemp, *pprev; |
| tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; |
| int idx, len; |
| tANI_U8 *pbIe; |
| tANI_S8 rssi = 0; |
| tANI_S8 rssi_raw = 0; |
| |
| index = limScanHashFunction(pBssDescr->bssDescription.bssId); |
| ptemp = pMac->lim.gLimCachedScanHashTable[index]; |
| |
| //ieFields start with TLV of SSID IE |
| ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); |
| pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; |
| |
| for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) |
| { |
| //For infrastructure, check BSSID and SSID. For IBSS, check more |
| pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; |
| if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first |
| (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, |
| (tANI_U8 *) ptemp->bssDescription.bssId, |
| sizeof(tSirMacAddr))) && //matching BSSID |
| // matching band to update new channel info |
| (vos_chan_to_band(pBssDescr->bssDescription.channelId) == |
| vos_chan_to_band(ptemp->bssDescription.channelId)) && |
| vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), |
| ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), |
| (tANI_U8) (ssidLen + 1)) && |
| ((pSirCapTemp->ess) || //we are done for infrastructure |
| //For IBSS, nwType and channelId |
| (((pBssDescr->bssDescription.nwType == |
| ptemp->bssDescription.nwType) && |
| (pBssDescr->bssDescription.channelId == |
| ptemp->bssDescription.channelId)))) |
| ) |
| { |
| if (ptemp->bssDescription.fProbeRsp && |
| !pBssDescr->bssDescription.fProbeRsp) |
| { |
| /* If the previously saved frame is probe response |
| * and the current frame is beacon, then no need |
| * to update the scan database. Probe response is |
| * going to have more proper information than beacon |
| * frame. So it is better to inform the probe |
| * response frame instead of beacon for proper |
| * information. */ |
| return eHAL_STATUS_FAILURE; |
| } |
| // Found the same BSS description |
| if (action == LIM_HASH_UPDATE) |
| { |
| if(dontUpdateAll) |
| { |
| rssi = ptemp->bssDescription.rssi; |
| rssi_raw = ptemp->bssDescription.rssi_raw; |
| } |
| |
| if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) |
| { |
| //We get a different, save the old frame WSC IE if it is there |
| idx = 0; |
| len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + |
| sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; |
| pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; |
| //Save WPS IE if it exists |
| pBssDescr->bssDescription.WscIeLen = 0; |
| while(idx < len) |
| { |
| if((DOT11F_EID_WSCPROBERES == pbIe[0]) && |
| (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) |
| { |
| //Found it |
| if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) |
| { |
| vos_mem_copy(pBssDescr->bssDescription.WscIeProbeRsp, |
| pbIe, pbIe[1] + 2); |
| pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; |
| } |
| break; |
| } |
| idx += pbIe[1] + 2; |
| pbIe += pbIe[1] + 2; |
| } |
| } |
| |
| |
| if(NULL != pMac->lim.gpLimMlmScanReq) |
| { |
| if((pMac->lim.gpLimMlmScanReq->numSsid)&& |
| ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) |
| &pBssDescr->bssDescription.ieFields + 1)))) |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| // Delete this entry |
| if (ptemp == pMac->lim.gLimCachedScanHashTable[index]) |
| pprev = pMac->lim.gLimCachedScanHashTable[index] = ptemp->next; |
| else |
| pprev->next = ptemp->next; |
| |
| pMac->lim.gLimMlmScanResultLength -= |
| ptemp->bssDescription.length + sizeof(tANI_U16); |
| |
| vos_mem_free(ptemp); |
| } |
| found = true; |
| break; |
| } |
| } |
| |
| //for now, only rssi, we can add more if needed |
| if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi && rssi_raw) |
| { |
| pBssDescr->bssDescription.rssi = rssi; |
| pBssDescr->bssDescription.rssi_raw = rssi_raw; |
| } |
| |
| // Add this BSS description at same index |
| if (pprev == pMac->lim.gLimCachedScanHashTable[index]) |
| { |
| pBssDescr->next = pMac->lim.gLimCachedScanHashTable[index]; |
| pMac->lim.gLimCachedScanHashTable[index] = pBssDescr; |
| } |
| else |
| { |
| pBssDescr->next = pprev->next; |
| pprev->next = pBssDescr; |
| } |
| pMac->lim.gLimMlmScanResultLength += |
| pBssDescr->bssDescription.length + sizeof(tANI_U16); |
| |
| PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id"), |
| pBssDescr->bssDescription.length, |
| pMac->lim.gLimMlmScanResultLength); |
| limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) |
| |
| // Send new BSS found indication to HDD if CFG option is set |
| if (!found) limSendSmeNeighborBssInd(pMac, pBssDescr); |
| |
| // |
| // TODO: IF applicable, do we need to send: |
| // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF |
| // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP |
| // |
| return eHAL_STATUS_SUCCESS; |
| } |
| |
| |
| |
| /** |
| * limDeleteHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon to delete |
| * a BSS description from scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * Yet to find the utility of the function |
| * |
| * @param pBssDescr - Pointer to BSS description to be |
| * deleted from the scan result hash table. |
| * |
| * @return None |
| */ |
| |
| void limDeleteHashEntry(tLimScanResultNode *pBssDescr) |
| { |
| } /****** end limDeleteHashEntry() ******/ |
| |
| |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| /** |
| * limInitLfrHashTable() |
| * |
| *FUNCTION: |
| * This function is called upon receiving SME_START_REQ |
| * to initialize global cached Lfr scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limInitLfrHashTable(tpAniSirGlobal pMac) |
| { |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| pMac->lim.gLimCachedLfrScanHashTable[i] = NULL; |
| } /****** end limInitLfrHashTable() ******/ |
| |
| |
| |
| /** |
| * limLookupNaddLfrHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon receiving a Beacon or |
| * Probe Response frame during Lfr scan phase from FW to store |
| * received BSS description into Lfr scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pBssDescr - Pointer to BSS description to be |
| * added to the Lfr scan result hash table. |
| * @param action - Indicates action to be performed |
| * when same BSS description is found. This is |
| * dependent on whether unique scan result to |
| * be stored or not. |
| * |
| * @return None |
| */ |
| |
| eHalStatus |
| limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, |
| tLimScanResultNode *pBssDescr, tANI_U8 action, |
| tANI_U8 dontUpdateAll) |
| { |
| tANI_U8 index, ssidLen = 0; |
| tLimScanResultNode *ptemp, *pprev; |
| tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; |
| int idx, len; |
| tANI_U8 *pbIe; |
| tANI_S8 rssi = 0; |
| tANI_S8 rssi_raw = 0; |
| |
| index = limScanHashFunction(pBssDescr->bssDescription.bssId); |
| ptemp = pMac->lim.gLimCachedLfrScanHashTable[index]; |
| |
| //ieFields start with TLV of SSID IE |
| ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); |
| pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; |
| |
| for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) |
| { |
| //For infrastructure, check BSSID and SSID. For IBSS, check more |
| pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; |
| if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first |
| (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, |
| (tANI_U8 *) ptemp->bssDescription.bssId, |
| sizeof(tSirMacAddr))) && //matching BSSID |
| (pBssDescr->bssDescription.channelId == |
| ptemp->bssDescription.channelId) && |
| vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), |
| ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), |
| (tANI_U8) (ssidLen + 1)) && |
| ((pSirCapTemp->ess) || //we are done for infrastructure |
| //For IBSS, nwType and channelId |
| (((pBssDescr->bssDescription.nwType == |
| ptemp->bssDescription.nwType) && |
| (pBssDescr->bssDescription.channelId == |
| ptemp->bssDescription.channelId)))) |
| ) |
| { |
| // Found the same BSS description |
| if (action == LIM_HASH_UPDATE) |
| { |
| if(dontUpdateAll) |
| { |
| rssi = ptemp->bssDescription.rssi; |
| rssi_raw = ptemp->bssDescription.rssi_raw; |
| } |
| |
| if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) |
| { |
| //We get a different, save the old frame WSC IE if it is there |
| idx = 0; |
| len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + |
| sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; |
| pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; |
| //Save WPS IE if it exists |
| pBssDescr->bssDescription.WscIeLen = 0; |
| while(idx < len) |
| { |
| if((DOT11F_EID_WSCPROBERES == pbIe[0]) && |
| (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && |
| (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) |
| { |
| //Found it |
| if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) |
| { |
| vos_mem_copy( pBssDescr->bssDescription.WscIeProbeRsp, |
| pbIe, pbIe[1] + 2); |
| pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; |
| } |
| break; |
| } |
| idx += pbIe[1] + 2; |
| pbIe += pbIe[1] + 2; |
| } |
| } |
| |
| |
| if(NULL != pMac->lim.gpLimMlmScanReq) |
| { |
| if((pMac->lim.gpLimMlmScanReq->numSsid)&& |
| ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) |
| &pBssDescr->bssDescription.ieFields + 1)))) |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| // Delete this entry |
| if (ptemp == pMac->lim.gLimCachedLfrScanHashTable[index]) |
| pprev = pMac->lim.gLimCachedLfrScanHashTable[index] = ptemp->next; |
| else |
| pprev->next = ptemp->next; |
| |
| pMac->lim.gLimMlmLfrScanResultLength -= |
| ptemp->bssDescription.length + sizeof(tANI_U16); |
| |
| vos_mem_free(ptemp); |
| } |
| break; |
| } |
| } |
| |
| //for now, only rssi, we can add more if needed |
| if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi && rssi_raw) |
| { |
| pBssDescr->bssDescription.rssi = rssi; |
| pBssDescr->bssDescription.rssi_raw = rssi_raw; |
| } |
| |
| // Add this BSS description at same index |
| if (pprev == pMac->lim.gLimCachedLfrScanHashTable[index]) |
| { |
| pBssDescr->next = pMac->lim.gLimCachedLfrScanHashTable[index]; |
| pMac->lim.gLimCachedLfrScanHashTable[index] = pBssDescr; |
| } |
| else |
| { |
| pBssDescr->next = pprev->next; |
| pprev->next = pBssDescr; |
| } |
| pMac->lim.gLimMlmLfrScanResultLength += |
| pBssDescr->bssDescription.length + sizeof(tANI_U16); |
| |
| PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"), |
| pBssDescr->bssDescription.length, |
| pMac->lim.gLimMlmLfrScanResultLength); |
| limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) |
| |
| // |
| // TODO: IF applicable, do we need to send: |
| // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF |
| // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP |
| // |
| return eHAL_STATUS_SUCCESS; |
| } |
| |
| |
| |
| /** |
| * limDeleteLfrHashEntry() |
| * |
| *FUNCTION: |
| * This function is called upon to delete |
| * a BSS description from LFR scan result hash table. |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * Yet to find the utility of the function |
| * |
| * @param pBssDescr - Pointer to BSS description to be |
| * deleted from the LFR scan result hash table. |
| * |
| * @return None |
| */ |
| |
| void limDeleteLfrHashEntry(tLimScanResultNode *pBssDescr) |
| { |
| } /****** end limDeleteLfrHashEntry() ******/ |
| |
| #endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| |
| /** |
| * limCopyScanResult() |
| * |
| *FUNCTION: |
| * This function is called by limProcessSmeMessages() while |
| * sending SME_SCAN_RSP with scan result to HDD. |
| * |
| *LOGIC: |
| * This function traverses the scan list stored in scan hash table |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param pDest - Destination pointer |
| * |
| * @return None |
| */ |
| |
| void |
| limCopyScanResult(tpAniSirGlobal pMac, tANI_U8 *pDest) |
| { |
| tLimScanResultNode *ptemp; |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((ptemp = pMac->lim.gLimCachedScanHashTable[i]) != NULL) |
| { |
| while(ptemp) |
| { |
| /// Copy entire BSS description including length |
| vos_mem_copy( pDest, |
| (tANI_U8 *) &ptemp->bssDescription, |
| ptemp->bssDescription.length + 2); |
| pDest += ptemp->bssDescription.length + 2; |
| ptemp = ptemp->next; |
| } |
| } |
| } |
| } /****** end limCopyScanResult() ******/ |
| |
| |
| |
| /** |
| * limDeleteCachedScanResults() |
| * |
| *FUNCTION: |
| * This function is called by limProcessSmeMessages() upon receiving |
| * SME_SCAN_REQ with fresh scan result flag set. |
| * |
| *LOGIC: |
| * This function traverses the scan list stored in scan hash table |
| * and deletes the entries if any |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limDeleteCachedScanResults(tpAniSirGlobal pMac) |
| { |
| tLimScanResultNode *pNode, *pNextNode; |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) |
| { |
| while (pNode) |
| { |
| pNextNode = pNode->next; |
| |
| // Delete the current node |
| vos_mem_free(pNode); |
| |
| pNode = pNextNode; |
| } |
| } |
| } |
| |
| pMac->lim.gLimSmeScanResultLength = 0; |
| } /****** end limDeleteCachedScanResults() ******/ |
| |
| /** |
| * limFlushp2pScanResults() |
| * |
| *FUNCTION: |
| * This function is called before scan to flush the |
| * the p2p scan entries from LIM |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limFlushp2pScanResults(tpAniSirGlobal pMac) |
| { |
| tLimScanResultNode *pNode, *pNextNode, *pPrev, *pHead, *pTemp; |
| tANI_U16 i; |
| tANI_U8 *pSsidStr; |
| tSirMacSSid *pSsid; |
| |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) |
| { |
| pPrev = pNode; |
| pHead = pNode; |
| while (pNode) |
| { |
| pSsid = (tSirMacSSid *)((tANI_U8 *)&pNode->bssDescription.ieFields + 1); |
| pSsidStr = pSsid->ssId; |
| if (vos_mem_compare(pSsidStr, "DIRECT-", 7)) |
| { |
| if (pNode == pHead) |
| { |
| pTemp = pNode; |
| pNode = pNode->next; |
| pMac->lim.gLimSmeScanResultLength -= |
| (pTemp->bssDescription.length + |
| sizeof(pTemp->bssDescription.length)); |
| pPrev = pNode; |
| pHead = pNode; |
| vos_mem_free(pTemp); |
| pMac->lim.gLimCachedScanHashTable[i]= pHead; |
| } |
| else |
| { |
| pNextNode = pNode->next; |
| pMac->lim.gLimSmeScanResultLength -= |
| (pNode->bssDescription.length + |
| sizeof(pNode->bssDescription.length)); |
| vos_mem_free(pNode); |
| pPrev->next = pNextNode; |
| pNode = pNextNode; |
| } |
| } |
| else |
| { |
| pPrev = pNode; |
| pNode = pNode->next; |
| } |
| } |
| } |
| } |
| } /****** end limFlushp2pScanResults() ******/ |
| |
| /** |
| * limReInitScanResults() |
| * |
| *FUNCTION: |
| * This function is called delete exisiting scan results |
| * and initialize the scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limReInitScanResults(tpAniSirGlobal pMac) |
| { |
| limLog(pMac, LOG1, FL("Re initialize scan hash table.")); |
| limDeleteCachedScanResults(pMac); |
| limInitHashTable(pMac); |
| |
| // !!LAC - need to clear out the global scan result length |
| // since the list was just purged from the hash table. |
| pMac->lim.gLimMlmScanResultLength = 0; |
| |
| } /****** end limReInitScanResults() ******/ |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| /** |
| * limDeleteCachedLfrScanResults() |
| * |
| *FUNCTION: |
| * This function is called by limProcessSmeMessages() upon receiving |
| * SME_SCAN_REQ with flush scan result flag set for LFR. |
| * |
| *LOGIC: |
| * This function traverses the scan list stored in lfr scan hash |
| * table and deletes the entries if any |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limDeleteCachedLfrScanResults(tpAniSirGlobal pMac) |
| { |
| tLimScanResultNode *pNode, *pNextNode; |
| tANI_U16 i; |
| for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) |
| { |
| if ((pNode = pMac->lim.gLimCachedLfrScanHashTable[i]) != NULL) |
| { |
| while (pNode) |
| { |
| pNextNode = pNode->next; |
| |
| // Delete the current node |
| vos_mem_free(pNode); |
| |
| pNode = pNextNode; |
| } |
| } |
| } |
| |
| pMac->lim.gLimSmeLfrScanResultLength = 0; |
| } /****** end limDeleteCachedLfrScanResults() ******/ |
| |
| |
| |
| /** |
| * limReInitLfrScanResults() |
| * |
| *FUNCTION: |
| * This function is called delete exisiting scan results |
| * and initialize the lfr scan hash table |
| * |
| *LOGIC: |
| * |
| *ASSUMPTIONS: |
| * NA |
| * |
| *NOTE: |
| * NA |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return None |
| */ |
| |
| void |
| limReInitLfrScanResults(tpAniSirGlobal pMac) |
| { |
| limLog(pMac, LOG1, FL("Re initialize lfr scan hash table.")); |
| limDeleteCachedLfrScanResults(pMac); |
| limInitLfrHashTable(pMac); |
| |
| // !!LAC - need to clear out the global scan result length |
| // since the list was just purged from the hash table. |
| pMac->lim.gLimMlmLfrScanResultLength = 0; |
| |
| } /****** end limReInitLfrScanResults() ******/ |
| #endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD |