• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 	{
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 
mlmeParser_getFrameType(mlme_t * pMlme,TI_UINT16 * pFrameCtrl,dot11MgmtSubType_e * pType)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
mlmeParser_readXCCOui(TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,XCCv4IEs_t * XCCIEs)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 
mlmeParser_readERP(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,TI_BOOL * useProtection,EPreamble * barkerPreambleMode)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 
mlmeParser_readRates(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_RATES_t * pRates)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 
mlmeParser_readSsid(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_SSID_t * pSsid)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 
mlmeParser_readFhParams(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_FH_PARAMS_t * pFhParams)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 
mlmeParser_readDsParams(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_DS_PARAMS_t * pDsParams)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 
mlmeParser_readCfParams(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_CF_PARAMS_t * pCfParams)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 
mlmeParser_readIbssParams(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_IBSS_PARAMS_t * pIbssParams)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 
mlmeParser_readTim(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_TIM_t * pTim)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 
mlmeParser_readCountry(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_COUNTRY_t * countryIE)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 
mlmeParser_readWMEParams(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_WME_PARAM_t * pWMEParamIE,assocRsp_t * assocRsp)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 
mlmeParser_getWSCReadLen(TI_UINT8 * pData)1180 static TI_UINT32 mlmeParser_getWSCReadLen(TI_UINT8 *pData)
1181 {
1182     return *(pData+1) + 2;
1183 }
1184 
1185 
mlmeParser_readWSCParams(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_WSC_t * pWSC_IE)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 
mlmeParser_readQosCapabilityIE(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_QOS_CAPABILITY_IE_t * QosCapParams)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 
mlmeParser_readHtCapabilitiesIE(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,Tdot11HtCapabilitiesUnparse * pHtCapabilities)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 
mlmeParser_readHtInformationIE(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,Tdot11HtInformationUnparse * pHtInformation)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 
mlmeParser_readChallange(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_CHALLENGE_t * pChallange)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 
mlmeParser_readRsnIe(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_RSN_t * pRsnIe)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 
mlmeParser_readPowerConstraint(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_POWER_CONSTRAINT_t * powerConstraintIE)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 
mlmeParser_readChannelSwitch(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_CHANNEL_SWITCH_t * channelSwitch,TI_UINT8 channel)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 
mlmeParser_readQuiet(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_QUIET_t * quiet)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 
mlmeParser_readTPCReport(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_TPC_REPORT_t * TPCReport)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
mlmeParser_readCellTP(mlme_t * pMlme,TI_UINT8 * pData,TI_UINT32 dataLen,TI_UINT32 * pReadLen,dot11_CELL_TP_t * cellTP)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 
mlmeParser_parseIEs(TI_HANDLE hMlme,TI_UINT8 * pData,TI_INT32 bodyDataLen,mlmeIEParsingParams_t * params)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 
mlmeParser_getParseIEsBuffer(TI_HANDLE * hMlme)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 */
mlmeParser_ParseIeBuffer(TI_HANDLE hMlme,TI_UINT8 * pIeBuffer,TI_UINT32 length,TI_UINT8 desiredIeId,TI_UINT8 ** pDesiredIe,TI_UINT8 * pMatchBuffer,TI_UINT32 matchBufferLen)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