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