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