Home | History | Annotate | Download | only in Sta_Management
      1 /*
      2  * mlmeParser.c
      3  *
      4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  *  * Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *  * Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *  * Neither the name Texas Instruments nor the names of its
     18  *    contributors may be used to endorse or promote products derived
     19  *    from this software without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34  /** \file mlmeBuilder.c
     35  *  \brief 802.11 MLME Parser
     36  *
     37  *  \see mlmeParser.h
     38  */
     39 
     40 
     41 /***************************************************************************/
     42 /*                                                                         */
     43 /*      MODULE: mlmeParser.c                                              */
     44 /*    PURPOSE:  802.11 MLME Parser                                        */
     45 /*                                                                         */
     46 /***************************************************************************/
     47 
     48 
     49 
     50 #define __FILE_ID__  FILE_ID_68
     51 #include "osApi.h"
     52 #include "paramOut.h"
     53 #include "report.h"
     54 #include "DataCtrl_Api.h"
     55 #include "smeApi.h"
     56 #include "mlmeApi.h"
     57 #include "mlmeSm.h"
     58 #include "AssocSM.h"
     59 #include "authSm.h"
     60 #include "mlmeParser.h"
     61 #include "measurementMgrApi.h"
     62 #include "ScanCncn.h"
     63 #include "siteMgrApi.h"
     64 #include "spectrumMngmntMgr.h"
     65 #include "currBss.h"
     66 #include "apConn.h"
     67 #include "SwitchChannelApi.h"
     68 #include "regulatoryDomainApi.h"
     69 #include "qosMngr_API.h"
     70 #include "scanResultTable.h"
     71 #include "RxBuf.h"
     72 
     73 
     74 /* Constants */
     75 
     76 /* Enumerations */
     77 
     78 /* Typedefs */
     79 
     80 /* Structures */
     81 
     82 /* External data definitions */
     83 
     84 /* External functions definitions */
     85 
     86 /* Local function prototypes */
     87 
     88 /* Functions */
     89 
     90 #define CHECK_PARSING_ERROR_CONDITION_PRINT 0
     91 
     92 extern int WMEQosTagToACTable[MAX_NUM_OF_802_1d_TAGS];
     93 
     94 TI_STATUS mlmeParser_recv(TI_HANDLE hMlme, void *pBuffer, TRxAttr* pRxAttr)
     95 {
     96     TI_STATUS              status;
     97     mlme_t                 *pHandle = (mlme_t *)hMlme;
     98     TI_UINT8               *pData;
     99     TI_INT32               bodyDataLen;
    100     TI_UINT32              readLen;
    101     dot11_eleHdr_t         *pEleHdr;
    102     dot11_mgmtFrame_t      *pMgmtFrame;
    103     dot11MgmtSubType_e     msgType;
    104     paramInfo_t            *pParam;
    105     TMacAddr               recvBssid;
    106     TMacAddr               recvSa;
    107     TI_UINT8               rsnIeIdx = 0;
    108     TI_UINT8               wpaIeOuiIe[] = WPA_IE_OUI;
    109 #ifdef XCC_MODULE_INCLUDED
    110 	TI_UINT8			   XCC_oui[] = XCC_OUI;
    111 	XCCv4IEs_t			   *pXCCIeParameter;
    112 #endif
    113     TI_BOOL				   ciscoIEPresent = TI_FALSE;
    114 
    115     if ((hMlme == NULL) || (pBuffer == NULL))
    116     {
    117         WLAN_OS_REPORT (("mlmeParser_recv: hMlme == %x, buf = %x\n", hMlme, pBuffer));
    118 		return TI_NOK;
    119     }
    120 
    121     /* zero frame content */
    122 	os_memoryZero (pHandle->hOs, &(pHandle->tempFrameInfo), sizeof(mlmeIEParsingParams_t));
    123 
    124     pMgmtFrame = (dot11_mgmtFrame_t*)RX_BUF_DATA(pBuffer);
    125 
    126     /* get frame type */
    127     status = mlmeParser_getFrameType(pHandle, (TI_UINT16 *)&pMgmtFrame->hdr.fc, &msgType);
    128     if (status != TI_OK)
    129     {
    130         RxBufFree(pHandle->hOs, pBuffer);
    131         return TI_NOK;
    132     }
    133 
    134     pParam = (paramInfo_t *)os_memoryAlloc(pHandle->hOs, sizeof(paramInfo_t));
    135     if (!pParam)
    136 	{
    137         RxBufFree(pHandle->hOs, pBuffer);
    138         return TI_NOK;
    139     }
    140 
    141     pHandle->tempFrameInfo.frame.subType = msgType;
    142 
    143     /* We have to ignore management frames from other BSSIDs (except beacons & probe responses) */
    144     pParam->paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
    145     ctrlData_getParam(pHandle->hCtrlData, pParam);
    146 
    147     MAC_COPY (recvBssid, pMgmtFrame->hdr.BSSID);
    148     MAC_COPY(recvSa, pMgmtFrame->hdr.SA);
    149 
    150     if (MAC_EQUAL (pParam->content.ctrlDataCurrentBSSID, recvBssid))
    151         pHandle->tempFrameInfo.myBssid = TI_TRUE;
    152     else
    153         pHandle->tempFrameInfo.myBssid = TI_FALSE;
    154 
    155 
    156     if (MAC_EQUAL (pParam->content.ctrlDataCurrentBSSID, recvSa))
    157 		pHandle->tempFrameInfo.mySa = TI_TRUE;
    158 	else
    159 		pHandle->tempFrameInfo.mySa = TI_FALSE;
    160 
    161 	/* The Default value of the myDst flag is false, only in case of unicast packet with the STA's destination address, the flag is set to True */
    162 	pHandle->tempFrameInfo.myDst = TI_FALSE;
    163 
    164 
    165     /* check destination MAC address for broadcast */
    166 
    167     if (MAC_BROADCAST (pMgmtFrame->hdr.DA))
    168     {
    169         pHandle->tempFrameInfo.frame.extesion.destType = MSG_BROADCAST;
    170     }
    171         else
    172         {
    173         if (MAC_MULTICAST (pMgmtFrame->hdr.DA))
    174         {
    175             pHandle->tempFrameInfo.frame.extesion.destType = MSG_MULTICAST;
    176         }
    177         else
    178         {
    179             pHandle->tempFrameInfo.frame.extesion.destType = MSG_UNICAST;
    180 			pParam->paramType = CTRL_DATA_MAC_ADDRESS;
    181 		    ctrlData_getParam(pHandle->hCtrlData, pParam);
    182 
    183 			/* Verifying whether the received unicast packet is for the STA, if yes we set the flag to True */
    184 			if (MAC_EQUAL( (pParam->content.ctrlDataDeviceMacAddress), (pMgmtFrame->hdr.DA) ))
    185 				pHandle->tempFrameInfo.myDst = TI_TRUE;
    186 
    187         }
    188     }
    189 
    190     MAC_COPY (pHandle->tempFrameInfo.bssid, pMgmtFrame->hdr.BSSID);
    191 
    192     pData = (TI_UINT8 *)(pMgmtFrame->body);
    193 
    194     /* length of body (BUF without 802.11 header and FCS) */
    195     bodyDataLen = RX_BUF_LEN(pBuffer) - WLAN_HDR_LEN;
    196 
    197     switch (msgType)
    198     {
    199     case ASSOC_REQUEST:
    200         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "MLME_PARSER: recieved ASSOC_REQ message \n");
    201         break;
    202     case RE_ASSOC_REQUEST:
    203         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "MLME_PARSER: recieved RE_ASSOC_REQ message \n");
    204         break;
    205     case RE_ASSOC_RESPONSE:
    206         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "MLME_PARSER: recieved RE_ASSOC_RSP message \n");
    207       /*  break;*/
    208     case ASSOC_RESPONSE:
    209 		/* if the assoc response is not directed to our STA or not from the current AP */
    210         if ((!pHandle->tempFrameInfo.myBssid) || (!pHandle->tempFrameInfo.mySa) || (pHandle->tempFrameInfo.myDst == TI_FALSE))
    211             break;
    212 
    213         /* Save the association response message */
    214         assoc_saveAssocRespMessage(pHandle->hAssoc, (TI_UINT8 *)(pMgmtFrame->body), bodyDataLen);
    215 
    216         /* init frame fields */
    217         pHandle->tempFrameInfo.frame.content.assocRsp.barkerPreambleMode = PREAMBLE_UNSPECIFIED;
    218 
    219         /* read capabilities */
    220 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.assocRsp.capabilities , pData);
    221         pData += 2;
    222         /* read status */
    223 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.assocRsp.status , pData);
    224         pData += 2;
    225         /* read AID */
    226 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.assocRsp.aid , pData);
    227         pHandle->tempFrameInfo.frame.content.assocRsp.aid &= ASSOC_RESP_AID_MASK;
    228         pData += 2;
    229 
    230         bodyDataLen -= ASSOC_RESP_FIXED_DATA_LEN;
    231         /***************************/
    232 
    233         pHandle->tempFrameInfo.frame.content.assocRsp.pRsnIe = NULL;
    234         pHandle->tempFrameInfo.frame.content.assocRsp.rsnIeLen = 0;
    235         while (bodyDataLen > 2)
    236         {
    237             pEleHdr = (dot11_eleHdr_t*)pData;
    238 
    239             if ((*pEleHdr)[1] > (bodyDataLen - 2))
    240             {
    241                 TRACE3(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: IE %d with length %d out of bounds %d\n", (*pEleHdr)[0], (*pEleHdr)[1], (bodyDataLen - 2));
    242                 status = TI_NOK;
    243                 goto mlme_recv_end;
    244             }
    245 
    246             switch ((*pEleHdr)[0])
    247             {
    248                         /* read rates */
    249             case SUPPORTED_RATES_IE_ID:
    250                 pHandle->tempFrameInfo.frame.content.assocRsp.pRates = &(pHandle->tempFrameInfo.rates);
    251                 status = mlmeParser_readRates(pHandle, pData, bodyDataLen, &readLen, &(pHandle->tempFrameInfo.rates));
    252                 if (status != TI_OK)
    253                 {
    254                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading RATES\n");
    255                     goto mlme_recv_end;
    256                 }
    257                 break;
    258 
    259             case EXT_SUPPORTED_RATES_IE_ID:
    260                 /* read rates */
    261                 pHandle->tempFrameInfo.frame.content.assocRsp.pExtRates = &(pHandle->tempFrameInfo.extRates);
    262                 status = mlmeParser_readRates(pHandle, pData, bodyDataLen, &readLen, &(pHandle->tempFrameInfo.extRates));
    263                 if (status != TI_OK)
    264                 {
    265                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading RATES\n");
    266                     goto mlme_recv_end;
    267                 }
    268                 break;
    269 
    270             case WPA_IE_ID:
    271                 /* Note : WPA, WME, TSRS and msdu lifetime use the same Element ID */
    272                 /*  Its assumes that:
    273                         TSRS and msdu lifetime use OUI = 0x00,0x40,0x96 (=Cisco) but
    274                         use different OUI Type:
    275                             TSRS          uses OUI Type 8
    276                             msdu lifetime uses OUI Type 9;
    277                         WPA and WME use the same OUI = 0x00,0x50,0xf2 but
    278                         use different OUI Type:
    279                             WPA - uses OUI Type with value  - 1
    280                             WME - uses OUI Type with value  - 2.
    281                 */
    282 
    283                 /* check if this is WME IE */
    284                 if((os_memoryCompare(pHandle->hOs, wpaIeOuiIe, pData+2, DOT11_OUI_LEN - 1) == 0) &&
    285 						((*(TI_UINT8*)(pData+5)) == dot11_WME_OUI_TYPE))
    286                 {
    287                     pHandle->tempFrameInfo.frame.content.assocRsp.WMEParams = &(pHandle->tempFrameInfo.WMEParams);
    288                     status = mlmeParser_readWMEParams(pHandle, pData, bodyDataLen, &readLen,
    289                                                       &(pHandle->tempFrameInfo.WMEParams),
    290 													  &(pHandle->tempFrameInfo.frame.content.assocRsp));
    291                     if (status != TI_OK)
    292                     {
    293                         TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading WME parameters\n");
    294                         goto mlme_recv_end;
    295                     }
    296                 }
    297 #ifdef XCC_MODULE_INCLUDED
    298 				/* check if this is XCC vendor specific OUI */
    299 				else if (os_memoryCompare(pHandle->hOs, XCC_oui, pData+2, DOT11_OUI_LEN - 1) == 0)
    300 				{
    301 					pXCCIeParameter = &(pHandle->tempFrameInfo.frame.content.assocRsp.XCCIEs[WMEQosTagToACTable[*(pData+6)]]);
    302 					mlmeParser_readXCCOui(pData, bodyDataLen, &readLen, pXCCIeParameter);
    303 				}
    304 #endif
    305 				else
    306                 {
    307                     /* skip this IE */
    308                     readLen = (*pEleHdr)[1] + 2;
    309                 }
    310                 break;
    311 
    312             case XCC_EXT_1_IE_ID:
    313 				ciscoIEPresent = TI_TRUE;
    314                 pHandle->tempFrameInfo.frame.content.assocRsp.pRsnIe = &(pHandle->tempFrameInfo.rsnIe[0]);
    315                 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen,
    316                                               &(pHandle->tempFrameInfo.rsnIe[rsnIeIdx]));
    317                 if (status != TI_OK)
    318                 {
    319                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading XCC EXT1 IE\n");
    320                     goto mlme_recv_end;
    321                 }
    322 
    323                 pHandle->tempFrameInfo.frame.content.assocRsp.rsnIeLen += readLen;
    324                 rsnIeIdx ++;
    325                 break;
    326 
    327             case XCC_EXT_2_IE_ID:
    328 				ciscoIEPresent = TI_TRUE;
    329                 pHandle->tempFrameInfo.frame.content.assocRsp.pRsnIe   = &(pHandle->tempFrameInfo.rsnIe[0]);
    330                 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen,
    331                                               &(pHandle->tempFrameInfo.rsnIe[rsnIeIdx]));
    332                 if (status != TI_OK)
    333                 {
    334                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading RSN IP ADDR IE\n");
    335                     goto mlme_recv_end;
    336                 }
    337 
    338                 pHandle->tempFrameInfo.frame.content.assocRsp.rsnIeLen += readLen;
    339                 rsnIeIdx ++;
    340                 break;
    341 
    342 			case DOT11_QOS_CAPABILITY_ELE_ID:
    343 				pHandle->tempFrameInfo.frame.content.assocRsp.QoSCapParameters = &(pHandle->tempFrameInfo.QosCapParams);
    344                 status = mlmeParser_readQosCapabilityIE(pHandle, pData, bodyDataLen, &readLen,
    345                                                         &(pHandle->tempFrameInfo.QosCapParams));
    346                 if (status != TI_OK)
    347                 {
    348                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading QOS\n");
    349                     goto mlme_recv_end;
    350                 }
    351                 break;
    352 
    353 			case HT_CAPABILITIES_IE_ID:
    354 				pHandle->tempFrameInfo.frame.content.assocRsp.pHtCapabilities = &(pHandle->tempFrameInfo.tHtCapabilities);
    355                 status = mlmeParser_readHtCapabilitiesIE (pHandle, pData, bodyDataLen, &readLen,
    356                                                           &(pHandle->tempFrameInfo.tHtCapabilities));
    357 
    358                 if (status != TI_OK)
    359                 {
    360                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading HT Capabilities IE\n");
    361                     goto mlme_recv_end;
    362                 }
    363                 break;
    364 
    365 			case HT_INFORMATION_IE_ID:
    366 				pHandle->tempFrameInfo.frame.content.assocRsp.pHtInformation = &(pHandle->tempFrameInfo.tHtInformation);
    367                 status = mlmeParser_readHtInformationIE (pHandle, pData, bodyDataLen, &readLen,
    368                                                          &(pHandle->tempFrameInfo.tHtInformation));
    369                 if (status != TI_OK)
    370                 {
    371                     TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: error reading HT Information IE\n");
    372                     goto mlme_recv_end;
    373                 }
    374                 break;
    375 
    376             default:
    377                 TRACE1(pHandle->hReport, REPORT_SEVERITY_INFORMATION, "MLME_PARSER: unsupported IE found (%d)\n", (*pEleHdr)[1]);
    378                 readLen = (*pEleHdr)[1] + 2;
    379                 status = TI_OK;
    380                 break;
    381             }
    382 
    383             pData += readLen;
    384             bodyDataLen -= readLen;
    385         }
    386         /***************************/
    387 
    388 		/* set the appropriate flag in the association response frame */
    389 		/* to indicate whether or not we encountered a Cisco IE, i.e., */
    390 		/* if we have any indication as to whether the AP we've associated */
    391 		/* with is a Cisco AP. */
    392 		pHandle->tempFrameInfo.frame.content.assocRsp.ciscoIEPresent = ciscoIEPresent;
    393 
    394         TRACE1(pHandle->hReport, REPORT_SEVERITY_INFORMATION, "MLME_PARSER: ciscoIEPresent = %d\n", ciscoIEPresent);
    395 
    396         status = assoc_recv(pHandle->hAssoc, &(pHandle->tempFrameInfo.frame));
    397         break;
    398 
    399     case PROBE_REQUEST:
    400         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "MLME_PARSER: recieved PROBE_REQ message \n");
    401         break;
    402     case PROBE_RESPONSE:
    403 
    404         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "MLME_PARSER: recieved PROBE_RESPONSE message \n");
    405 
    406         if(RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4 > MAX_BEACON_BODY_LENGTH)
    407         {
    408             TRACE3(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv: probe response length out of range. length=%d, band=%d, channel=%d\n", RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4, pRxAttr->band, pRxAttr->channel);
    409             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    410             {
    411                 /* Notify the result CB of an invalid frame (to update the result counter) */
    412                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    413             }
    414             status = TI_NOK;
    415             goto mlme_recv_end;
    416         }
    417 
    418         /* init frame fields */
    419         pHandle->tempFrameInfo.frame.content.iePacket.barkerPreambleMode = PREAMBLE_UNSPECIFIED;
    420 
    421         /* read time stamp */
    422         os_memoryCopy(pHandle->hOs, (void *)pHandle->tempFrameInfo.frame.content.iePacket.timestamp, pData, TIME_STAMP_LEN);
    423         pData += TIME_STAMP_LEN;
    424 
    425         bodyDataLen -= TIME_STAMP_LEN;
    426         /* read beacon interval */
    427 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.iePacket.beaconInerval , pData);
    428         pData += 2;
    429         /* read capabilities */
    430 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.iePacket.capabilities , pData);
    431         pData += 2;
    432 
    433         bodyDataLen -= 4;
    434         pHandle->tempFrameInfo.frame.content.iePacket.pRsnIe = NULL;
    435         pHandle->tempFrameInfo.frame.content.iePacket.rsnIeLen = 0;
    436 
    437 		pHandle->tempFrameInfo.band = pRxAttr->band;
    438 		pHandle->tempFrameInfo.rxChannel = pRxAttr->channel;
    439 
    440         if ((pRxAttr->band == RADIO_BAND_2_4_GHZ) && (pRxAttr->channel > NUM_OF_CHANNELS_24))
    441         {
    442             TRACE2(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv, band=%d, channel=%d\n", pRxAttr->band, pRxAttr->channel);
    443             /* Error in parsing Probe response packet - exit */
    444             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    445             {
    446                 /* Notify the result CB of an invalid frame (to update the result counter) */
    447                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    448             }
    449             status = TI_NOK;
    450             goto mlme_recv_end;
    451         }
    452         else if ((pRxAttr->band == RADIO_BAND_5_0_GHZ) && (pRxAttr->channel <= NUM_OF_CHANNELS_24))
    453         {
    454             TRACE2(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv, band=%d, channel=%d\n", pRxAttr->band, pRxAttr->channel);
    455             /* Error in parsing Probe response packet - exit */
    456             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    457             {
    458                 /* Notify the result CB of an invalid frame (to update the result counter) */
    459                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    460             }
    461             status = TI_NOK;
    462             goto mlme_recv_end;
    463         }
    464         if (mlmeParser_parseIEs(hMlme, pData, bodyDataLen, &(pHandle->tempFrameInfo)) != TI_OK)
    465         {
    466             TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv: Error in parsing Probe response packet\n");
    467 
    468             /* Error in parsing Probe response packet - exit */
    469             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    470             {
    471                 /* Notify the result CB of an invalid frame (to update the result counter) */
    472                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    473             }
    474             status = TI_NOK;
    475             goto mlme_recv_end;
    476         }
    477 
    478         /* updating CountryIE  */
    479         if ((pHandle->tempFrameInfo.frame.content.iePacket.country != NULL) &&
    480             (pHandle->tempFrameInfo.frame.content.iePacket.country->hdr[1] != 0))
    481         {
    482             /* set the country info in the regulatory domain - If a different code was detected earlier
    483                the regDomain will ignore it */
    484             pParam->paramType = REGULATORY_DOMAIN_COUNTRY_PARAM;
    485             pParam->content.pCountry = (TCountry *)pHandle->tempFrameInfo.frame.content.iePacket.country;
    486             regulatoryDomain_setParam (pHandle->hRegulatoryDomain, pParam);
    487         }
    488 
    489         /* if tag = MSR, forward to the MSR module.  */
    490         if (SCAN_RESULT_TAG_MEASUREMENT == pRxAttr->eScanTag)
    491         {
    492             measurementMgr_mlmeResultCB( pHandle->hMeasurementMgr,
    493                                    &(pHandle->tempFrameInfo.bssid),
    494                                    &(pHandle->tempFrameInfo.frame),
    495                                    pRxAttr,
    496                                    (TI_UINT8 *)(pMgmtFrame->body+TIME_STAMP_LEN+4),
    497                                    RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4 );
    498         }
    499 
    500         /* only forward frames from the current BSS (according to the tag) to current BSS */
    501         else if (SCAN_RESULT_TAG_CURENT_BSS == pRxAttr->eScanTag)
    502         {
    503 			currBSS_probRespReceivedCallb(pHandle->hCurrBss,
    504                                           pRxAttr,
    505                                           &(pHandle->tempFrameInfo.bssid),
    506                                           &(pHandle->tempFrameInfo.frame),
    507                                           (TI_UINT8 *)(pMgmtFrame->body+TIME_STAMP_LEN+4),
    508                                           RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4);
    509         }
    510 
    511 		/* Check if there is a scan in progress, and this is a scan or measurement result (according to tag) */
    512 		else /* (SCAN_RESULT_TAG_CURENT_BSS!= pRxAttr->eScanTag) & (SCAN_RESULT_TAG_MEASUREMENT != pRxAttr->eScanTag) */
    513         {
    514             /* result CB is registered - results are sent to the registered callback */
    515             scanCncn_MlmeResultCB( pHandle->hScanCncn,
    516                                    &(pHandle->tempFrameInfo.bssid),
    517                                    &(pHandle->tempFrameInfo.frame),
    518                                    pRxAttr,
    519                                    (TI_UINT8 *)(pMgmtFrame->body+TIME_STAMP_LEN+4),
    520                                    RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4 );
    521         }
    522 
    523         if(pHandle->tempFrameInfo.recvChannelSwitchAnnoncIE == TI_FALSE)
    524 		{
    525 			switchChannel_recvCmd(pHandle->hSwitchChannel, NULL, pRxAttr->channel);
    526 		}
    527 
    528         break;
    529     case BEACON:
    530 
    531         TRACE1(pHandle->hReport, REPORT_SEVERITY_INFORMATION, "MLME_PARSER: recieved BEACON message, TS= %ld\n", os_timeStampMs(pHandle->hOs));
    532         TRACE0(pHandle->hReport, REPORT_SEVERITY_INFORMATION, "beacon BUF");
    533 
    534         if(RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4 > MAX_BEACON_BODY_LENGTH)
    535         {
    536             TRACE3(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv: beacon length out of range. length=%d, band=%d, channel=%d\n", RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4, pRxAttr->band, pRxAttr->channel);
    537             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    538             {
    539 			    /* Notify the result CB of an invalid frame (to update the result counter) */
    540 			    scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    541             }
    542             status = TI_NOK;
    543             goto mlme_recv_end;
    544         }
    545 
    546         /* init frame fields */
    547         pHandle->tempFrameInfo.frame.content.iePacket.barkerPreambleMode = PREAMBLE_UNSPECIFIED;
    548 
    549         /* read time stamp */
    550         os_memoryCopy(pHandle->hOs, (void *)pHandle->tempFrameInfo.frame.content.iePacket.timestamp, pData, TIME_STAMP_LEN);
    551         pData += TIME_STAMP_LEN;
    552 
    553         bodyDataLen -= TIME_STAMP_LEN;
    554         /* read beacon interval */
    555 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.iePacket.beaconInerval , pData);
    556         pData += 2;
    557         /* read capabilities */
    558 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.iePacket.capabilities , pData);
    559         pData += 2;
    560 
    561         bodyDataLen -= 4;
    562         pHandle->tempFrameInfo.frame.content.iePacket.pRsnIe = NULL;
    563         pHandle->tempFrameInfo.frame.content.iePacket.rsnIeLen = 0;
    564 
    565         if ((pRxAttr->band == RADIO_BAND_2_4_GHZ) && (pRxAttr->channel > NUM_OF_CHANNELS_24))
    566         {
    567             TRACE2(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv, band=%d, channel=%d\n", pRxAttr->band, pRxAttr->channel);
    568             /* Error in parsing Probe response packet - exit */
    569             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    570             {
    571                 /* Notify the result CB of an invalid frame (to update the result counter) */
    572                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    573             }
    574             status = TI_NOK;
    575             goto mlme_recv_end;
    576         }
    577         else if ((pRxAttr->band == RADIO_BAND_5_0_GHZ) && (pRxAttr->channel <= NUM_OF_CHANNELS_24))
    578         {
    579             TRACE2(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlmeParser_recv, band=%d, channel=%d\n", pRxAttr->band, pRxAttr->channel);
    580             /* Error in parsing Probe response packet - exit */
    581             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    582             {
    583                 /* Notify the result CB of an invalid frame (to update the result counter) */
    584                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    585             }
    586             status = TI_NOK;
    587             goto mlme_recv_end;
    588         }
    589 		pHandle->tempFrameInfo.band = pRxAttr->band;
    590 		pHandle->tempFrameInfo.rxChannel = pRxAttr->channel;
    591 
    592         if (mlmeParser_parseIEs(hMlme, pData, bodyDataLen, &(pHandle->tempFrameInfo)) != TI_OK)
    593         {
    594             TRACE0(pHandle->hReport, REPORT_SEVERITY_WARNING, "mlmeParser_parseIEs - Error in parsing Beacon \n");
    595             /* Error in parsing Probe response packet - exit */
    596             if ((pRxAttr->eScanTag > SCAN_RESULT_TAG_CURENT_BSS) && (pRxAttr->eScanTag != SCAN_RESULT_TAG_MEASUREMENT))
    597             {
    598                 /* Notify the result CB of an invalid frame (to update the result counter) */
    599                 scanCncn_MlmeResultCB( pHandle->hScanCncn, NULL, NULL, pRxAttr, NULL, 0);
    600             }
    601             status = TI_NOK;
    602             goto mlme_recv_end;
    603         }
    604 
    605         /* updating CountryIE  */
    606         if ((pHandle->tempFrameInfo.frame.content.iePacket.country != NULL) &&
    607             (pHandle->tempFrameInfo.frame.content.iePacket.country->hdr[1] != 0))
    608         {
    609             /* set the country info in the regulatory domain - If a different code was detected earlier
    610                the regDomain will ignore it */
    611             pParam->paramType = REGULATORY_DOMAIN_COUNTRY_PARAM;
    612             pParam->content.pCountry = (TCountry *)pHandle->tempFrameInfo.frame.content.iePacket.country;
    613             regulatoryDomain_setParam (pHandle->hRegulatoryDomain, pParam);
    614         }
    615 
    616 
    617         /* if tag = MSR, forward to the MSR module.  */
    618         if (SCAN_RESULT_TAG_MEASUREMENT == pRxAttr->eScanTag)
    619         {
    620             measurementMgr_mlmeResultCB( pHandle->hMeasurementMgr,
    621                                    &(pHandle->tempFrameInfo.bssid),
    622                                    &(pHandle->tempFrameInfo.frame),
    623                                    pRxAttr,
    624                                    (TI_UINT8 *)(pMgmtFrame->body+TIME_STAMP_LEN+4),
    625                                    RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4 );
    626         }
    627 
    628         /* only forward frames from the current BSS (according to the tag) to current BSS */
    629         else if (SCAN_RESULT_TAG_CURENT_BSS == pRxAttr->eScanTag)
    630         {
    631 			currBSS_beaconReceivedCallb(pHandle->hCurrBss, pRxAttr,
    632                                     &(pHandle->tempFrameInfo.bssid),
    633                                     &(pHandle->tempFrameInfo.frame),
    634                                     (TI_UINT8 *)(pMgmtFrame->body+TIME_STAMP_LEN+4),
    635                                     RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4);
    636         }
    637 
    638         /* Check if there is a scan in progress, and this is a scan or measurement result (according to tag) */
    639 		else /* (SCAN_RESULT_TAG_CURENT_BSS!= pRxAttr->eScanTag) & (SCAN_RESULT_TAG_MEASUREMENT != pRxAttr->eScanTag) */
    640 		{
    641 			/* result CB is registered - results are sent to the registered callback */
    642             scanCncn_MlmeResultCB( pHandle->hScanCncn,
    643                                    &(pHandle->tempFrameInfo.bssid),
    644                                    &(pHandle->tempFrameInfo.frame),
    645                                    pRxAttr,
    646                                    (TI_UINT8 *)(pMgmtFrame->body+TIME_STAMP_LEN+4),
    647                                    RX_BUF_LEN(pBuffer)-WLAN_HDR_LEN-TIME_STAMP_LEN-4 );
    648         }
    649 
    650         /* Counting the number of recieved beacons - used for statistics */
    651         pHandle->BeaconsCounterPS++;
    652 
    653         if (pHandle->tempFrameInfo.recvChannelSwitchAnnoncIE == TI_FALSE)
    654 		{
    655 			switchChannel_recvCmd(pHandle->hSwitchChannel, NULL, pRxAttr->channel);
    656 		}
    657 
    658         break;
    659     case ATIM:
    660         if (!pHandle->tempFrameInfo.myBssid)
    661             break;
    662 
    663         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "MLME_PARSER: recieved ATIM message \n");
    664         break;
    665     case DIS_ASSOC:
    666         if ((!pHandle->tempFrameInfo.myBssid) || (!pHandle->tempFrameInfo.mySa))
    667             break;
    668 
    669         /* read Reason interval */
    670 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.disAssoc.reason , pData);
    671 
    672    		{	/* Send roaming trigger */
    673 			roamingEventData_u RoamingEventData;
    674 			RoamingEventData.APDisconnect.uStatusCode = pHandle->tempFrameInfo.frame.content.disAssoc.reason;
    675 			RoamingEventData.APDisconnect.bDeAuthenticate = TI_FALSE; /* i.e. This is not DeAuth packet */
    676 			apConn_reportRoamingEvent(pHandle->hApConn, ROAMING_TRIGGER_AP_DISCONNECT, &RoamingEventData);
    677 		}
    678         break;
    679 
    680     case AUTH:
    681         /* Auth response frame is should be directed to our STA, and from the current AP */
    682 		if ( (!pHandle->tempFrameInfo.myBssid) || (!pHandle->tempFrameInfo.mySa) || (pHandle->tempFrameInfo.myDst == TI_FALSE) )
    683             break;
    684 
    685         /* read Algorithm interval */
    686 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.auth.authAlgo , pData);
    687         pData += 2;
    688         /* read Sequence number */
    689 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.auth.seqNum , pData);
    690         pData += 2;
    691         /* read status */
    692 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.auth.status , pData);
    693         pData += 2;
    694 
    695         TRACE3(pHandle->hReport, REPORT_SEVERITY_INFORMATION, "MLME_PARSER: Read Auth: algo=%d, seq=%d, status=%d\n", pHandle->tempFrameInfo.frame.content.auth.authAlgo, pHandle->tempFrameInfo.frame.content.auth.seqNum, pHandle->tempFrameInfo.frame.content.auth.status);
    696         bodyDataLen -= 6;
    697         /* read Challenge */
    698         pHandle->tempFrameInfo.frame.content.auth.pChallenge = &(pHandle->tempFrameInfo.challenge);
    699         status = mlmeParser_readChallange(pHandle, pData, bodyDataLen, &readLen, &(pHandle->tempFrameInfo.challenge));
    700         if (status != TI_OK)
    701         {
    702             pHandle->tempFrameInfo.challenge.hdr[1] = 0;
    703             readLen = 0;
    704         }
    705         pData += readLen;
    706 
    707         status = auth_recv(pHandle->hAuth, &(pHandle->tempFrameInfo.frame));
    708         break;
    709     case DE_AUTH:
    710         if ((!pHandle->tempFrameInfo.myBssid) || (!pHandle->tempFrameInfo.mySa))
    711             break;
    712 
    713         /* consider the Assoc frame if it is one of the following:
    714 			1) unicast frame and directed to our STA
    715 			2) broadcast frame
    716 		*/
    717 		if( (pHandle->tempFrameInfo.frame.extesion.destType == MSG_UNICAST) && (pHandle->tempFrameInfo.myDst == TI_FALSE) )
    718             break;
    719 
    720         /* read Reason */
    721 	    COPY_WLAN_WORD(&pHandle->tempFrameInfo.frame.content.deAuth.reason , pData);
    722 
    723 		{	/* Send roaming trigger */
    724 			roamingEventData_u RoamingEventData;
    725 			RoamingEventData.APDisconnect.uStatusCode = pHandle->tempFrameInfo.frame.content.disAssoc.reason;
    726 			RoamingEventData.APDisconnect.bDeAuthenticate = TI_TRUE; /* i.e. This is DeAuth packet */
    727 			apConn_reportRoamingEvent(pHandle->hApConn, ROAMING_TRIGGER_AP_DISCONNECT, &RoamingEventData);
    728 		}
    729         break;
    730 
    731     case ACTION:
    732 		pParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
    733 		ctrlData_getParam(pHandle->hCtrlData, pParam);
    734 
    735         if ((!pHandle->tempFrameInfo.myBssid) ||
    736 			((!pHandle->tempFrameInfo.mySa) && (pParam->content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE)))
    737             break;
    738 
    739 		/* if the action frame is unicast and not directed to our STA, we should ignore it */
    740 		if( (pHandle->tempFrameInfo.frame.extesion.destType == MSG_UNICAST) && (pHandle->tempFrameInfo.myDst == TI_FALSE) )
    741 			break;
    742 
    743         /* read Category field */
    744         pHandle->tempFrameInfo.frame.content.action.category = *pData;
    745         pData ++;
    746         bodyDataLen --;
    747 
    748         /* Checking if the category field is valid */
    749 		if(( pHandle->tempFrameInfo.frame.content.action.category != CATAGORY_SPECTRUM_MANAGEMENT) &&
    750 			(pHandle->tempFrameInfo.frame.content.action.category != CATAGORY_QOS)  &&
    751 			(pHandle->tempFrameInfo.frame.content.action.category != WME_CATAGORY_QOS) )
    752         {
    753             TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: Error category is invalid for action management frame %d \n", pHandle->tempFrameInfo.frame.content.action.category );
    754             break;
    755         }
    756 
    757 		switch(pHandle->tempFrameInfo.frame.content.action.category)
    758 		{
    759 			case CATAGORY_QOS:
    760 			case WME_CATAGORY_QOS:
    761 				/* read action field */
    762 				pHandle->tempFrameInfo.frame.content.action.action = *pData;
    763 				pData ++;
    764 				bodyDataLen --;
    765 
    766 				QosMngr_receiveActionFrames(pHandle->hQosMngr, pData, pHandle->tempFrameInfo.frame.content.action.action, bodyDataLen);
    767 				break;
    768 
    769 			case CATAGORY_SPECTRUM_MANAGEMENT:
    770 				/* read action field */
    771 				pHandle->tempFrameInfo.frame.content.action.action = *pData;
    772 				pData ++;
    773 				bodyDataLen --;
    774 
    775 				switch(pHandle->tempFrameInfo.frame.content.action.action)
    776 				{
    777 					case MEASUREMENT_REQUEST:
    778 						/* Checking the frame type  */
    779 						if(pHandle->tempFrameInfo.frame.extesion.destType == MSG_BROADCAST)
    780 							pHandle->tempFrameInfo.frame.content.action.frameType = MSR_FRAME_TYPE_BROADCAST;
    781 						else
    782 							pHandle->tempFrameInfo.frame.content.action.frameType = MSR_FRAME_TYPE_UNICAST;
    783 
    784 							/*measurementMgr_receiveFrameRequest(pHandle->hMeasurementMgr,
    785 							pHandle->tempFrameInfo.frame.content.action.frameType,
    786 							bodyDataLen,pData);*/
    787 						break;
    788 
    789 					case TPC_REQUEST:
    790 						/*measurementMgr_receiveTPCRequest(pHandle->hMeasurementMgr,(TI_UINT8)bodyDataLen,pData);*/
    791 						break;
    792 
    793 					case CHANNEL_SWITCH_ANNOUNCEMENT:
    794 						if (pHandle->tempFrameInfo.myBssid)
    795 						{   /* Ignore Switch Channel commands from non my BSSID */
    796 							mlmeParser_readChannelSwitch(pHandle,pData,bodyDataLen,&readLen,&(pHandle->tempFrameInfo.channelSwitch),
    797 								pRxAttr->channel);
    798 						}
    799 						break;
    800 
    801 					default:
    802                         TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: Error, category is invalid for action management frame %d \n",							pHandle->tempFrameInfo.frame.content.action.category );
    803 						break;
    804 				}
    805 
    806 				break;
    807 
    808 			default:
    809 				status = TI_NOK;
    810 				break;
    811 
    812 		}
    813     }
    814 
    815 mlme_recv_end:
    816     /* release BUF */
    817     os_memoryFree(pHandle->hOs, pParam, sizeof(paramInfo_t));
    818 	RxBufFree(pHandle->hOs, pBuffer);
    819     if (status != TI_OK)
    820         return TI_NOK;
    821     return status;
    822 }
    823 
    824 TI_STATUS mlmeParser_getFrameType(mlme_t *pMlme, TI_UINT16* pFrameCtrl, dot11MgmtSubType_e *pType)
    825 {
    826     TI_UINT16 fc;
    827 
    828 	COPY_WLAN_WORD(&fc, pFrameCtrl); /* copy with endianess handling. */
    829 
    830 	if ((fc & DOT11_FC_PROT_VERSION_MASK) != DOT11_FC_PROT_VERSION)
    831     {
    832         TRACE1(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: Error Wrong protocol version (not %d) \n", DOT11_FC_PROT_VERSION);
    833         return TI_NOK;
    834     }
    835 
    836     if ((fc & DOT11_FC_TYPE_MASK) != DOT11_FC_TYPE_MGMT)
    837     {
    838         TRACE0(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: Error not MANAGEMENT frame\n");
    839         return TI_NOK;
    840     }
    841 
    842     *pType = (dot11MgmtSubType_e)((fc & DOT11_FC_SUB_MASK) >> 4);
    843 
    844     return TI_OK;
    845 }
    846 
    847 
    848 #ifdef XCC_MODULE_INCLUDED
    849 void mlmeParser_readXCCOui (TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, XCCv4IEs_t *XCCIEs)
    850 {
    851     TI_UINT8 ieLen;
    852 	TI_UINT8 ouiType;
    853 
    854     ieLen = *(pData+1) + 2;
    855 
    856     if (dataLen < ieLen)
    857     {
    858 		/* Wrong length of info-element, skip to the end of the packet */
    859 		*pReadLen = dataLen;
    860 		return;
    861     }
    862 
    863     *pReadLen = ieLen;
    864 	ouiType = *(pData+5);
    865 
    866 	switch (ouiType)
    867 	{
    868 		case TS_METRIX_OUI_TYPE:
    869 			XCCIEs->tsMetrixParameter = (dot11_TS_METRICS_IE_t *)pData;
    870 			break;
    871 		case TS_RATE_SET_OUI_TYPE:
    872 			XCCIEs->trafficStreamParameter = (dot11_TSRS_IE_t *)pData;
    873 			break;
    874 		case EDCA_LIFETIME_OUI_TYPE:
    875 			XCCIEs->edcaLifetimeParameter = (dot11_MSDU_LIFE_TIME_IE_t *)pData;
    876 			break;
    877 	}
    878     return;
    879 }
    880 #endif
    881 
    882 
    883 TI_STATUS mlmeParser_readERP(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen,
    884                              TI_BOOL *useProtection, EPreamble *barkerPreambleMode)
    885 {
    886 
    887     TI_UINT32 erpIElen;
    888     TI_UINT16 ctrl;
    889 
    890     erpIElen = *(pData+1);
    891     *pReadLen = erpIElen + 2;
    892 
    893     if (dataLen < (TI_UINT32)(erpIElen + 2))
    894     {
    895         return TI_NOK;
    896     }
    897 
    898     COPY_WLAN_WORD(&ctrl , pData + 2);
    899 
    900     *useProtection = (ctrl & 0x2) >>1;
    901     *barkerPreambleMode = ((ctrl & 0x4) >>2) ? PREAMBLE_LONG : PREAMBLE_SHORT;
    902 
    903     return TI_OK;
    904 }
    905 
    906 
    907 TI_STATUS mlmeParser_readRates(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_RATES_t *pRates)
    908 {
    909     pRates->hdr[0] = *pData;
    910     pRates->hdr[1] = *(pData+1);
    911 
    912     *pReadLen = pRates->hdr[1] + 2;
    913 
    914     if (dataLen < (TI_UINT32)(pRates->hdr[1] + 2))
    915     {
    916         return TI_NOK;
    917     }
    918 
    919     if (pRates->hdr[1] > DOT11_MAX_SUPPORTED_RATES)
    920     {
    921         return TI_NOK;
    922     }
    923 
    924     os_memoryCopy(pMlme->hOs, (void *)pRates->rates, pData+2, pRates->hdr[1]);
    925 
    926     return TI_OK;
    927 }
    928 
    929 
    930 TI_STATUS mlmeParser_readSsid(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_SSID_t *pSsid)
    931 {
    932     pSsid->hdr[0] = *pData;
    933     pSsid->hdr[1] = *(pData+1);
    934 
    935     *pReadLen = pSsid->hdr[1] + 2;
    936 
    937     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pSsid->hdr[1] + 2)))
    938     {
    939         return TI_NOK;
    940     }
    941 
    942     if (pSsid->hdr[1] > MAX_SSID_LEN)
    943     {
    944         return TI_NOK;
    945     }
    946 
    947     os_memoryCopy(pMlme->hOs, (void *)pSsid->serviceSetId, pData+2, pSsid->hdr[1]);
    948 
    949     return TI_OK;
    950 }
    951 
    952 
    953 TI_STATUS mlmeParser_readFhParams(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_FH_PARAMS_t *pFhParams)
    954 {
    955     pFhParams->hdr[0] = *pData;
    956     pFhParams->hdr[1] = *(pData+1);
    957     pData += 2;
    958 
    959     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pFhParams->hdr[1] + 2)))
    960     {
    961         return TI_NOK;
    962     }
    963 
    964     COPY_WLAN_WORD(&pFhParams->dwellTime , pData);
    965     pData += 2;
    966 
    967     pFhParams->hopSet = *pData;
    968     pFhParams->hopPattern = *(pData+1);
    969     pFhParams->hopIndex = *(pData+2);
    970 
    971     *pReadLen = pFhParams->hdr[1] + 2;
    972 
    973     return TI_OK;
    974 }
    975 
    976 
    977 TI_STATUS mlmeParser_readDsParams(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_DS_PARAMS_t *pDsParams)
    978 {
    979     pDsParams->hdr[0] = *pData;
    980     pDsParams->hdr[1] = *(pData+1);
    981 
    982     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pDsParams->hdr[1] + 2)))
    983     {
    984         return TI_NOK;
    985     }
    986 
    987     pDsParams->currChannel = *(pData+2);
    988 
    989     *pReadLen = pDsParams->hdr[1] + 2;
    990 
    991     return TI_OK;
    992 }
    993 
    994 
    995 TI_STATUS mlmeParser_readCfParams(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_CF_PARAMS_t *pCfParams)
    996 {
    997     pCfParams->hdr[0] = *pData;
    998     pCfParams->hdr[1] = *(pData+1);
    999     pData += 2;
   1000 
   1001     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pCfParams->hdr[1] + 2)))
   1002     {
   1003         return TI_NOK;
   1004     }
   1005 
   1006     pCfParams->cfpCount = *pData;
   1007     pCfParams->cfpPeriod = *(pData+1);
   1008     pData += 2;
   1009 
   1010     COPY_WLAN_WORD(&pCfParams->cfpMaxDuration, pData);
   1011     pData += 2;
   1012 
   1013     COPY_WLAN_WORD(&pCfParams->cfpDurRemain, pData);
   1014 
   1015     *pReadLen = pCfParams->hdr[1] + 2;
   1016 
   1017     return TI_OK;
   1018 }
   1019 
   1020 
   1021 TI_STATUS mlmeParser_readIbssParams(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_IBSS_PARAMS_t *pIbssParams)
   1022 {
   1023     pIbssParams->hdr[0] = *pData;
   1024     pIbssParams->hdr[1] = *(pData+1);
   1025     pData += 2;
   1026 
   1027     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pIbssParams->hdr[1] + 2)))
   1028     {
   1029         return TI_NOK;
   1030     }
   1031 
   1032     COPY_WLAN_WORD(&pIbssParams->atimWindow, pData);
   1033 
   1034     *pReadLen = pIbssParams->hdr[1] + 2;
   1035 
   1036     return TI_OK;
   1037 }
   1038 
   1039 
   1040 TI_STATUS mlmeParser_readTim(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_TIM_t *pTim)
   1041 {
   1042     pTim->hdr[0] = *pData;
   1043     pTim->hdr[1] = *(pData+1);
   1044 
   1045     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pTim->hdr[1] + 2)) || (pTim->hdr[1] < 3))
   1046     {
   1047         return TI_NOK;
   1048     }
   1049 
   1050     pTim->dtimCount		= *(pData + 2);
   1051     pTim->dtimPeriod	= *(pData + 3);
   1052     pTim->bmapControl	= *(pData + 4);
   1053 
   1054     os_memoryCopy(pMlme->hOs, (void *)pTim->partialVirtualBmap, pData + 5, pTim->hdr[1] - 3);
   1055 
   1056     *pReadLen = pTim->hdr[1] + 2;
   1057 
   1058     return TI_OK;
   1059 }
   1060 
   1061 
   1062 TI_STATUS mlmeParser_readCountry(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_COUNTRY_t *countryIE)
   1063 {
   1064 	TI_INT32 i, j;
   1065 
   1066     countryIE->hdr[0] = *pData;
   1067     countryIE->hdr[1] = *(pData+1);
   1068 
   1069     *pReadLen = countryIE->hdr[1] + 2;
   1070 
   1071     if ((dataLen < 8) || (dataLen < (TI_UINT32)(countryIE->hdr[1] + 2)))
   1072     {
   1073         return TI_NOK;
   1074     }
   1075 
   1076     if (countryIE->hdr[1] > DOT11_COUNTRY_ELE_LEN_MAX)
   1077     {
   1078         TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: country IE error: eleLen=%d, maxLen=%d\n", countryIE->hdr[1], DOT11_COUNTRY_ELE_LEN_MAX);
   1079         return TI_NOK;
   1080     }
   1081 
   1082     os_memoryCopy(pMlme->hOs,&(countryIE->countryIE.CountryString), pData+2, DOT11_COUNTRY_STRING_LEN);
   1083 
   1084 	/* Loop on all tripletChannels. Each item has three fields ('i' counts rows and 'j' counts bytes). */
   1085 	for (i = 0, j = 0;  j < (countryIE->hdr[1] - DOT11_COUNTRY_STRING_LEN);  i++, j+=3)
   1086 	{
   1087 		countryIE->countryIE.tripletChannels[i].firstChannelNumber	= *(pData + j + 5);
   1088 		countryIE->countryIE.tripletChannels[i].numberOfChannels	= *(pData + j + 6);
   1089 		countryIE->countryIE.tripletChannels[i].maxTxPowerLevel		= *(pData + j + 7);
   1090 	}
   1091 
   1092     return TI_OK;
   1093 }
   1094 
   1095 
   1096 TI_STATUS mlmeParser_readWMEParams(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen,
   1097 								   TI_UINT32 *pReadLen, dot11_WME_PARAM_t *pWMEParamIE,
   1098 								   assocRsp_t *assocRsp)
   1099 {
   1100 	TI_UINT8 ieSubtype;
   1101 	TI_UINT8 ac;
   1102 
   1103 	/* Note:  This function actually reads either the WME-Params IE or the WME-Info IE! */
   1104 
   1105 	pWMEParamIE->hdr[0] = *pData;
   1106 	pWMEParamIE->hdr[1] = *(pData+1);
   1107 
   1108 	*pReadLen = pWMEParamIE->hdr[1] + 2;
   1109 
   1110 	if (dataLen < *pReadLen)
   1111 	{
   1112 		TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: WME Parameter: eleLen=%d is too long (%d)\n", *pReadLen, dataLen);
   1113 		*pReadLen = dataLen;
   1114 		return TI_NOK;
   1115 	}
   1116 
   1117 	if ((pWMEParamIE->hdr[1]> WME_TSPEC_IE_LEN) || (pWMEParamIE->hdr[1]< DOT11_WME_ELE_LEN))
   1118 	{
   1119         TRACE1(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: WME Parameter IE error: eleLen=%d\n", pWMEParamIE->hdr[1]);
   1120 		return TI_NOK;
   1121 	}
   1122 
   1123 	ieSubtype = *((TI_UINT8*)(pData+6));
   1124 	switch (ieSubtype)
   1125 	{
   1126 		case dot11_WME_OUI_SUB_TYPE_IE:
   1127 		case dot11_WME_OUI_SUB_TYPE_PARAMS_IE:
   1128 			/* Checking WME Version validity */
   1129 			if (*((TI_UINT8*)(pData+7)) != dot11_WME_VERSION )
   1130 			{
   1131 				TRACE1(pMlme->hReport, REPORT_SEVERITY_INFORMATION, "MLME_PARSER: WME Parameter IE error: Version =%d is unsupported\n",								  *((TI_UINT8*)(pData+7)) );
   1132 				return TI_NOK;
   1133 			}
   1134 
   1135 			/*
   1136 			 * Copy either the WME-Params IE or the WME-Info IE (Info is a subset of Params)!
   1137 			 *
   1138 			 * Note that the WME_ACParameteres part is copied separately for two reasons:
   1139 			 *	1) It exists only in the WME-Params IE.
   1140 			 *	2) There is a gap of 2 bytes before the WME_ACParameteres if OS_PACKED is not supported.
   1141 			 */
   1142 			os_memoryCopy(pMlme->hOs,&(pWMEParamIE->OUI), pData+2, 8);
   1143 
   1144 			if ( *((TI_UINT8*)(pData+6)) == dot11_WME_OUI_SUB_TYPE_PARAMS_IE )
   1145 			{
   1146 				os_memoryCopy(pMlme->hOs,&(pWMEParamIE->WME_ACParameteres), pData+10, pWMEParamIE->hdr[1] - 8);
   1147 			}
   1148 
   1149 			break;
   1150 
   1151 		case WME_TSPEC_IE_OUI_SUB_TYPE:
   1152 			/* Read renegotiated TSPEC parameters */
   1153 			if (assocRsp == NULL)
   1154 			{
   1155 TRACE0(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: WME Parameter IE error: TSPEC Sub Type in beacon or probe resp\n");
   1156 				return TI_NOK;
   1157 			}
   1158 
   1159 			ac = WMEQosTagToACTable [ GET_USER_PRIORITY_FROM_WME_TSPEC_IE(pData) ];
   1160 
   1161 			if (ac == QOS_AC_VO)
   1162 			{
   1163 				assocRsp->tspecVoiceParameters = pData;
   1164 			}
   1165 			else if (ac == QOS_AC_VI)
   1166 			{
   1167 				assocRsp->tspecSignalParameters = pData;
   1168 			}
   1169 			break;
   1170 
   1171 		default:
   1172 			/* Checking OUI Sub Type validity */
   1173 TRACE1(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: WME Parameter IE error: Sub Type =%d is invalid\n",							  ieSubtype);
   1174 			return TI_NOK;
   1175 	}
   1176     return TI_OK;
   1177 }
   1178 
   1179 
   1180 static TI_UINT32 mlmeParser_getWSCReadLen(TI_UINT8 *pData)
   1181 {
   1182     return *(pData+1) + 2;
   1183 }
   1184 
   1185 
   1186 static TI_STATUS mlmeParser_readWSCParams(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_WSC_t *pWSC_IE)
   1187 {
   1188 	pWSC_IE->hdr[0] = *pData;
   1189 	pWSC_IE->hdr[1] = *(pData+1);
   1190 
   1191     *pReadLen = pWSC_IE->hdr[1] + 2;
   1192 
   1193     /* Length Sanity check of the WSC IE */
   1194 	if ((dataLen < 8) || (dataLen < (TI_UINT32)(pWSC_IE->hdr[1] + 2)))
   1195     {
   1196         TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: WSC Parameter IE error: dataLen=%d, pWSC_IE->hdr[1]=%d\n", dataLen, pWSC_IE->hdr[1]);
   1197 		return TI_NOK;
   1198     }
   1199 
   1200     /* Length Sanity check of the WSC IE */
   1201 	if (pWSC_IE->hdr[1] > ( sizeof(dot11_WSC_t) - sizeof(dot11_eleHdr_t) ))
   1202     {
   1203         TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: WSC Parameter IE error: eleLen=%d, maxLen=%d\n", pWSC_IE->hdr[1], ( sizeof(dot11_WSC_t) - sizeof(dot11_eleHdr_t) ));
   1204         return TI_NOK;
   1205     }
   1206 
   1207 	/* Copy the WSC Params IE */
   1208 	os_memoryCopy(pMlme->hOs,&(pWSC_IE->OUI), pData+2, pWSC_IE->hdr[1]);
   1209 
   1210     return TI_OK;
   1211 }
   1212 
   1213 
   1214 TI_STATUS mlmeParser_readQosCapabilityIE(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_QOS_CAPABILITY_IE_t *QosCapParams)
   1215 {
   1216     QosCapParams->hdr[0] = *pData;
   1217     QosCapParams->hdr[1] = *(pData+1);
   1218 
   1219     *pReadLen = QosCapParams->hdr[1] + 2;
   1220 
   1221     if (dataLen < (TI_UINT32)(QosCapParams->hdr[1] + 2))
   1222     {
   1223         return TI_NOK;
   1224     }
   1225 
   1226     if (QosCapParams->hdr[1] > DOT11_QOS_CAPABILITY_ELE_LEN)
   1227     {
   1228         TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: QOS Capability  IE error: eleLen=%d, maxLen=%d\n", QosCapParams->hdr[1], DOT11_QOS_CAPABILITY_ELE_LEN);
   1229         return TI_NOK;
   1230     }
   1231 
   1232    QosCapParams->QosInfoField = (*(pData+1));
   1233     return TI_OK;
   1234 }
   1235 
   1236 
   1237 TI_STATUS mlmeParser_readHtCapabilitiesIE(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, Tdot11HtCapabilitiesUnparse *pHtCapabilities)
   1238 {
   1239     pHtCapabilities->tHdr[0] = *pData;
   1240     pHtCapabilities->tHdr[1] = *(pData+1);
   1241 
   1242     *pReadLen = pHtCapabilities->tHdr[1] + 2;
   1243 
   1244     if (dataLen < (TI_UINT32)(pHtCapabilities->tHdr[1] + 2))
   1245     {
   1246         return TI_NOK;
   1247     }
   1248 
   1249     if (pHtCapabilities->tHdr[1] != DOT11_HT_CAPABILITIES_ELE_LEN)
   1250     {
   1251         TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: HT Capability IE error: eleLen=%d, expectedLen=%d\n", pHtCapabilities->tHdr[1], DOT11_HT_CAPABILITIES_ELE_LEN);
   1252         return TI_NOK;
   1253     }
   1254 
   1255     os_memoryCopy(pMlme->hOs, (void*)pHtCapabilities->aHtCapabilitiesIe, pData + 2, pHtCapabilities->tHdr[1]);
   1256 
   1257     return TI_OK;
   1258 }
   1259 
   1260 
   1261 TI_STATUS mlmeParser_readHtInformationIE(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, Tdot11HtInformationUnparse *pHtInformation)
   1262 {
   1263     pHtInformation->tHdr[0] = *pData;
   1264     pHtInformation->tHdr[1] = *(pData+1);
   1265 
   1266     *pReadLen = pHtInformation->tHdr[1] + 2;
   1267 
   1268     if (dataLen < (TI_UINT32)(pHtInformation->tHdr[1] + 2))
   1269     {
   1270         return TI_NOK;
   1271     }
   1272 
   1273     if (pHtInformation->tHdr[1] < DOT11_HT_INFORMATION_ELE_LEN)
   1274     {
   1275         TRACE2(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: HT Information IE error: eleLen=%d, minimum Len=%d\n", pHtInformation->tHdr[1], DOT11_HT_INFORMATION_ELE_LEN);
   1276         return TI_NOK;
   1277     }
   1278 
   1279     os_memoryCopy(pMlme->hOs, (void*)pHtInformation->aHtInformationIe, pData + 2, pHtInformation->tHdr[1]);
   1280 
   1281     return TI_OK;
   1282 }
   1283 
   1284 
   1285 TI_STATUS mlmeParser_readChallange(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_CHALLENGE_t *pChallange)
   1286 {
   1287     if (dataLen < 2)
   1288     {
   1289         return TI_NOK;
   1290     }
   1291 
   1292     pChallange->hdr[0] = *pData;
   1293     pChallange->hdr[1] = *(pData+1);
   1294     pData += 2;
   1295 
   1296     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pChallange->hdr[1] + 2)))
   1297     {
   1298         return TI_NOK;
   1299     }
   1300 
   1301     if (pChallange->hdr[1] > DOT11_CHALLENGE_TEXT_MAX)
   1302     {
   1303         return TI_NOK;
   1304     }
   1305 
   1306     os_memoryCopy(pMlme->hOs, (void *)pChallange->text, pData, pChallange->hdr[1]);
   1307 
   1308     *pReadLen = pChallange->hdr[1] + 2;
   1309 
   1310     return TI_OK;
   1311 }
   1312 
   1313 TI_STATUS mlmeParser_readRsnIe(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_RSN_t *pRsnIe)
   1314 {
   1315     pRsnIe->hdr[0] = *pData;
   1316     pRsnIe->hdr[1] = *(pData+1);
   1317     pData += 2;
   1318 
   1319     if ((dataLen < 2) || (dataLen < (TI_UINT32)(pRsnIe->hdr[1] + 2)))
   1320     {
   1321         return TI_NOK;
   1322     }
   1323 
   1324     os_memoryCopy(pMlme->hOs, (void *)pRsnIe->rsnIeData, pData, pRsnIe->hdr[1]);
   1325 
   1326     *pReadLen = pRsnIe->hdr[1] + 2;
   1327 
   1328     return TI_OK;
   1329 }
   1330 
   1331 TI_STATUS mlmeParser_readPowerConstraint(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_POWER_CONSTRAINT_t *powerConstraintIE)
   1332 {
   1333     powerConstraintIE->hdr[0] = *pData;
   1334     powerConstraintIE->hdr[1] = *(pData+1);
   1335 
   1336     *pReadLen = powerConstraintIE->hdr[1] + 2;
   1337 
   1338     if ((dataLen < 2) || (dataLen < (TI_UINT32)(powerConstraintIE->hdr[1] + 2)))
   1339     {
   1340         return TI_NOK;
   1341     }
   1342 
   1343     if (powerConstraintIE->hdr[1] > DOT11_POWER_CONSTRAINT_ELE_LEN)
   1344     {
   1345         return TI_NOK;
   1346     }
   1347 
   1348     os_memoryCopy(pMlme->hOs,(void *)&(powerConstraintIE->powerConstraint), pData+2, powerConstraintIE->hdr[1]);
   1349 
   1350     return TI_OK;
   1351 }
   1352 
   1353 
   1354 TI_STATUS mlmeParser_readChannelSwitch(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_UINT8 channel)
   1355 {
   1356     channelSwitch->hdr[0] = *pData++;
   1357     channelSwitch->hdr[1] = *pData++;
   1358 
   1359     *pReadLen = channelSwitch->hdr[1] + 2;
   1360 
   1361     if ((dataLen < 2) || (dataLen < (TI_UINT32)(channelSwitch->hdr[1] + 2)))
   1362     {
   1363         return TI_NOK;
   1364     }
   1365 
   1366     if (channelSwitch->hdr[1] > DOT11_CHANNEL_SWITCH_ELE_LEN)
   1367     {
   1368         return TI_NOK;
   1369     }
   1370 
   1371     channelSwitch->channelSwitchMode = *pData++;
   1372     channelSwitch->channelNumber = *pData++;
   1373     channelSwitch->channelSwitchCount = *pData;
   1374 
   1375 
   1376 	switchChannel_recvCmd(pMlme->hSwitchChannel, channelSwitch, channel);
   1377 	return TI_OK;
   1378 }
   1379 
   1380 TI_STATUS mlmeParser_readQuiet(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_QUIET_t *quiet)
   1381 {
   1382     quiet->hdr[0] = *pData++;
   1383     quiet->hdr[1] = *pData++;
   1384 
   1385     *pReadLen = quiet->hdr[1] + 2;
   1386 
   1387     if ((dataLen < 2) || (dataLen < (TI_UINT32)(quiet->hdr[1] + 2)))
   1388     {
   1389         return TI_NOK;
   1390     }
   1391 
   1392     if (quiet->hdr[1] > DOT11_QUIET_ELE_LEN)
   1393     {
   1394         return TI_NOK;
   1395     }
   1396 
   1397     quiet->quietCount = *pData++;
   1398     quiet->quietPeriod = *pData++;
   1399     quiet->quietDuration = *((TI_UINT16*)pData);
   1400     pData += sizeof(TI_UINT16);
   1401     quiet->quietOffset = *((TI_UINT16*)pData);
   1402 
   1403 	return TI_OK;
   1404 }
   1405 
   1406 
   1407 TI_STATUS mlmeParser_readTPCReport(mlme_t *pMlme,TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_TPC_REPORT_t *TPCReport)
   1408 {
   1409     TPCReport->hdr[0] = *pData;
   1410     TPCReport->hdr[1] = *(pData+1);
   1411 
   1412     *pReadLen = TPCReport->hdr[1] + 2;
   1413 
   1414     if ((dataLen < 2) || (dataLen < (TI_UINT32)(TPCReport->hdr[1] + 2)))
   1415     {
   1416         return TI_NOK;
   1417     }
   1418 
   1419     if (TPCReport->hdr[1] > DOT11_TPC_REPORT_ELE_LEN)
   1420     {
   1421         return TI_NOK;
   1422     }
   1423 
   1424     TPCReport->transmitPower = *(pData+2);
   1425 
   1426     return TI_OK;
   1427 }
   1428 
   1429 
   1430 #ifdef XCC_MODULE_INCLUDED
   1431 TI_STATUS mlmeParser_readCellTP(mlme_t *pMlme, TI_UINT8 *pData, TI_UINT32 dataLen, TI_UINT32 *pReadLen, dot11_CELL_TP_t *cellTP)
   1432 {
   1433     TI_UINT8 XCC_OUI[] = XCC_OUI;
   1434 
   1435     cellTP->hdr[0] = *pData++;
   1436     cellTP->hdr[1] = *pData++;
   1437 
   1438     *pReadLen = cellTP->hdr[1] + 2;
   1439 
   1440     if ((dataLen < 2) || (dataLen < (TI_UINT32)(cellTP->hdr[1] + 2)))
   1441     {
   1442         return TI_NOK;
   1443     }
   1444 
   1445     if (cellTP->hdr[1] > DOT11_CELL_TP_ELE_LEN)
   1446     {
   1447         return TI_NOK;
   1448     }
   1449 
   1450 	os_memoryCopy(pMlme->hOs, (void*)cellTP->oui, pData, cellTP->hdr[1]);
   1451 
   1452     if (os_memoryCompare(pMlme->hOs, (void*)cellTP->oui, XCC_OUI, 3) != 0)
   1453     {
   1454 		return TI_NOK;
   1455     }
   1456 
   1457     return TI_OK;
   1458 }
   1459 #endif
   1460 
   1461 #if CHECK_PARSING_ERROR_CONDITION_PRINT
   1462 	#define CHECK_PARSING_ERROR_CONDITION(x, msg, bDump)	   \
   1463 			if ((x)) \
   1464 			{ \
   1465                 TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, msg);    \
   1466                 if (bDump) {\
   1467                     TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "Buff len = %d \n", packetLength);    \
   1468                     report_PrintDump (pPacketBody, packetLength); }\
   1469 				return TI_NOK; \
   1470 			}
   1471 #else
   1472 	#define CHECK_PARSING_ERROR_CONDITION(x, msg, bDump) \
   1473          if ((x)) return TI_NOK;
   1474 #endif
   1475 
   1476 TI_STATUS mlmeParser_parseIEs(TI_HANDLE hMlme,
   1477 							  TI_UINT8 *pData,
   1478 							  TI_INT32 bodyDataLen,
   1479 							  mlmeIEParsingParams_t *params)
   1480 {
   1481     dot11_eleHdr_t 		*pEleHdr;
   1482     TI_UINT32 			 readLen;
   1483 	TI_STATUS			 status = TI_NOK;
   1484     TI_UINT8 			 rsnIeIdx = 0;
   1485     TI_UINT8 			 wpaIeOuiIe[4] = { 0x00, 0x50, 0xf2, 0x01};
   1486 	beacon_probeRsp_t 	*frame = &(params->frame.content.iePacket);
   1487 	mlme_t 				*pHandle = (mlme_t *)hMlme;
   1488 #ifdef XCC_MODULE_INCLUDED
   1489 	TI_BOOL				allowCellTP = TI_TRUE;
   1490 #endif
   1491 #if CHECK_PARSING_ERROR_CONDITION_PRINT
   1492 	TI_INT32				packetLength = bodyDataLen;
   1493 	TI_UINT8				*pPacketBody = pData;
   1494 #endif
   1495 
   1496 	params->recvChannelSwitchAnnoncIE = TI_FALSE;
   1497 
   1498 	while (bodyDataLen > 1)
   1499 	{
   1500 		pEleHdr = (dot11_eleHdr_t *)pData;
   1501 
   1502 #if CHECK_PARSING_ERROR_CONDITION_PRINT
   1503 		/* CHECK_PARSING_ERROR_CONDITION(((*pEleHdr)[1] > (bodyDataLen - 2)), ("MLME_PARSER: IE %d with length %d out of bounds %d\n", (*pEleHdr)[0], (*pEleHdr)[1], (bodyDataLen - 2)), TI_TRUE); */
   1504 		if ((*pEleHdr)[1] > (bodyDataLen - 2))
   1505 		{
   1506 			TRACE3(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: IE %d with length %d out of bounds %d\n", (*pEleHdr)[0], (*pEleHdr)[1], (bodyDataLen - 2));
   1507 
   1508 			TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "Buff len = %d \n", packetLength);
   1509 			report_PrintDump (pPacketBody, packetLength);
   1510 		}
   1511 #endif
   1512         switch ((*pEleHdr)[0])
   1513 		{
   1514 		/* read SSID */
   1515 		case SSID_IE_ID:
   1516 			frame->pSsid = &params->ssid;
   1517 			status = mlmeParser_readSsid(pHandle, pData, bodyDataLen, &readLen, frame->pSsid);
   1518 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading SSID\n"),TI_TRUE);
   1519 			break;
   1520 		/* read rates */
   1521 		case SUPPORTED_RATES_IE_ID:
   1522 			frame->pRates = &params->rates;
   1523 			status = mlmeParser_readRates(pHandle, pData, bodyDataLen, &readLen, frame->pRates);
   1524 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading RATES\n"),TI_TRUE);
   1525 			break;
   1526 		case EXT_SUPPORTED_RATES_IE_ID:
   1527 			frame->pExtRates = &params->extRates;
   1528 			status = mlmeParser_readRates(pHandle, pData, bodyDataLen, &readLen, frame->pExtRates);
   1529 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading EXT RATES\n"),TI_TRUE);
   1530 			break;
   1531 
   1532 		case ERP_IE_ID:
   1533 			status = mlmeParser_readERP(pHandle, pData, bodyDataLen, &readLen,
   1534 										(TI_BOOL *)&frame->useProtection,
   1535 										(EPreamble *)&frame->barkerPreambleMode);
   1536 
   1537 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading ERP\n"),TI_TRUE);
   1538 			break;
   1539 		/* read FH parameter set */
   1540 		case FH_PARAMETER_SET_IE_ID:
   1541 			frame->pFHParamsSet = &params->fhParams;
   1542 			status = mlmeParser_readFhParams(pHandle, pData, bodyDataLen, &readLen, frame->pFHParamsSet);
   1543 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading FH parameters\n"),TI_TRUE);
   1544 			break;
   1545 		/* read DS parameter set */
   1546 		case DS_PARAMETER_SET_IE_ID:
   1547 			frame->pDSParamsSet = &params->dsParams;
   1548 			status = mlmeParser_readDsParams(pHandle, pData, bodyDataLen, &readLen, frame->pDSParamsSet);
   1549 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading DS parameters\n"),TI_TRUE);
   1550 			if (RADIO_BAND_2_4_GHZ == params->band )
   1551 			{
   1552 				if (frame->pDSParamsSet->currChannel != params->rxChannel)
   1553 				{
   1554 					TRACE2(pHandle->hReport, REPORT_SEVERITY_ERROR, "Channel ERROR - incompatible channel source information: Frame=%d Vs Radio=%d.\nparser ABORTED!!!\n",
   1555 						frame->pDSParamsSet->currChannel , params->rxChannel);
   1556 
   1557 					return TI_NOK;
   1558 				}
   1559 			}
   1560 			break;
   1561 		/* read CF parameter set */
   1562 		case CF_PARAMETER_SET_IE_ID:
   1563 			frame->pCFParamsSet = &params->cfParams;
   1564 			status = mlmeParser_readCfParams(pHandle, pData, bodyDataLen, &readLen, frame->pCFParamsSet);
   1565 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading CF parameters\n"),TI_TRUE);
   1566 			break;
   1567 		/* read IBSS parameter set */
   1568 		case IBSS_PARAMETER_SET_IE_ID:
   1569 			frame->pIBSSParamsSet = &params->ibssParams;
   1570 			status = mlmeParser_readIbssParams(pHandle, pData, bodyDataLen, &readLen, frame->pIBSSParamsSet);
   1571 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading IBSS parameters\n"),TI_TRUE);
   1572 			break;
   1573 
   1574 		/* read TIM */
   1575 		case TIM_IE_ID:
   1576 			frame->pTIM = &params->tim;
   1577 			status = mlmeParser_readTim(pHandle, pData, bodyDataLen, &readLen, frame->pTIM);
   1578 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading TIM\n"),TI_TRUE);
   1579 			break;
   1580 
   1581 		/* read Country */
   1582 		case COUNTRY_IE_ID:
   1583 			frame->country = &params->country;
   1584 			status = mlmeParser_readCountry(pHandle, pData, bodyDataLen, &readLen, frame->country);
   1585 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading country parameters\n"),TI_TRUE);
   1586 			break;
   1587 
   1588 		/* read Power Constraint */
   1589 		case POWER_CONSTRAINT_IE_ID:
   1590 #ifdef XCC_MODULE_INCLUDED
   1591 			allowCellTP = TI_FALSE;
   1592 #endif
   1593 			frame->powerConstraint = &params->powerConstraint;
   1594 			status = mlmeParser_readPowerConstraint(pHandle, pData, bodyDataLen, &readLen, frame->powerConstraint);
   1595 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading Power Constraint parameters\n"),TI_TRUE);
   1596 			break;
   1597 
   1598 		/* read Channel Switch Mode */
   1599         case CHANNEL_SWITCH_ANNOUNCEMENT_IE_ID:
   1600 
   1601             frame->channelSwitch = &params->channelSwitch;
   1602 
   1603             if (params->myBssid)
   1604 			{   /* Ignore Switch Channel commands from non my BSSID */
   1605 				params->recvChannelSwitchAnnoncIE = TI_TRUE;
   1606 				status = mlmeParser_readChannelSwitch(pHandle, pData, bodyDataLen, &readLen, frame->channelSwitch, params->rxChannel);
   1607 				if (status != TI_OK)
   1608 				{
   1609 					/*
   1610 					 * PATCH for working with AP-DK 4.0.51 that use IE 37 (with length 20) for RSNE
   1611 					 * Ignore the IE instead of rejecting the whole BUF (beacon or probe response)
   1612 					 */
   1613                     TRACE0(pHandle->hReport, REPORT_SEVERITY_WARNING, "MLME_PARSER: error reading Channel Switch announcement parameters - ignore IE\n");
   1614 				}
   1615 			}
   1616 			break;
   1617 
   1618 		/* read Quiet IE */
   1619 		case QUIET_IE_ID:
   1620 			frame->quiet = &params->quiet;
   1621 			status = mlmeParser_readQuiet(pHandle, pData, bodyDataLen, &readLen, frame->quiet);
   1622 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading Quiet parameters\n"),TI_TRUE);
   1623 			break;
   1624 
   1625 		/* read TPC report IE */
   1626 		case TPC_REPORT_IE_ID:
   1627 			frame->TPCReport = &params->TPCReport;
   1628 			status = mlmeParser_readTPCReport(pHandle, pData, bodyDataLen, &readLen, frame->TPCReport);
   1629 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading TPC report parameters\n"),TI_TRUE);
   1630 			break;
   1631 
   1632 		case XCC_EXT_1_IE_ID:
   1633 			frame->pRsnIe   = &params->rsnIe[0];
   1634 			status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen, &params->rsnIe[rsnIeIdx]);
   1635 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading RSN IE\n"),TI_TRUE);
   1636 
   1637 			frame->rsnIeLen += readLen;
   1638 			rsnIeIdx ++;
   1639 			break;
   1640 
   1641 		case RSN_IE_ID:
   1642 			frame->pRsnIe = &params->rsnIe[0];
   1643 			status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen, &params->rsnIe[rsnIeIdx]);
   1644 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading RSN IE\n"),TI_TRUE);
   1645 
   1646 			frame->rsnIeLen += readLen;
   1647 			rsnIeIdx ++;
   1648 			break;
   1649 
   1650 		case DOT11_QOS_CAPABILITY_ELE_ID:
   1651 			frame->QoSCapParameters = &params->QosCapParams;
   1652 			status = mlmeParser_readQosCapabilityIE(pHandle, pData, bodyDataLen, &readLen, &params->QosCapParams);
   1653 			CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading QOS CapabilityIE\n"),TI_TRUE);
   1654 			break;
   1655 
   1656 	case HT_CAPABILITIES_IE_ID:
   1657 		frame->pHtCapabilities = &params->tHtCapabilities;
   1658 		status = mlmeParser_readHtCapabilitiesIE(pHandle, pData, bodyDataLen, &readLen, &params->tHtCapabilities);
   1659 		CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading HT Capabilitys IE\n"),TI_TRUE);
   1660 		break;
   1661 
   1662 	case HT_INFORMATION_IE_ID:
   1663 		frame->pHtInformation = &params->tHtInformation;
   1664 		status = mlmeParser_readHtInformationIE(pHandle, pData, bodyDataLen, &readLen, &params->tHtInformation);
   1665 		CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading HT Information IE\n"),TI_TRUE);
   1666 		break;
   1667 
   1668 		case WPA_IE_ID:
   1669 			if (!os_memoryCompare(pHandle->hOs, pData+2, wpaIeOuiIe, 3))
   1670 			{
   1671 				/* Note : WSC, WPA and WME use the same OUI */
   1672 				/*  Its assumes that:
   1673 						WPA uses OUI Type with value  - 1
   1674 						WME uses OUI Type with value  - 2
   1675 						WSC uses OUI Type with value  - 4
   1676 				*/
   1677 
   1678 				/* Check the OUI sub Type to verify whether this is a WSC IE, WME IE or WPA IE*/
   1679 				if( (*(TI_UINT8*)(pData+5)) == dot11_WPA_OUI_TYPE)
   1680 				{
   1681 					/* If we are here - the following is WPA IE */
   1682 					frame->pRsnIe = &params->rsnIe[0];
   1683 					status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen,
   1684 												  &readLen, &params->rsnIe[rsnIeIdx]);
   1685 					frame->rsnIeLen += readLen;
   1686 					rsnIeIdx ++;
   1687 
   1688 					CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading RSN IE\n"),TI_TRUE);
   1689 				}
   1690 				if( ( (*(TI_UINT8*)(pData+5)) == dot11_WME_OUI_TYPE ) &&
   1691 					( ( (*(TI_UINT8*)(pData+6)) == dot11_WME_OUI_SUB_TYPE_PARAMS_IE) ||
   1692 					  ( (*(TI_UINT8*)(pData+6)) == dot11_WME_OUI_SUB_TYPE_IE) ) )
   1693 				{
   1694 					/* If we are here - the following is WME-Params IE, WME-Info IE or TSPEC IE. */
   1695 					/* Note that we are using the WMEParams struct also to hold the WME-Info IE
   1696 					     which is a subset of WMEParams, and only one of them is sent in a frame. */
   1697 					frame->WMEParams = &params->WMEParams;
   1698 					status = mlmeParser_readWMEParams(pHandle, pData, bodyDataLen, &readLen, frame->WMEParams, NULL);
   1699 
   1700 					CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading WME params\n"),TI_TRUE);
   1701 				}
   1702 				if( ( (*(TI_UINT8*)(pData+5)) == dot11_WSC_OUI_TYPE ))
   1703 				{
   1704 					/* If we are here - the following is WSC IE */
   1705                     readLen = mlmeParser_getWSCReadLen (pData);
   1706                     /*
   1707                      * This IE is not supposed to be found in beacons accroding to the standard
   1708                      * definition. However, some APs do add it to beacons. It is read from beacons
   1709                      * accroding to a registry key (which is false by default). Even if it is not
   1710                      * read, the readLen must be set for the pointer to advance, which is done
   1711                      * above.
   1712                      */
   1713                     if ((BEACON != params->frame.subType) || (TI_TRUE == pHandle->bParseBeaconWSC))
   1714                     {
   1715 					frame->WSCParams = &params->WSCParams;
   1716 					status = mlmeParser_readWSCParams(pHandle, pData, bodyDataLen, &readLen, frame->WSCParams);
   1717 					CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading WSC params\n"),TI_TRUE);
   1718 				}
   1719                 }
   1720 				else
   1721 				{
   1722 					/* Unrecognized OUI type */
   1723 					readLen = (*pEleHdr)[1] + 2;
   1724 				}
   1725 			}
   1726 			else
   1727 			{
   1728 				readLen = (*pEleHdr)[1] + 2;
   1729 			}
   1730 
   1731 			break;
   1732 
   1733 #ifdef XCC_MODULE_INCLUDED
   1734 		case CELL_POWER_IE:
   1735 			/* We mustn't take the Cell Transmit Power IE into account if */
   1736 			/* there's a Power Constraint IE. Since the IEs must be in increasing */
   1737 			/* order, it's enough to perform the check here, because if the Power */
   1738 			/* Constraint IE is present it must have already been processed. */
   1739 			if (allowCellTP)
   1740 			{
   1741 				frame->cellTP = &params->cellTP;
   1742 				status = mlmeParser_readCellTP(pHandle, pData, bodyDataLen, &readLen, frame->cellTP);
   1743 				CHECK_PARSING_ERROR_CONDITION((status != TI_OK), ("MLME_PARSER: error reading Cell Transmit Power params.\n"),TI_TRUE);
   1744 			}
   1745 			break;
   1746 #endif
   1747 
   1748 		default:
   1749 			TRACE1(pHandle->hReport, REPORT_SEVERITY_INFORMATION, "MLME_PARSER: unknown IE found (%d)\n", pData[0]);
   1750 			readLen = pData[1] + 2;
   1751 			status = TI_OK;
   1752 			os_memoryCopy( pHandle->hOs,
   1753 				       &params->unknownIe[params->frame.content.iePacket.unknownIeLen],
   1754 				       pData, readLen );
   1755 			params->frame.content.iePacket.pUnknownIe = params->unknownIe;
   1756 			params->frame.content.iePacket.unknownIeLen += readLen;
   1757 			break;
   1758 		}
   1759 		pData += readLen;
   1760 		bodyDataLen -= readLen;
   1761 #if CHECK_PARSING_ERROR_CONDITION_PRINT
   1762 		/* CHECK_PARSING_ERROR_CONDITION((bodyDataLen < 0), ("MLME_PARSER: negative bodyDataLen %d bytes\n", bodyDataLen),TI_TRUE); */
   1763 		if (bodyDataLen < 0)
   1764 		{
   1765 			TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "MLME_PARSER: negative bodyDataLen %d bytes\n", bodyDataLen);
   1766 			TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "Buff len = %d \n", packetLength);
   1767 			report_PrintDump (pPacketBody, packetLength);
   1768 		}
   1769 #endif
   1770 	}
   1771 	return TI_OK;
   1772 }
   1773 
   1774 mlmeIEParsingParams_t *mlmeParser_getParseIEsBuffer(TI_HANDLE *hMlme)
   1775 {
   1776 	return (&(((mlme_t *)hMlme)->tempFrameInfo));
   1777 }
   1778 
   1779 
   1780 /**
   1781 *
   1782 * parseIeBuffer  - Parse a required information element.
   1783 *
   1784 * \b Description:
   1785 *
   1786 * Parse an required information element
   1787 * and returns a pointer to the IE.
   1788  * If given a matching buffer as well, returns a pointer to the first IE
   1789  * that matches the IE ID and the given buffer.
   1790 *
   1791 * \b ARGS:
   1792 *
   1793 *  I   - hOs - pointer to OS context
   1794 *  I   - pIeBuffer - pointer to the IE buffer  \n
   1795 *  I   - length - the length of the whole buffer
   1796 *  I   - desiredIeId - the desired IE ID
   1797 *  O   - pDesiredIe - a pointer to the desired IE
   1798 *  I   - pMatchBuffer - a matching buffer in the IE buffer. Optional, if not required a NULL can be given.
   1799 *  I   - matchBufferLen - the matching buffer length. Optional, if not required zero can be given.
   1800 *
   1801 *
   1802 * \b RETURNS:
   1803 *
   1804 * TI_TRUE if IE pointer was found, TI_FALSE on failure.
   1805 *
   1806 * \sa
   1807 */
   1808 TI_BOOL mlmeParser_ParseIeBuffer (TI_HANDLE hMlme, TI_UINT8 *pIeBuffer, TI_UINT32 length, TI_UINT8 desiredIeId, TI_UINT8 **pDesiredIe, TI_UINT8 *pMatchBuffer, TI_UINT32 matchBufferLen)
   1809 {
   1810     mlme_t  		 *pMlme = (mlme_t *)hMlme;
   1811     dot11_eleHdr_t   *eleHdr;
   1812     TI_UINT8         *pCurIe;
   1813 
   1814 
   1815     if (pDesiredIe!=NULL)
   1816     {
   1817         *pDesiredIe = NULL;
   1818     }
   1819 
   1820     if ((pIeBuffer == NULL) || (length==0))
   1821     {
   1822        return TI_FALSE;
   1823     }
   1824 
   1825     pCurIe = pIeBuffer;
   1826 
   1827     while (length>0)
   1828     {
   1829         eleHdr = (dot11_eleHdr_t*)pCurIe;
   1830 
   1831         if ((TI_UINT8)length < ((*eleHdr)[1] + 2))
   1832         {
   1833             return TI_FALSE;
   1834         }
   1835 
   1836         if ((*eleHdr)[0] == desiredIeId)
   1837         {
   1838             if ((matchBufferLen==0) || (pMatchBuffer == NULL) ||
   1839                 (!os_memoryCompare(pMlme->hOs, &pCurIe[2], pMatchBuffer, matchBufferLen)))
   1840             {
   1841                 if (pDesiredIe!=NULL)
   1842                 {
   1843                     *pDesiredIe = (TI_UINT8*)eleHdr;
   1844                 }
   1845                 return TI_TRUE;
   1846             }
   1847 
   1848         }
   1849         length -= (*eleHdr)[1] + 2;
   1850         pCurIe += (*eleHdr)[1] + 2;
   1851     }
   1852 
   1853     return TI_FALSE;
   1854 }
   1855 
   1856 
   1857