diff options
| author | Abhishek Singh <absingh@qti.qualcomm.com> | 2016-04-14 17:02:15 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-18 12:57:22 +0530 |
| commit | 72e4dba10c62bd969775c3f047bf7ab6442b012c (patch) | |
| tree | e44516e0e767ec404ae0ad3a3de29943800dcb3d | |
| parent | 2212e8cd27edf8fd2d77b7e23ec6b127473897f6 (diff) | |
qcacld-2.0: If parsing fails for the beacon after connect, parse TIM IE.
prima to qcacld-2.0 propagation
In case AP is sending malformed beacons, the currunt firmware drops
it and thus Host does not receive any beacon after the connection.
Due to this Host could not enter the BMPS and battery is drained.
To avoid this, now the firmware will send the first beacon to host
even if it is malformed but have the TIM IE.
To handle these malformed beacons in the host, even if parsing
fails, try to extract the TIM params and timestamp from the beacon,
required to enter BMPS.
Change-Id: Id4a22f45614224fc04c55f22831a3227c1dbabb1
CRs-Fixed: 782493
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessBeaconFrame.c | 6 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limUtils.c | 61 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limUtils.h | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/sch/schBeaconProcess.c | 4 |
4 files changed, 72 insertions, 1 deletions
diff --git a/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c b/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c index eff17d221f5b..9bc63fe6fdb0 100644 --- a/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2013, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -124,6 +124,10 @@ limProcessBeaconFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession ps FL("Received invalid Beacon in state %X"), psessionEntry->limMlmState); limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + if ((!psessionEntry->currentBssBeaconCnt) && + (sirCompareMacAddr(psessionEntry->bssId, pHdr->sa))) + lim_parse_beacon_for_tim(pMac, + pRxPacketInfo, psessionEntry); vos_mem_free(pBeacon); return; } diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c index a0b90c746a48..156c2c795ef2 100644 --- a/CORE/MAC/src/pe/lim/limUtils.c +++ b/CORE/MAC/src/pe/lim/limUtils.c @@ -98,6 +98,11 @@ static const tANI_U8 aUnsortedChannelList[]= {52,56,60,64,100,104,108,112,116, #define SUCCESS 1 +#define MAX_DTIM_PERIOD 15 +#define MAX_DTIM_COUNT 15 +#define DTIM_PERIOD_DEFAULT 1 +#define DTIM_COUNT_DEFAULT 1 + #define MAX_BA_WINDOW_SIZE_FOR_CISCO 25 /** ------------------------------------------------------------- @@ -8789,3 +8794,59 @@ void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx, } } +/* + * lim_parse_beacon_for_tim() - Extract TIM and beacon timestamp + * from beacon frame. + * @mac_ctx: mac context + * @rx_packet_info: beacon frame + * @session: Session on which beacon is received + * + * This function is used if beacon is corrupted and parser API fails to + * parse the whole beacon. Try to extract the TIM params and timestamp + * from the beacon, required to enter BMPS + * + * Return: void + */ +void lim_parse_beacon_for_tim(tpAniSirGlobal mac_ctx, + uint8_t* rx_packet_info, tpPESession session) +{ + uint32_t frame_len; + uint8_t *frame; + uint8_t *ie_ptr; + tSirMacTim *tim; + + frame = WDA_GET_RX_MPDU_DATA(rx_packet_info); + frame_len = WDA_GET_RX_PAYLOAD_LEN(rx_packet_info); + + if (frame_len < (SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN)) { + limLog(mac_ctx, LOGE, FL("Beacon length too short to parse")); + return; + } + + ie_ptr = lim_get_ie_ptr((frame + SIR_MAC_B_PR_SSID_OFFSET), + frame_len, SIR_MAC_TIM_EID); + + if (NULL != ie_ptr) { + /* Ignore EID and Length field */ + tim = (tSirMacTim *)(ie_ptr + IE_LEN_SIZE + IE_EID_SIZE); + + vos_mem_copy((uint8_t*)&session->lastBeaconTimeStamp, + (uint8_t*)frame, sizeof(uint64_t)); + if (tim->dtimCount >= MAX_DTIM_COUNT) + tim->dtimCount = DTIM_COUNT_DEFAULT; + if (tim->dtimPeriod >= MAX_DTIM_PERIOD) + tim->dtimPeriod = DTIM_PERIOD_DEFAULT; + session->lastBeaconDtimCount = tim->dtimCount; + session->lastBeaconDtimPeriod = tim->dtimPeriod; + session->currentBssBeaconCnt++; + + limLog(mac_ctx, LOG1, + FL("currentBssBeaconCnt %d lastBeaconDtimCount %d lastBeaconDtimPeriod %d"), + session->currentBssBeaconCnt, + session->lastBeaconDtimCount, + session->lastBeaconDtimPeriod); + + } + return; +} + diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h index 3bc93143add7..e9d760975575 100644 --- a/CORE/MAC/src/pe/lim/limUtils.h +++ b/CORE/MAC/src/pe/lim/limUtils.h @@ -670,5 +670,7 @@ bool lim_is_ext_cap_ie_present (struct s_ext_cap *ext_cap); bool lim_is_robust_mgmt_action_frame(uint8_t action_catagory); void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx, uint16_t *caps, uint16_t bss_caps); +void lim_parse_beacon_for_tim(tpAniSirGlobal mac_ctx, uint8_t* rx_packet_info, + tpPESession session); #endif /* __LIM_UTILS_H */ diff --git a/CORE/MAC/src/pe/sch/schBeaconProcess.c b/CORE/MAC/src/pe/sch/schBeaconProcess.c index afd1e9682a27..ef0e9f806301 100644 --- a/CORE/MAC/src/pe/sch/schBeaconProcess.c +++ b/CORE/MAC/src/pe/sch/schBeaconProcess.c @@ -757,6 +757,10 @@ void schBeaconProcess(tpAniSirGlobal pMac, tANI_U8* pRxPacketInfo, tpPESession p { PELOGE(schLog(pMac, LOGE, FL("beacon parsing failed"));) pMac->sch.gSchBcnParseErrorCnt++; + if ((NULL != psessionEntry) && + (!psessionEntry->currentBssBeaconCnt)) + lim_parse_beacon_for_tim(pMac, + pRxPacketInfo, psessionEntry); return; } |
