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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->rsnIe[0];
1634 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->rsnIe[0];
1643 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->QosCapParams;
1652 status = mlmeParser_readQosCapabilityIE(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->tHtCapabilities;
1658 status = mlmeParser_readHtCapabilitiesIE(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->tHtInformation;
1664 status = mlmeParser_readHtInformationIE(pHandle, pData, bodyDataLen, &readLen, ¶ms->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 = ¶ms->rsnIe[0];
1683 status = mlmeParser_readRsnIe(pHandle, pData, bodyDataLen,
1684 &readLen, ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 ¶ms->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