1 /**************************************************************************** 2 **+-----------------------------------------------------------------------+** 3 **| |** 4 **| Copyright(c) 1998 - 2008 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 ****************************************************************************/ 35 36 /***************************************************************************/ 37 /* */ 38 /* MODULE: ackEmulUtil.c */ 39 /* PURPOSE: Ack emulation utility */ 40 /* */ 41 /***************************************************************************/ 42 #include "osApi.h" 43 #include "802_11Defs.h" 44 #include "ackEmulDb.h" 45 #include "report.h" 46 #include "utils.h" 47 #include "memMngrEx.h" 48 #include "ackEmulDb.h" 49 #include "ackEmulUtil.h" 50 #include "whalCtrl_api.h" 51 52 53 /* The minimum of segment size in byte to lock the segment size */ 54 #define MIN_LOCK_SEGMENT_SIZE 500 55 56 typedef enum { 57 OTHER =0, 58 TCP_ACK_ONLY , 59 TCP_DATA , 60 } packetInclude_T; 61 62 63 64 #define TI_SNAP_HEADER_LEN 8 65 #define TI_SNAP_AE_TYPE 0x02 66 #define TI_SNAP_AE_LEN 3 67 68 #define OFFSET_802_3_HDR 14 69 70 #define K_FACTOR 14 71 72 /* TI Snap Header */ 73 /* ------------------------------------------- 74 | dsap | SSAP | Control | OUI | Type | 75 | 0xAA | 0xAA | 0x00 | 0x080028 | 0x60D0 | 76 ------------------------------------------- */ 77 78 static UINT8 tiSnapHeader[]={0xAA,0xAA,0x00,0x08,0x00,0x28,0x60,0xD0}; 79 80 static void wdrv_ackEmulationPktType(ackEmul_t* ackEmul, UINT8 *pWlanSnapHeader ,UINT8 *pIpHeader , packetInclude_T *packetInclude, UINT16 *tcpDataSize); 81 static void wdrv_ackEmulationDataStandbyState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader); 82 static void wdrv_ackEmulationAckStandbyState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader); 83 static void wdrv_ackEmulationAckCandidateActivState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader, 84 UINT8 *addYTag, UINT8 *activeIndex, 85 UINT32 *segmentSize); 86 static void wdrv_ackEmulationAckActivState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader,UINT8 *dropAck); 87 static void wdrv_ackEmulationAckTerminateState(ackEmul_t* ackEmul, UINT8 sessionIndex); 88 89 static void wdrv_ackEmulationAddYTag(ackEmul_t* ackEmul, UINT8 *pDot11Header, UINT16 firstBdLength, 90 UINT8 activeIndex, UINT32 segmentSize); 91 92 static int wdrv_aeChackSnapWithYtag(ackEmul_t* ackEmul, UINT8 *pSnapHeader, UINT8 *tiSnapLen, 93 UINT8 *activeIndex, UINT16 *segmentSize); 94 95 static void wdrv_aeGenerateAck(ackEmul_t* ackEmul, UINT16 stationIndex, UINT8 activeIndex ,UINT32 ackNumber); 96 97 98 static UINT16 wdrv_IpChecksumCalc(ackEmul_t* ackEmul, UINT16 len_ip_header, UINT8 *buff); 99 static UINT16 wdrv_TcpChecksumCalc(ackEmul_t* ackEmul, UINT16 len_tcp_header,UINT8 *IpSource, UINT8 *IpDest ,UINT8 *buff); 100 101 102 103 104 ackEmul_t* ackEmul_create(TI_HANDLE hOs) 105 { 106 ackEmul_t* ackEmul; 107 ackEmulDB_t* ackEmulDB; 108 109 if( hOs == NULL ) 110 { 111 WLAN_OS_REPORT(("FATAL ERROR: ackEmul_create(): OS handle Error - Aborting\n")); 112 return NULL; 113 } 114 115 ackEmul = os_memoryAlloc(hOs, (sizeof(ackEmul_t))); 116 117 ackEmulDB = ackEmulDb_create(hOs); 118 119 if ( (!ackEmul) || (!ackEmulDB) ) 120 { 121 utils_nullMemoryFree(hOs, ackEmul, sizeof(ackEmul_t)); 122 utils_nullMemoryFree(hOs, ackEmulDB, sizeof(ackEmulDB_t)); 123 WLAN_OS_REPORT(("FATAL ERROR: ackEmul_create(): Error Creating ackEmulDB module- Aborting\n")); 124 return(NULL); 125 } 126 127 /* reset control module control block */ 128 os_memoryZero(hOs, ackEmul, (sizeof(ackEmul_t))); 129 130 ackEmul->pAckEmulDB = ackEmulDB; 131 132 ackEmul->hOs = hOs; 133 134 return(ackEmul); 135 136 137 } 138 139 TI_STATUS ackEmul_config(ackEmul_t* ackEmul, 140 TI_HANDLE hWhalCtrl, 141 TI_HANDLE hOs, 142 TI_HANDLE hReport, 143 TI_HANDLE hMemMngr) 144 { 145 /* check parameters validity */ 146 if( (ackEmul == NULL) || (hOs == NULL) || (hReport == NULL)|| 147 (hWhalCtrl == NULL) || (hMemMngr == NULL) ) 148 { 149 WLAN_OS_REPORT(("FATAL ERROR: ackEmul_config(): Parameters Error - Aborting\n")); 150 return NOK; 151 } 152 153 /* set objects handles */ 154 ackEmul->hOs = hOs; 155 ackEmul->hReport = hReport; 156 ackEmul->hMemMngr = hMemMngr; 157 ackEmul->hWhalCtrl = hWhalCtrl; 158 159 ackEmul->ackEmulationActive = TRUE; 160 161 ackEmulDb_config(ackEmul->pAckEmulDB,hOs,hReport); 162 163 /*whalCtrl_setSend4xWackInfo(ackEmul->hWhalCtrl, 0); */ 164 165 WLAN_REPORT_INIT(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 166 (".....ackEmul configured successfully\n")); 167 168 return OK; 169 170 } 171 172 TI_STATUS ackEmul_destroy(ackEmul_t* ackEmul) 173 { 174 ackEmulDb_destroy(ackEmul->pAckEmulDB); 175 176 /* free control module controll block */ 177 os_memoryFree(ackEmul->hOs, ackEmul, sizeof(ackEmul_t)); 178 179 return OK; 180 181 182 } 183 184 185 /********************************************************************************** 186 * wdrv_ackEmulationRxPacket() 187 ********************************************************************************** 188 * DESCRIPTION: This is the Ack emulation packet receiver main function. 189 * 190 * INPUTS: *pMsdu - Pointer to the packet MSDU. 191 * 192 * OUTPUT: None 193 * 194 * RETURNS: None 195 **********************************************************************************/ 196 TI_STATUS wdrv_ackEmulationRxPacket(ackEmul_t* ackEmul, mem_MSDU_T *pMsdu) 197 { 198 199 UINT8 rc; 200 UINT8 *dataBuf; 201 dot11_header_t *pDot11Header; 202 UINT8 *pWlanSnapHeader; 203 UINT8 *pSnapHeader; 204 UINT8 *pIpHeader; 205 UINT16 tcpDataSize; 206 packetInclude_T packetInclude; 207 UINT8 sessionIndex, monitorState; 208 UINT8 activeIndex = 0xff; 209 UINT16 segmentSize = 0; 210 UINT8 tiSnapLen = 0; 211 UINT16 dataLen; 212 UINT8 WTsessionIndex =0xff; 213 UINT8 XTag =0; 214 215 216 if (ackEmul->ackEmulationActive == FALSE) 217 return OK; 218 219 220 dataBuf = (UINT8 *)memMgr_BufData(pMsdu->firstBDPtr)+ memMgr_BufOffset(pMsdu->firstBDPtr); 221 dataLen = memMgr_BufLength(pMsdu->firstBDPtr); 222 pDot11Header = (dot11_header_t*) dataBuf; 223 /* Find the station Index */ 224 225 226 XTag = ((pDot11Header->fc)&0x8000)>>15; 227 pSnapHeader = dataBuf + WLAN_HDR_LEN; 228 229 pWlanSnapHeader = dataBuf + WLAN_HDR_LEN; 230 pIpHeader = pWlanSnapHeader + WLAN_SNAP_HDR_LEN; 231 232 /* Chack if SNAP with Y TAG */ 233 rc = wdrv_aeChackSnapWithYtag(ackEmul, pSnapHeader, &tiSnapLen, &activeIndex, &segmentSize); 234 if(rc == OK) 235 { 236 WLAN_REPORT_WARNING(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 237 ("Packet with Ytag........\n")); 238 239 /* remove the TI SMAP */ 240 os_memoryMove(NULL, pSnapHeader,pSnapHeader + tiSnapLen, dataLen - WLAN_HDR_LEN - tiSnapLen); 241 pMsdu->firstBDPtr->length -= tiSnapLen ; 242 pMsdu->dataLen -= tiSnapLen; 243 244 /* Update table and save template */ 245 wdrv_aeWSourceSaveAckTemplate(ackEmul->pAckEmulDB, 0,activeIndex,dataBuf,pWlanSnapHeader,pIpHeader,(UINT16)pMsdu->dataLen,segmentSize); 246 247 248 return OK; 249 } 250 251 /* Packet without ack emulation TI Snap */ 252 253 /* Find the packet type and length */ 254 wdrv_ackEmulationPktType(ackEmul, pWlanSnapHeader,pIpHeader,&packetInclude,&tcpDataSize); 255 256 switch (packetInclude) 257 { 258 case TCP_DATA: 259 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 260 ("RX packet = TCP_DATA....\n")); 261 262 rc = wdrv_aeWTargetDbFindDataSession(ackEmul->pAckEmulDB, pIpHeader ,&sessionIndex, &monitorState); 263 if(rc == OK) 264 { 265 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 266 ("RX packet XTAG = %d......\n",XTag)); 267 268 wdrv_aeDbSetXTagStatus(ackEmul->pAckEmulDB, sessionIndex, XTag); 269 } 270 switch (monitorState) 271 { 272 case AE_INACTIVE: 273 rc = wdrv_aeWTargetDbAddSession(ackEmul->pAckEmulDB, pIpHeader); 274 275 break; 276 case AE_STANDBY: 277 wdrv_ackEmulationDataStandbyState(ackEmul, sessionIndex, pIpHeader); 278 break; 279 case AE_CANDIDATE_ACTIVE: 280 break; 281 case AE_ACTIVE: 282 default: 283 break; 284 } 285 /* printf("\n rc= %d sessionIndex = %d monitorState = %d\n",rc, sessionIndex , monitorState);*/ 286 break; 287 case TCP_ACK_ONLY: 288 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 289 ("RX packet = TCP_ACK_ONLY....\n")); 290 291 wdrv_aeWSourceDbUpdateTemplate(ackEmul->pAckEmulDB, pIpHeader,0,&WTsessionIndex); 292 break; 293 case OTHER: 294 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 295 ("RX packet = OTHER....\n")); 296 297 default: 298 break; 299 } 300 /*wdrv_aeWTargetDbPrint(ackEmul->pAckEmulDB);*/ 301 return OK; 302 } 303 304 305 /********************************************************************************** 306 * wdrv_ackEmulationTxPacket() 307 ********************************************************************************** 308 * DESCRIPTION: This is the Ack emulation packet transmission main function. 309 * 310 * INPUTS: *pMsdu - Pointer to the packet MSDU. 311 * 312 * OUTPUT: *discardPacket - If TRUE discard the msdu. 313 * 314 * RETURNS: None 315 **********************************************************************************/ 316 TI_STATUS wdrv_ackEmulationTxPacket(ackEmul_t* ackEmul, mem_MSDU_T *pMsdu,int *discardPacket) 317 { 318 UINT8 *pDot11Header; 319 UINT8 *pWlanSnapHeader; 320 UINT8 *pIpHeader; 321 UINT16 tcpDataSize; 322 packetInclude_T packetInclude; 323 UINT8 sessionIndex = 0xff; 324 UINT8 monitorState = 0xff; 325 UINT8 addYTag =FALSE; 326 UINT8 dropAck =FALSE; 327 UINT16 firstBdLength = 0; 328 UINT32 firstBddataOffset = 0; 329 UINT32 secondBddataOffset = 0; 330 UINT8 activeIndex = 0xff; 331 UINT32 segmentSize = 0; 332 333 *discardPacket = FALSE; 334 pIpHeader = NULL; 335 336 337 if (ackEmul->ackEmulationActive == FALSE) 338 return OK; 339 340 firstBdLength = memMgr_BufLength(pMsdu->firstBDPtr); 341 firstBddataOffset = memMgr_BufOffset(pMsdu->firstBDPtr) ; 342 pDot11Header = (UINT8 *)memMgr_BufData(pMsdu->firstBDPtr)+firstBddataOffset; 343 344 if (firstBdLength == WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN) 345 { 346 /* Packet from Ethernet, the IP heder is in the second data buffer */ 347 if(pMsdu->firstBDPtr->nextBDPtr != NULL) 348 { 349 secondBddataOffset = memMgr_BufOffset(pMsdu->firstBDPtr->nextBDPtr); 350 pIpHeader = (UINT8 *)memMgr_BufData(pMsdu->firstBDPtr->nextBDPtr)+ secondBddataOffset; 351 } 352 } 353 else 354 { 355 /* Packet from Wlan */ 356 pIpHeader = pDot11Header + WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN; 357 } 358 359 pWlanSnapHeader = pDot11Header + WLAN_HDR_LEN; 360 361 /* Find the packet type and length */ 362 wdrv_ackEmulationPktType(ackEmul, pWlanSnapHeader,pIpHeader ,&packetInclude,&tcpDataSize); 363 364 switch (packetInclude) 365 { 366 case TCP_ACK_ONLY: 367 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 368 ("TX packet = TCP_ACK_ONLY....\n")); 369 370 371 wdrv_aeWTargetDbFindAckSession(ackEmul->pAckEmulDB, pIpHeader ,&sessionIndex, &monitorState); 372 373 switch (monitorState) 374 { 375 case AE_INACTIVE: 376 377 break; 378 case AE_STANDBY: 379 380 wdrv_ackEmulationAckStandbyState(ackEmul, sessionIndex, pIpHeader); 381 break; 382 case AE_CANDIDATE_ACTIVE: 383 wdrv_ackEmulationAckCandidateActivState(ackEmul, sessionIndex, 384 pIpHeader, 385 &addYTag, 386 &activeIndex, 387 &segmentSize); 388 if(addYTag == TRUE) 389 { 390 wdrv_ackEmulationAddYTag(ackEmul, pDot11Header, firstBdLength, activeIndex, segmentSize); 391 392 /* update the MSDU fields */ 393 pMsdu->firstBDPtr->length += TI_SNAP_HEADER_LEN+2+TI_SNAP_AE_LEN; 394 pMsdu->dataLen += TI_SNAP_HEADER_LEN+2+TI_SNAP_AE_LEN; 395 } 396 397 break; 398 case AE_ACTIVE: 399 /* Comper Template and drop packet */ 400 wdrv_ackEmulationAckActivState(ackEmul, sessionIndex, pIpHeader,&dropAck); 401 402 *discardPacket = dropAck; 403 break; 404 405 case AE_TERMINATE: 406 wdrv_ackEmulationAckTerminateState(ackEmul, sessionIndex); 407 408 break; 409 default: 410 411 break; 412 } 413 414 break; 415 case TCP_DATA: 416 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 417 ("TX packet = TCP_DATA....\n")); 418 419 break; 420 case OTHER: 421 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 422 ("TX packet = OTHER....\n")); 423 default: 424 break; 425 } 426 return OK; 427 } 428 429 430 431 /********************************************************************************** 432 * wdrv_ackEmulationPktType() 433 ********************************************************************************** 434 * DESCRIPTION: Find the packet type and length. 435 * 436 * INPUTS: pWlanSnapHeader - Pointer to the 802.11 SNAP header buffer. 437 * pIpHeader - Pointer to the ip header header buffer. 438 * 439 * OUTPUT: packetInclude - The packet type, TCP_DATA, TCP_ACK_ONLY or OTHER 440 * tcpDataSize - The packet size (only for tcp packet) 441 * 442 * RETURNS: None 443 **********************************************************************************/ 444 static void wdrv_ackEmulationPktType(ackEmul_t* ackEmul, UINT8 *pWlanSnapHeader ,UINT8 *pIpHeader , 445 packetInclude_T *packetInclude, UINT16 *tcpDataSize) 446 { 447 UINT16 pktTotalLen; 448 UINT8 ipHeaderLen, tcpHeaderLen; 449 450 *tcpDataSize =0; 451 452 453 454 /* Check if the packet is TCP/IP */ 455 if ((wlan_ntohs(((Wlan_LlcHeader_T*)pWlanSnapHeader)->Type) == IP_PROTOCOL_NUMBER) && 456 (*(unsigned char*) ((ULONG)pIpHeader+(ULONG)IP_PROTOCOL_FIELD)== TCP_PROTOCOL)) 457 { 458 /* Check if the packet include data or Ack only */ 459 pktTotalLen = wlan_ntohs((*(UINT16*)(pIpHeader + IP_TOTAL_LEN_FIELD))); 460 ipHeaderLen = ((*(unsigned char*)pIpHeader & 0x0f) * 4); 461 tcpHeaderLen = ((((*(unsigned char*)(pIpHeader + ipHeaderLen+TCP_OFFSET_FIELD))& 0xf0)>>4) * 4); 462 *tcpDataSize = pktTotalLen - (ipHeaderLen + tcpHeaderLen); 463 464 if(*tcpDataSize > 0) 465 *packetInclude = TCP_DATA; 466 else 467 *packetInclude = TCP_ACK_ONLY; 468 469 } 470 else 471 { 472 *packetInclude = OTHER; 473 } 474 475 } 476 477 478 479 /********************************************************************************** 480 * wdrv_ackEmulationDataStandbyState() 481 ********************************************************************************** 482 * DESCRIPTION: This function handle the tcp date packet for session in 483 * standby state. 484 * 485 * INPUTS: sessionIndex - the session index 486 * *pIpHeader - Pointer to the ip header header buffer. 487 * 488 * OUTPUT: None. 489 * 490 * RETURNS: None 491 **********************************************************************************/ 492 static void wdrv_ackEmulationDataStandbyState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader) 493 { 494 UINT8 ipHeaderLen = 0; 495 496 UINT32 prevSequenceNumber =0; 497 UINT32 currentSequenceNumber =0; 498 499 UINT32 prevSegmentSize = 0; 500 UINT32 currentSegmentSize =0; 501 502 UINT8 equalSegmentSizeCounter =0; 503 504 505 506 /* Calculate Current Sequence Number */ 507 ipHeaderLen = ((*(unsigned char*)pIpHeader & 0x0f) * 4); 508 currentSequenceNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_SEQUENCE_NUMBER_FIELD)); 509 510 wdrv_aeWTargetDbGetSessionSequenceNumber(ackEmul->pAckEmulDB, sessionIndex,&prevSequenceNumber); 511 /* Calclate Segment Size */ 512 wdrv_aeWTargetDbGetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,&prevSegmentSize); 513 currentSegmentSize = currentSequenceNumber - prevSequenceNumber; 514 515 if (prevSegmentSize == currentSegmentSize) 516 { 517 /* Increase Equal Segment Size Counter */ 518 wdrv_aeWTargetDbGetIncrSessionEqualSegmentSizeCounter(ackEmul->pAckEmulDB, sessionIndex,&equalSegmentSizeCounter); 519 if(equalSegmentSizeCounter == 2 && currentSegmentSize > MIN_LOCK_SEGMENT_SIZE) 520 { 521 /* Monitor state -> AE_CANDIDATE_ACTIVE */ 522 /* printf("\n Session %d chabge state to AE_CANDIDATE_ACTIVE with segment size %d\n", 523 sessionIndex, 524 currentSegmentSize);*/ 525 wdrv_aeWTargetDbSetSessionMonitorState(ackEmul->pAckEmulDB, sessionIndex,AE_CANDIDATE_ACTIVE); 526 } 527 528 } 529 else 530 { 531 wdrv_aeWTargetDbSetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,currentSegmentSize); 532 wdrv_aeWTargetDbSetSessionEqualSegmentSizeCounter(ackEmul->pAckEmulDB, sessionIndex,0); 533 } 534 535 wdrv_aeWTargetDbSetSessionSequenceNumber(ackEmul->pAckEmulDB, sessionIndex,currentSequenceNumber); 536 } 537 538 539 /********************************************************************************** 540 * wdrv_ackEmulationAckStandbyState() 541 ********************************************************************************** 542 * DESCRIPTION: This function handle the tcp ack packet for session in 543 * standby state. 544 * 545 * INPUTS: sessionIndex - the session index 546 * *pIpHeader - Pointer to the ip header header buffer. 547 * 548 * OUTPUT: None. 549 * 550 * RETURNS: None 551 **********************************************************************************/ 552 static void wdrv_ackEmulationAckStandbyState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader) 553 { 554 555 UINT8 ipHeaderLen = 0; 556 UINT32 currentAckNumber =0; 557 558 /* Calculate Current Ack Number */ 559 ipHeaderLen = ((*(unsigned char*)pIpHeader & 0x0f) * 4); 560 currentAckNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_ACK_NUMBER_FIELD)); 561 562 /* Set Current Ack Number */ 563 wdrv_aeWTargetDbSetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,currentAckNumber); 564 565 566 567 } 568 569 /********************************************************************************** 570 * wdrv_ackEmulationAckCandidateActivState() 571 ********************************************************************************** 572 * DESCRIPTION: This function handle the tcp ack packet for session in 573 * candidate activ state. 574 * 575 * INPUTS: sessionIndex - the session index 576 * *pIpHeader - Pointer to the ip header header buffer. 577 * 578 * OUTPUT: *addYTag - If true, add Ytag to the tcp acp packet 579 * *activeIndex - The activeIndex that assign for this session 580 * *segmentSize - The segment size of this tcp session. 581 * 582 * RETURNS: None 583 **********************************************************************************/ 584 static void wdrv_ackEmulationAckCandidateActivState(ackEmul_t* ackEmul, UINT8 sessionIndex, 585 UINT8 *pIpHeader, 586 UINT8 *addYTag, 587 UINT8 *activeIndex, 588 UINT32 *segmentSize) 589 { 590 591 UINT8 ipHeaderLen = 0; 592 UINT32 prevAckNumber =0; 593 UINT32 currentAckNumber =0; 594 UINT32 ackCounter =0; 595 596 /* Calculate Current Ack Number */ 597 ipHeaderLen = ((*(unsigned char*)pIpHeader & 0x0f) * 4); 598 currentAckNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_ACK_NUMBER_FIELD)); 599 600 wdrv_aeWTargetDbGetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,segmentSize); 601 wdrv_aeWTargetDbGetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,&prevAckNumber); 602 603 if((currentAckNumber - prevAckNumber) == *segmentSize *2) 604 { 605 WLAN_REPORT_FATAL_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 606 ("Change State to active............\n")); 607 /* Change state to Active and update Active index */ 608 if(wdrv_aeWTargetDbSetActiveState(ackEmul->pAckEmulDB, sessionIndex, activeIndex) == OK) 609 { 610 611 612 /* Calculate Ack Counter */ 613 ackCounter = currentAckNumber / (*segmentSize *2); 614 wdrv_aeWTargetDbSetSessionAckCounter(ackEmul->pAckEmulDB, sessionIndex,ackCounter) ; 615 /* Save template update Active index */ 616 wdrv_aeWTargetDbSaveAckTemplate(ackEmul->pAckEmulDB, sessionIndex,pIpHeader); 617 /* add addYTag */ 618 619 WLAN_REPORT_FATAL_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 620 ("ADD Y TAG.........!!!!!!!!!!!!\n")); 621 622 *addYTag = TRUE; 623 624 } 625 } 626 wdrv_aeWTargetDbSetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,currentAckNumber); 627 628 } 629 630 /********************************************************************************** 631 * wdrv_ackEmulationAckActivState() 632 ********************************************************************************** 633 * DESCRIPTION: This function handle the tcp ack packet for session in 634 * active state. 635 * 636 * INPUTS: sessionIndex - the session index 637 * *pIpHeader - Pointer to the ip header header buffer. 638 * 639 * OUTPUT: *dropAck - If TRUE discard the packet. 640 * 641 * RETURNS: None 642 **********************************************************************************/ 643 static void wdrv_ackEmulationAckActivState(ackEmul_t* ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader,UINT8 *dropAck) 644 { 645 int rc =NOK; 646 647 UINT8 ipHeaderLen = 0; 648 UINT32 currentAckNumber =0; 649 UINT32 prevAckNumber =0; 650 UINT32 segmentSize =0; 651 UINT32 currentAckCounter =0; 652 UINT32 prevAckCounter =0; 653 UINT8 activeIndex = 0xff; 654 UINT32 segmentNumber = 0; 655 UINT32 prevTimeStamp; 656 UINT32 currentTimeStamp; 657 UINT8 newWackInfo = 0; 658 UINT8 prevWackInfo; 659 UINT8 prevOwnershipBit; 660 UINT8 prevActvIndxBits; 661 UINT8 prevAckCounterBits; 662 663 664 currentTimeStamp =os_timeStampUs(ackEmul->hOs); 665 666 wdrv_aeWTargetDbGetSessionTimeStamp(ackEmul->pAckEmulDB, sessionIndex, &prevTimeStamp); 667 if(prevTimeStamp != 0) 668 { 669 if((WTARGET_ACTIVE_TIME_OUT) < (currentTimeStamp - prevTimeStamp)) 670 { /* If the delay between two ack packet for the same session grater */ 671 /* than WTARGET_ACTIVE_TIME_OUT change session state to terminate */ 672 wdrv_aeWTargetDbSetSessionMonitorState(ackEmul->pAckEmulDB, sessionIndex,AE_TERMINATE); 673 /*WLAN_OS_REPORT(("1\n"));*/ 674 return; 675 } 676 } 677 678 679 /* extract the information from prevWackInfo */ 680 681 whalCtrl_getSend4xWackInfo(ackEmul->hWhalCtrl, &prevWackInfo); 682 prevAckCounterBits = (prevWackInfo&0x0f); 683 prevActvIndxBits = (prevWackInfo&0x10)>>4; 684 prevOwnershipBit = (prevWackInfo&0x80)>>7; 685 686 /* Calculate Current Ack Number */ 687 ipHeaderLen = ((*(unsigned char*)pIpHeader & 0x0f) * 4); 688 currentAckNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_ACK_NUMBER_FIELD)); 689 690 wdrv_aeWTargetDbGetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,&segmentSize); 691 wdrv_aeWTargetDbGetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,&prevAckNumber); 692 693 wdrv_aeWTargetDbGetSessionAckCounter(ackEmul->pAckEmulDB, sessionIndex, &prevAckCounter) ; 694 wdrv_aeWTargetDbGetSessionActiveIndex(ackEmul->pAckEmulDB, sessionIndex, &activeIndex); 695 696 /* Calculate Ack Counter */ 697 currentAckCounter = currentAckNumber / (segmentSize*2); 698 if((currentAckNumber - prevAckNumber) == segmentSize *2) 699 { 700 /*WLAN_OS_REPORT(("--2\n"));*/ 701 702 if ((currentAckCounter > prevAckCounter) && (currentAckCounter < prevAckCounter + 5)) 703 { 704 /*WLAN_OS_REPORT(("----3\n"));*/ 705 rc = wdrv_aeWTargetDbCmpAckTemplate(ackEmul->pAckEmulDB, sessionIndex, pIpHeader); 706 if (rc == OK) 707 { 708 /* drop this Ack */ 709 710 UINT8 Xtag; 711 712 wdrv_aeDbGetXTagStatus(ackEmul->pAckEmulDB, sessionIndex,&Xtag); 713 /*WLAN_OS_REPORT(("------4 Xtag=%d prevOwnershipBit=%d activeIndex=%d prevActvIndxBits=%d\n",Xtag,prevOwnershipBit,activeIndex,prevActvIndxBits));*/ 714 if (((prevOwnershipBit == 1)|| (activeIndex == prevActvIndxBits)) && Xtag) 715 { 716 *dropAck = TRUE; 717 718 } 719 } 720 } 721 } 722 else 723 { 724 /*WLAN_OS_REPORT(("------99 prevAckNumber=%d,currentAckCounter=%d currentAckNumber=%d segmentSize=%d \n",*/ 725 /* prevAckNumber, currentAckCounter, currentAckNumber, segmentSize));*/ 726 } 727 728 WLAN_REPORT_FATAL_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 729 ("dropAck = %d\n",*dropAck)); 730 731 if(*dropAck == TRUE) 732 { 733 newWackInfo = (((currentAckCounter % K_FACTOR)+1)&0xf); /* Add currentAckCounter MOD K_FACTOR to bit 0-3 */ 734 newWackInfo = newWackInfo | (activeIndex << 4); /* Add activeIndex to bit 4 */ 735 whalCtrl_setSend4xWackInfo(ackEmul->hWhalCtrl, newWackInfo); 736 wdrv_aeWTargetDbSetSessionTimeStamp(ackEmul->pAckEmulDB, sessionIndex, currentTimeStamp); 737 } 738 else 739 { 740 741 if((prevAckNumber % (segmentSize*2))>(currentAckNumber % (segmentSize*2))) 742 { 743 /* Ack Reorder Problem */ 744 newWackInfo = 0xF; 745 } 746 else 747 { 748 if(prevAckCounterBits == 0xF) 749 { 750 /* chack if this wack info send */ 751 if(prevOwnershipBit == 1) 752 newWackInfo = 0; 753 } 754 else 755 { 756 newWackInfo = 0; 757 } 758 } 759 newWackInfo = newWackInfo | (activeIndex << 4); /* Add activeIndex to bit 4 */ 760 whalCtrl_setSend4xWackInfo(ackEmul->hWhalCtrl, newWackInfo); 761 762 wdrv_aeWTargetDbSetSessionAckCounter(ackEmul->pAckEmulDB, sessionIndex,currentAckCounter) ; 763 764 } 765 wdrv_aeWTargetDbSetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,currentAckNumber); 766 segmentNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_SEQUENCE_NUMBER_FIELD)); 767 wdrv_aeWTargetDbUpdateAckTemplate(ackEmul->pAckEmulDB, sessionIndex,segmentNumber); 768 769 } 770 771 772 /********************************************************************************** 773 * wdrv_ackEmulationAckTerminateState() 774 ********************************************************************************** 775 * DESCRIPTION: This function handle the tcp ack packet for session in 776 * terminate state. 777 * 778 * INPUTS: sessionIndex - 779 * 780 * OUTPUT: None 781 * 782 * RETURNS: None 783 **********************************************************************************/ 784 static void wdrv_ackEmulationAckTerminateState(ackEmul_t* ackEmul, UINT8 sessionIndex) 785 { 786 UINT32 prevTimeStamp; 787 UINT32 currentTimeStamp = os_timeStampUs(ackEmul->hOs); 788 789 wdrv_aeWTargetDbGetSessionTimeStamp(ackEmul->pAckEmulDB, sessionIndex, &prevTimeStamp); 790 if(prevTimeStamp != 0) 791 { 792 if((WTARGET_TERMINATE_TIME_OUT) < (currentTimeStamp - prevTimeStamp)) 793 { 794 /* Reset Session */ 795 wdrv_aeWTargetDbResetTuple(ackEmul->pAckEmulDB, sessionIndex); 796 } 797 } 798 return; 799 } 800 801 /********************************************************************************** 802 * wdrv_ackEmulationAddYTag() 803 ********************************************************************************** 804 * DESCRIPTION: Add Ytag to the Tcp Ack PAcket 805 * 806 * INPUTS: *pDot11Header - Pointer to the 802.11 heder 807 * firstBdLength - The length of the first BD 808 * activeIndex - The active index of the monitor session. 809 * segmentSize - The segmentSize of the monitor session. 810 * 811 * OUTPUT: None 812 * 813 * RETURNS: None 814 **********************************************************************************/ 815 816 /* Tcp Ack without Ytag */ 817 /* ------------------------------------------- 818 | 802.11 | SSAP | IP | TCP | Payload | 819 | header | | header | header | | 820 ------------------------------------------- */ 821 /* Tcp Ack with Ytag */ 822 /* --------------------------------------------------------- 823 | 802.11 | TI | 802.11 SNAP | IP | TCP | Payload | 824 | header | SNAP | header | header | header | | 825 --------------------------------------------------------- */ 826 827 828 /* TI Snap */ 829 /* ------------------------------------------------------------------------- 830 | dsap | SSAP | Control | OUI | Type | AE | AE |Active |Segment | 831 | 0xAA | 0xAA | 0x00 | 0x080028 | 0x60D0 | Type | Len | Index | Size | 832 ------------------------------------------------------------------------- */ 833 834 835 static void wdrv_ackEmulationAddYTag(ackEmul_t* ackEmul, UINT8 *pDot11Header, UINT16 firstBdLength, 836 UINT8 activeIndex, UINT32 segmentSize) 837 { 838 UINT8 *tempPtr; 839 UINT32 moveLen; 840 841 tempPtr = pDot11Header + WLAN_HDR_LEN; 842 moveLen = firstBdLength - WLAN_HDR_LEN; 843 os_memoryMove(NULL, tempPtr+TI_SNAP_HEADER_LEN+2+TI_SNAP_AE_LEN ,tempPtr,moveLen); 844 os_memoryCopy(NULL, tempPtr,tiSnapHeader,TI_SNAP_HEADER_LEN); 845 tempPtr += TI_SNAP_HEADER_LEN; 846 *(UINT8*)tempPtr = TI_SNAP_AE_TYPE; 847 tempPtr ++; 848 *(UINT8*)tempPtr = TI_SNAP_AE_LEN; /* Length */ 849 tempPtr ++; 850 *(UINT8*)tempPtr = activeIndex; /* Active Index */ 851 tempPtr ++; 852 *(UINT16*)tempPtr = wlan_ntohs((UINT16)segmentSize); /* Segment Size */ 853 } 854 855 /********************************************************************************** 856 * wdrv_aeChackSnapWithYtag() 857 ********************************************************************************** 858 * DESCRIPTION: Check if the packet include Ytag 859 * 860 * INPUTS: *pSnapHeader - Pointer to the SNAP heder 861 * 862 * OUTPUT: *tiSnapLen - The length of the first BD 863 * *activeIndex - The active index. 864 * *segmentSize - The segmentSize. 865 * 866 * RETURNS: Ok if include Ytag, otherwise NOK 867 **********************************************************************************/ 868 static int wdrv_aeChackSnapWithYtag(ackEmul_t* ackEmul, UINT8 *pSnapHeader, UINT8 *tiSnapLen, 869 UINT8 *activeIndex, UINT16 *segmentSize) 870 { 871 872 /* Chack if SNAP with Y TAG */ 873 if ((os_memoryCompare(ackEmul->hOs, pSnapHeader,tiSnapHeader,TI_SNAP_HEADER_LEN)== 0)&& 874 (*(UINT8*)(pSnapHeader + TI_SNAP_HEADER_LEN) == TI_SNAP_AE_TYPE)) 875 { 876 877 /* This packet include Ack with Y TAG */ 878 UINT8* tempPtr; 879 UINT8 templen; 880 tempPtr = pSnapHeader + TI_SNAP_HEADER_LEN+1; 881 templen = *(UINT8*)tempPtr; 882 *tiSnapLen = TI_SNAP_HEADER_LEN + 2 + templen; 883 tempPtr ++; 884 *activeIndex = (UINT8)(wlan_ntohs(*(UINT16*)tempPtr)); 885 tempPtr +=2; 886 *segmentSize = (UINT16)(wlan_ntohl(*(UINT32*)tempPtr)); 887 return OK; 888 } 889 else 890 { 891 return NOK; 892 } 893 } 894 895 int genera = 0; 896 int modulo_off = 0; 897 int mod_off = 0; 898 int mod_on = 0; 899 900 /********************************************************************************** 901 * wdrv_aeWackReceive() 902 ********************************************************************************** 903 * DESCRIPTION: Parse the wack info and generate emulated tcp ack 904 * 905 * INPUTS: station - The wack source station index. 906 * wackInfo - The wackInfo 907 * 908 * OUTPUT: None 909 * 910 * RETURNS: None 911 **********************************************************************************/ 912 void wdrv_aeWackReceive(ackEmul_t* ackEmul, UINT16 station, UINT8 wackInfo) 913 { 914 UINT8 ackCounterlowBits; 915 UINT8 activeIndex; 916 UINT32 oldAckNumber; 917 UINT32 newAckNumber; 918 UINT32 oldAckCounter; 919 UINT32 newAckCounter; 920 UINT32 segmentSize; 921 UINT32 prevWackTimeStamp; 922 UINT32 currentWackTimeStamp; 923 UINT32 reorderProblemStatus; 924 925 static UINT8 prev_wackInfo = 0xff; 926 927 if(prev_wackInfo != wackInfo) 928 { 929 prev_wackInfo = wackInfo; 930 931 932 /* extract the information from wackInfo */ 933 ackCounterlowBits = (wackInfo & 0xf); 934 activeIndex = (wackInfo & 0x10) >> 4; 935 936 937 if (ackCounterlowBits == 0) 938 ackCounterlowBits = 0xF; 939 else 940 ackCounterlowBits --; 941 942 943 if(ackCounterlowBits == 0xF) 944 return; 945 946 if(ackCounterlowBits == 0xE) 947 { 948 /* Reorder problem is possible */ 949 wdrv_aeWSourceDbSetSessionAckReorderProblem(ackEmul->pAckEmulDB, station,activeIndex,REORDER_PROBLEM_ON); 950 return; 951 } 952 wdrv_aeWSourceDbGetSessionTimeStamp(ackEmul->pAckEmulDB, station,activeIndex,&prevWackTimeStamp); 953 if(prevWackTimeStamp != 0) 954 { 955 currentWackTimeStamp = os_timeStampUs(ackEmul->hOs); 956 957 if((WSOURCE_SESSION_TIME_OUT) < (currentWackTimeStamp - prevWackTimeStamp)) 958 { 959 /* reset Wsource session */ 960 /*WLAN_OS_REPORT((" Reset Wsource session activeIndex %\n",activeIndex));*/ 961 962 wdrv_aeWSourceDbResetSession(ackEmul->pAckEmulDB, station, activeIndex); 963 964 return; 965 } 966 967 wdrv_aeWSourceDbSetSessionTimeStamp(ackEmul->pAckEmulDB, station,activeIndex,currentWackTimeStamp); 968 969 wdrv_aeWSourceDbGetSessionSegmentSize(ackEmul->pAckEmulDB, station,activeIndex,&segmentSize); 970 971 if(segmentSize != 0) 972 { 973 wdrv_aeWSourceDbGetSessionAckNumber(ackEmul->pAckEmulDB, station,activeIndex,&oldAckNumber); 974 wdrv_aeWSourceDbGetSessionAckCounter(ackEmul->pAckEmulDB, station,activeIndex,&oldAckCounter); 975 976 /* newACK_counter = (Low_counter - (oldACK_counter mod 2^k) + 2^k + 3) mod 2^k - 3 + oldACK_counter*/ 977 newAckCounter = ((ackCounterlowBits - (oldAckCounter % K_FACTOR) + K_FACTOR + 3) % K_FACTOR) -3 + oldAckCounter; 978 979 if(newAckCounter <= oldAckCounter) 980 return; 981 982 wdrv_aeWSourceDbGetSessionAckReorderProblem(ackEmul->pAckEmulDB, station,activeIndex,&reorderProblemStatus); 983 984 if(reorderProblemStatus == REORDER_PROBLEM_ON) 985 { 986 newAckNumber = (newAckCounter * (segmentSize*2)); 987 } 988 else 989 { 990 /* newACK_number = oldACK_number mod (Segment_Size*2) + Rx_Ack_count * (Segment_Size*2)*/ 991 newAckNumber = (oldAckNumber % (segmentSize*2)) + (newAckCounter * (segmentSize*2)); 992 } 993 /* Generate ack */ 994 genera++; 995 wdrv_aeGenerateAck(ackEmul, station,activeIndex,newAckNumber); 996 997 wdrv_aeWSourceDbSetSessionAckNumber(ackEmul->pAckEmulDB, station,activeIndex,newAckNumber); 998 wdrv_aeWSourceDbSetSessionAckCounter(ackEmul->pAckEmulDB, station,activeIndex,newAckCounter); 999 } 1000 return; 1001 1002 } 1003 1004 } 1005 } 1006 /********************************************************************************** 1007 * wdrv_aeGenerateAck() 1008 ********************************************************************************** 1009 * DESCRIPTION: Generate emulated TCP Ack 1010 * 1011 * INPUTS: sessionIndex - 1012 * activeIndex 1013 * ackNumber 1014 * 1015 * OUTPUT: None 1016 * 1017 * RETURNS: None 1018 **********************************************************************************/ 1019 static void wdrv_aeGenerateAck(ackEmul_t* ackEmul, UINT16 stationIndex, UINT8 activeIndex ,UINT32 ackNumber) 1020 { 1021 mem_MSDU_T *pMsdu; 1022 UINT8 ipHeaderLen; 1023 UINT8 tcpHeaderLen; 1024 UINT8 *pTeplate; 1025 UINT8 *pNewPkt; 1026 UINT16 newPktLen; 1027 UINT8 *ipSource, *ipDest; 1028 UINT8 *pIpHeader, *pTcpHeader; 1029 UINT16 ipChecksum =0; 1030 UINT16 tcpChecksum =0; 1031 1032 dot11_header_t *pDot11Header; 1033 UINT8 *pDAddr,*pSAddr; 1034 1035 WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG, 1036 ("wdrv_aeGenerateAck....==============================================\n")); 1037 1038 wdrv_aeWSourceDbGetAckTemplate(ackEmul->pAckEmulDB, stationIndex, activeIndex, &pTeplate,&ipHeaderLen, &tcpHeaderLen); 1039 if(ipHeaderLen > 0) 1040 { 1041 newPktLen = ipHeaderLen+tcpHeaderLen; 1042 if(wlan_memMngrAllocMSDU(ackEmul->hMemMngr, &pMsdu,newPktLen+OFFSET_802_3_HDR,(allocatingModule_e)(ACK_EMUL_MODULE+ sizeof(DbTescriptor)))==NOK) 1043 { 1044 WLAN_OS_REPORT(( "WDRV_4X: GenerateAck - fail to allocate buildMsduPtr\n")); 1045 return; 1046 } 1047 pNewPkt = (UINT8*)memMgr_BufData(pMsdu->firstBDPtr)+ sizeof(DbTescriptor); 1048 1049 os_memoryCopy(ackEmul->hOs, pNewPkt + OFFSET_802_3_HDR -2,pTeplate + WLAN_HDR_LEN+WLAN_SNAP_HDR_LEN -2,newPktLen+2); 1050 1051 /* Extract Info from frame header */ 1052 pDot11Header = (dot11_header_t *)pTeplate; 1053 1054 pDAddr = (UINT8 *)&pDot11Header->address1; 1055 pSAddr = (UINT8 *)((pDot11Header->fc & DOT11_FC_FROM_DS)? &pDot11Header->address3 : &pDot11Header->address2); 1056 1057 pMsdu->firstBDPtr->dataOffset = sizeof(DbTescriptor); 1058 pMsdu->firstBDPtr->length = newPktLen; 1059 pMsdu->dataLen = newPktLen+OFFSET_802_3_HDR; 1060 1061 /* Calclate IP Checksum */ 1062 pIpHeader = pNewPkt+OFFSET_802_3_HDR; 1063 ipChecksum = wdrv_IpChecksumCalc(ackEmul, ipHeaderLen,pIpHeader); 1064 1065 /* Calclate TCP Checksum */ 1066 pTcpHeader = pIpHeader + ipHeaderLen; 1067 *(UINT32*)(pTcpHeader+TCP_ACK_NUMBER_FIELD) = wlan_ntohl(ackNumber); 1068 ipSource = pIpHeader+IP_SRC_ADDRESS_FIELD; 1069 ipDest = pIpHeader+IP_DEST_ADDRESS_FIELD; 1070 tcpChecksum = wdrv_TcpChecksumCalc(ackEmul, tcpHeaderLen, ipSource, ipDest, pTcpHeader); 1071 /* Add the Checksum to the new packet */ 1072 *(UINT16*)(pIpHeader+IP_CHECKSUM_FIELD) = wlan_ntohs(ipChecksum); 1073 *(UINT16*)(pTcpHeader+TCP_CHECKSUM_FIELD) = wlan_ntohs(tcpChecksum); 1074 1075 /* Generate 802.3 Header */ 1076 os_memoryCopy (ackEmul->hOs, pNewPkt, pDAddr, MAC_ADDR_LEN); 1077 os_memoryCopy (ackEmul->hOs, pNewPkt+MAC_ADDR_LEN, pSAddr, MAC_ADDR_LEN); 1078 1079 /* Send the emulated ack to the bss Bridge*/ 1080 os_receivePacket(ackEmul->hOs, pMsdu, (UINT16)pMsdu->dataLen); 1081 } 1082 } 1083 1084 /**************************************************************************** 1085 * wdrv_aeSetActive() 1086 **************************************************************************** 1087 * DESCRIPTION: Enable/ Desable Ack Emulation 1088 * 1089 * INPUTS: 1090 * 1091 * OUTPUT: None 1092 * 1093 * RETURNS: OK or NOK 1094 ****************************************************************************/ 1095 1096 void wdrv_aeSetActive(ackEmul_t* ackEmul, int status) 1097 { 1098 1099 /* if (status == TRUE) 1100 { 1101 (void)whal_apiSetSend4xWackInfo(ackEmul->hWhalCtrl, 0); 1102 (void)whal_apiEnable4xWackFeature(ackEmul->hWhalCtrl); 1103 } 1104 if (status == FALSE) 1105 { 1106 (void)whal_apiSetSend4xWackInfo(ackEmul->hWhalCtrl, 0); 1107 (void)whal_apiDisable4xWackFeature(ackEmul->hWhalCtrl); 1108 } 1109 */ 1110 ackEmul->ackEmulationActive = status; 1111 } 1112 1113 1114 1115 int wdrv_aeGetActive(ackEmul_t* ackEmul ) 1116 { 1117 return(ackEmul->ackEmulationActive); 1118 } 1119 1120 1121 1122 /* 1123 ************************************************************************** 1124 Function: wdrv_IpChecksumCalc 1125 Description: Calculate the 16 bit IP Checksum. 1126 *************************************************************************** 1127 */ 1128 1129 1130 static UINT16 wdrv_IpChecksumCalc(ackEmul_t* ackEmul, UINT16 len_ip_header, UINT8 *buff) 1131 { 1132 UINT16 word16; 1133 UINT32 sum=0; 1134 1135 UINT16 i; 1136 /* make 16 bit words out of every two adjacent 8 bit words in the packet*/ 1137 /* and add them up*/ 1138 for (i=0;i<len_ip_header;i=i+2){ 1139 word16 = wlan_ntohs(*(UINT16*)(buff+i)); 1140 sum = sum + (UINT32) word16; 1141 } 1142 1143 /* take only 16 bits out of the 32 bit sum*/ 1144 /*temp = (sum & 0xffff0000)>>16;*/ 1145 sum = (sum & 0x0000ffff)+((sum & 0xffff0000)>>16); 1146 /* one's complement the result*/ 1147 sum = ~sum; 1148 1149 return ((UINT16) sum); 1150 } 1151 1152 /* 1153 ************************************************************************** 1154 Function: wdrv_TcpChecksumCalc 1155 Description: Calculate the 16 bit TCP Checksum. 1156 *************************************************************************** 1157 */ 1158 1159 static UINT16 wdrv_TcpChecksumCalc(ackEmul_t* ackEmul, UINT16 len_tcp_header,UINT8 *IpSource, UINT8 *IpDest ,UINT8 *buff) 1160 { 1161 UINT16 word16; 1162 UINT32 sum=0; 1163 UINT16 i; 1164 1165 1166 1167 /* add a padding byte = 0 at the end of packet */ 1168 1169 buff[len_tcp_header]=0; 1170 1171 1172 /* make 16 bit words out of every two adjacent 8 bit words in the packet 1173 and add them up */ 1174 for (i=0;i<len_tcp_header;i=i+2){ 1175 word16 = wlan_ntohs(*(UINT16*)(buff+i)); 1176 sum = sum + (UINT32) word16; 1177 } 1178 1179 1180 /* add the TCP pseudo header which contains: 1181 the IP source and destinationn addresses, TCP protocol & TCP length */ 1182 1183 1184 word16 = wlan_ntohs(*(UINT16*)IpSource); 1185 sum = sum + (UINT32) word16; 1186 word16 = wlan_ntohs(*(UINT16*)(IpSource+2)); 1187 sum = sum + (UINT32) word16; 1188 word16 = wlan_ntohs(*(UINT16*)IpDest); 1189 sum = sum + (UINT32) word16; 1190 word16 = wlan_ntohs(*(UINT16*)(IpDest+2)); 1191 sum = sum + (UINT32) word16; 1192 sum = sum + (UINT32)len_tcp_header + 0x06; 1193 1194 1195 1196 1197 /* take only 16 bits out of the 32 bit sum */ 1198 sum = (sum & 0x0000ffff)+((sum & 0xffff0000)>>16); 1199 /* one's complement the result */ 1200 sum = ~sum; 1201 1202 return ((UINT16) sum); 1203 } 1204 1205 1206