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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->rsnIe[0];
1631 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->rsnIe[0];
1640 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->QosCapParams;
1649 status = mlmeParser_readQosCapabilityIE(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->tHtCapabilities;
1655 status = mlmeParser_readHtCapabilitiesIE(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->tHtInformation;
1661 status = mlmeParser_readHtInformationIE(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->rsnIe[0];
1680 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen,
1681 &readLen, ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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