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
ackEmul_create(TI_HANDLE hOs)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
ackEmul_config(ackEmul_t * ackEmul,TI_HANDLE hWhalCtrl,TI_HANDLE hOs,TI_HANDLE hReport,TI_HANDLE hMemMngr)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
ackEmul_destroy(ackEmul_t * ackEmul)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 **********************************************************************************/
wdrv_ackEmulationRxPacket(ackEmul_t * ackEmul,mem_MSDU_T * pMsdu)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 **********************************************************************************/
wdrv_ackEmulationTxPacket(ackEmul_t * ackEmul,mem_MSDU_T * pMsdu,int * discardPacket)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 **********************************************************************************/
wdrv_ackEmulationPktType(ackEmul_t * ackEmul,UINT8 * pWlanSnapHeader,UINT8 * pIpHeader,packetInclude_T * packetInclude,UINT16 * tcpDataSize)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 **********************************************************************************/
wdrv_ackEmulationDataStandbyState(ackEmul_t * ackEmul,UINT8 sessionIndex,UINT8 * pIpHeader)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 **********************************************************************************/
wdrv_ackEmulationAckStandbyState(ackEmul_t * ackEmul,UINT8 sessionIndex,UINT8 * pIpHeader)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 **********************************************************************************/
wdrv_ackEmulationAckCandidateActivState(ackEmul_t * ackEmul,UINT8 sessionIndex,UINT8 * pIpHeader,UINT8 * addYTag,UINT8 * activeIndex,UINT32 * segmentSize)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 **********************************************************************************/
wdrv_ackEmulationAckActivState(ackEmul_t * ackEmul,UINT8 sessionIndex,UINT8 * pIpHeader,UINT8 * dropAck)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 **********************************************************************************/
wdrv_ackEmulationAckTerminateState(ackEmul_t * ackEmul,UINT8 sessionIndex)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
wdrv_ackEmulationAddYTag(ackEmul_t * ackEmul,UINT8 * pDot11Header,UINT16 firstBdLength,UINT8 activeIndex,UINT32 segmentSize)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 **********************************************************************************/
wdrv_aeChackSnapWithYtag(ackEmul_t * ackEmul,UINT8 * pSnapHeader,UINT8 * tiSnapLen,UINT8 * activeIndex,UINT16 * segmentSize)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 **********************************************************************************/
wdrv_aeWackReceive(ackEmul_t * ackEmul,UINT16 station,UINT8 wackInfo)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 **********************************************************************************/
wdrv_aeGenerateAck(ackEmul_t * ackEmul,UINT16 stationIndex,UINT8 activeIndex,UINT32 ackNumber)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
wdrv_aeSetActive(ackEmul_t * ackEmul,int status)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
wdrv_aeGetActive(ackEmul_t * ackEmul)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
wdrv_IpChecksumCalc(ackEmul_t * ackEmul,UINT16 len_ip_header,UINT8 * buff)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
wdrv_TcpChecksumCalc(ackEmul_t * ackEmul,UINT16 len_tcp_header,UINT8 * IpSource,UINT8 * IpDest,UINT8 * buff)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