• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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