summaryrefslogtreecommitdiff
path: root/network/wlan/WDI/COMMON/ParserGen.c
diff options
context:
space:
mode:
authorDaiqian Hu <[email protected]>2016-11-21 08:54:24 +0800
committerDaiqian Hu <[email protected]>2016-11-21 08:54:24 +0800
commita95eaad088f61aa55da9d73015cf1ed86e64a67e (patch)
tree15b498a08a4aee4b7f8b1627d39c965b3aa3ba98 /network/wlan/WDI/COMMON/ParserGen.c
parent1aa0338ec5418345ea0c383e92b4fa19f7c98425 (diff)
Re-submit for WDI sample driver to GitHub
Submit WDI sample driver to GitHub for RS1.
Diffstat (limited to 'network/wlan/WDI/COMMON/ParserGen.c')
-rw-r--r--network/wlan/WDI/COMMON/ParserGen.c2292
1 files changed, 2292 insertions, 0 deletions
diff --git a/network/wlan/WDI/COMMON/ParserGen.c b/network/wlan/WDI/COMMON/ParserGen.c
new file mode 100644
index 00000000..df264db2
--- /dev/null
+++ b/network/wlan/WDI/COMMON/ParserGen.c
@@ -0,0 +1,2292 @@
+/*++
+Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+ ParserGen.c
+
+Abstract:
+ Parse MSDU to match the specified type, fetch fixed offset.
+
+Major Change History:
+ When Who What
+ ---------- --------------- -------------------------------
+ 2007-06-11 shienchang Create.
+ 2008-03-11 Bruce Modify from 818xB.
+
+--*/
+
+#include "Mp_Precomp.h"
+
+#if WPP_SOFTWARE_TRACE
+#include "ParserGen.tmh"
+#endif
+
+// Global protocols and the corresponding actions.
+static GP_RULE GPGlobalRule[] =
+{
+ { PROTO_ETHERNET, PROTO_IP, 12, 2, GPParserHandlerEthernet },
+ { PROTO_WLAN_80211, PROTO_WLAN_LLC, 0, 2, GPParserHandlerWlan },
+ { PROTO_WLAN_LLC, PROTO_IP, 6, 2, GPParserHandlerWlanLlc },
+ { PROTO_IP, PROTO_TCP, 9, 1, GPParserHandlerIP },
+ { PROTO_IP, PROTO_UDP, 9, 1, GPParserHandlerIP },
+ {0},
+};
+
+// The SIP protocol definitions and the corresponding actions.
+static GP_RULE GPVoWlanSipRule[] =
+{
+ { PROTO_UDP, PROTO_SIP_INVITE, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleUDP2SIP },
+ { PROTO_UDP, PROTO_SIP_STATUS, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleUDP2SIP },
+ { PROTO_UDP, PROTO_SIP_BYE, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleUDP2SIP },
+ { PROTO_SIP_INVITE, PROTO_SIP_SDP, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleSIP2SDP },
+ { PROTO_SIP_STATUS, PROTO_SIP_SDP, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleSIP2SDP },
+ { PROTO_SIP_STATUS, PROTO_UNKNOWN, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleSIPSTATUS },
+ { PROTO_SIP_SDP, PROTO_UNKNOWN, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleSDP },
+ { PROTO_SIP_BYE, PROTO_UNKNOWN, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleSIPBYE },
+ { PROTO_UDP, PROTO_RTP, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleUDP2RTP },
+ { PROTO_RTP, PROTO_RTP_G711, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleRTP2G711 },
+ { PROTO_RTP_G711, PROTO_UNKNOWN, UNKNOWN_SIG, UNKNOWN_SIG, GPParserCustomHandleG711 },
+ {0},
+};
+//=============================================================================
+// Prototype of protected function.
+//=============================================================================
+TR_ACTION
+ParseBuffer(
+ IN PADAPTER Adapter,
+ IN PGPPARSE_TOKEN pToken
+ );
+
+VOID
+RuleMatchingProcess(
+ IN PADAPTER Adapter,
+ IN PGPPARSE_TOKEN pToken,
+ IN PGENERIC_PARSER pParser
+ );
+
+BOOLEAN
+MatchingByRule(
+ IN PADAPTER Adapter,
+ IN PGP_RULE pRule,
+ IN PGPPARSE_TOKEN pToken,
+ IN PGENERIC_PARSER pParser
+ );
+
+BOOLEAN
+GetSignatureAndAdvanceToNextProtocol(
+ IN PGPPARSE_TOKEN pToken,
+ IN u4Byte DataOffset,
+ IN u4Byte HeaderLength,
+ IN PVOID pDataBuffer,
+ IN u4Byte DataBufLength
+ );
+
+BOOLEAN
+GetNextLine(
+ IN PGPPARSE_TOKEN pToken,
+ IN BOOLEAN bNoAdvance,
+ OUT pu1Byte pOutBuffer,
+ IN u4Byte OutBufferLen
+ );
+
+BOOLEAN
+UngetLine(
+ IN PGPPARSE_TOKEN pToken
+ );
+
+BOOLEAN
+AdvanceAndGetDataByOffset(
+ IN PGPPARSE_TOKEN pToken,
+ IN u4Byte DataOffset,
+ IN BOOLEAN bNoAdvance,
+ OUT PVOID pDataBuffer,
+ IN u4Byte DataBufLength
+ );
+
+//=============================================================================
+// End of Prototype of protected function.
+//=============================================================================
+
+//=============================================================================
+// Private utility function.
+//=============================================================================
+
+#if DBG
+//
+// Description:
+// Debug routine of protocol.
+// 2007.07.10, by shien chang.
+//
+VOID
+DbgProtocol(
+ IN u4Byte protocol
+ )
+{
+ switch (protocol)
+ {
+ case PROTO_UNKNOWN:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("\n"));
+ break;
+ case PROTO_ETHERNET:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("ethernet -> "));
+ break;
+ case PROTO_WLAN_80211:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("wlan -> "));
+ break;
+ case PROTO_WLAN_LLC:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("llc -> "));
+ break;
+ case PROTO_IP:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("ip -> "));
+ break;
+ case PROTO_TCP:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("tcp -> "));
+ break;
+ case PROTO_UDP:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("udp -> "));
+ break;
+ case PROTO_RTP:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("rtp -> "));
+ break;
+ case PROTO_SIP_INVITE:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("sip invite -> "));
+ break;
+ case PROTO_SIP_STATUS:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("sip status -> "));
+ break;
+ case PROTO_SIP_BYE:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("sip bye -> "));
+ break;
+ case PROTO_SIP_NOTIFY:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("sip notify -> "));
+ break;
+ case PROTO_SIP_SDP:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("sip sdp -> "));
+ break;
+ case PROTO_RTP_G711:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("rtp g711 -> "));
+ break;
+ default:
+ RT_TRACE(COMP_CCX, DBG_TRACE, ("protocol: %d -> ", protocol));
+ break;
+ }
+}
+#endif
+
+
+//
+// Description:
+// Request every parser to parse the tx or rx packet.
+// 2007.07.10, by shien chang.
+//
+TR_ACTION
+ParseBuffer(
+ IN PADAPTER Adapter,
+ IN PGPPARSE_TOKEN pToken
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ u4Byte i;
+ PGENERIC_PARSER pParser;
+ TR_ACTION trAction = TR_ACTION_CONTINUE;
+
+ for (i=0; i < MAX_PARSER_NUM; i++)
+ {
+ pParser = *(((PGENERIC_PARSER*)pMgntInfo->pGenericParser) + i);
+ if ( pParser )
+ {
+ //
+ // Drive the parser go through the registered rules.
+ //
+ if ( pParser->Gate && pParser->Gate(Adapter, pParser) )
+ {
+ RuleMatchingProcess(Adapter, pToken, pParser);
+ if (pParser->Action != NULL)
+ trAction = pParser->Action(Adapter, pToken, pParser);
+ if (trAction != TR_ACTION_CONTINUE)
+ break;
+ }
+ }
+ }
+
+ return trAction;
+}
+
+//
+// Description:
+// This routine drive parser according to parsing rules.
+// 2007.07.10, by shien chang.
+//
+VOID
+RuleMatchingProcess(
+ IN PADAPTER Adapter,
+ IN PGPPARSE_TOKEN pToken,
+ IN PGENERIC_PARSER pParser
+ )
+{
+ PGP_RULE pRule = NULL;
+ BOOLEAN bMatched = FALSE;
+ PGP_RULE pRuleSet[2];
+ u4Byte i=0;
+
+ pRuleSet[0] = pParser->pParseRules;
+ pRuleSet[1] = GPGlobalRule;
+
+ while ( i < sizeof(pRuleSet) / sizeof(PGP_RULE) )
+ {
+ //
+ // Go through parser's rules & global rules.
+ //
+ bMatched = FALSE;
+
+ for (pRule = pRuleSet[i];
+ (pRule != NULL) && (pRule->CurrProtocol != 0);
+ pRule ++)
+ {
+ if (pRule->CurrProtocol == pToken->currProtocol)
+ {
+ bMatched = MatchingByRule(Adapter,
+ pRule,
+ pToken,
+ pParser);
+ if (bMatched)
+ break;
+ }
+ }
+
+ if (bMatched)
+ {
+ if (pRule->NextProtocol != PROTO_UNKNOWN)
+ {
+ i = 0;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ i ++;
+ }
+
+ if (!bMatched)
+ {
+ DbgProtocol(pToken->currProtocol);
+ if (pToken->ProtocolCount < MAX_PROTOCOL_NUM)
+ pToken->ProtocolSuite[pToken->ProtocolCount++] = pToken->currProtocol;
+ }
+ DbgProtocol(PROTO_UNKNOWN);
+}
+
+//
+// Description:
+// Try to match a rule.
+// 2007.7.13, by shien chang.
+//
+BOOLEAN
+MatchingByRule(
+ IN PADAPTER Adapter,
+ IN PGP_RULE pRule,
+ IN PGPPARSE_TOKEN pToken,
+ IN PGENERIC_PARSER pParser
+ )
+{
+ u1Byte SigBuffer[MAX_SIG_LENGTH];
+ BOOLEAN bApply = FALSE;
+ BOOLEAN bMatched = FALSE;
+ BOOLEAN bAdv=FALSE;
+ u4Byte currIndex, currOffset;
+ u4Byte hdrLen=0;
+
+ if ( pRule->SigLength <= MAX_SIG_LENGTH)
+ {
+ currIndex = pToken->currBufferIndex;
+ currOffset = pToken->currBufferOffset;
+ hdrLen = PROTO_UNKNOWN_HDRLEN;
+
+ //
+ // Check signature.
+ // case 1: if signature is unknown, invoke the customer routine
+ // and advance to next protocol if success.
+ // case 2: if signature is known, get the signature first and then
+ // invoke the costomer routine.
+ //
+ if ( pRule->SigLength == UNKNOWN_SIG )
+ {
+ bApply = pRule->ParseHandler(
+ Adapter,
+ pParser->ParserContext,
+ pToken->currProtocol,
+ pRule->NextProtocol,
+ NULL,
+ 0,
+ pToken,
+ &hdrLen);
+
+ if (hdrLen == PROTO_UNKNOWN_HDRLEN)
+ {
+ pToken->currBufferIndex = currIndex;
+ pToken->currBufferOffset = currOffset;
+ bAdv = TRUE;
+ }
+ else if (bApply)
+ {
+ bAdv = GetSignatureAndAdvanceToNextProtocol(
+ pToken,
+ pRule->SigStart,
+ hdrLen,
+ NULL,
+ 0);
+ }
+
+ if (bApply && bAdv)
+ {
+ DbgProtocol(pToken->currProtocol);
+ if (pToken->ProtocolCount < MAX_PROTOCOL_NUM)
+ pToken->ProtocolSuite[pToken->ProtocolCount++] = pToken->currProtocol;
+
+ if (pRule->NextProtocol != PROTO_UNKNOWN)
+ pToken->currProtocol = pRule->NextProtocol;
+ bMatched = TRUE;
+ }
+
+ }
+ else
+ {
+ if (AdvanceAndGetDataByOffset(
+ pToken,
+ pRule->SigStart,
+ TRUE,
+ SigBuffer,
+ pRule->SigLength))
+ {
+ bApply = pRule->ParseHandler(
+ Adapter,
+ pParser->ParserContext,
+ pToken->currProtocol,
+ pRule->NextProtocol,
+ SigBuffer,
+ pRule->SigLength,
+ pToken,
+ &hdrLen);
+
+ if (hdrLen == PROTO_UNKNOWN_HDRLEN)
+ {
+ pToken->currBufferIndex = currIndex;
+ pToken->currBufferOffset = currOffset;
+ bAdv = TRUE;
+ }
+ else if (bApply)
+ {
+ bAdv = GetSignatureAndAdvanceToNextProtocol(
+ pToken,
+ pRule->SigStart,
+ hdrLen,
+ NULL,
+ 0);
+ }
+
+ if (bApply && bAdv)
+ {
+ DbgProtocol(pToken->currProtocol);
+ if (pToken->ProtocolCount < MAX_PROTOCOL_NUM)
+ pToken->ProtocolSuite[pToken->ProtocolCount++] = pToken->currProtocol;
+
+ if (pRule->NextProtocol != PROTO_UNKNOWN)
+ pToken->currProtocol = pRule->NextProtocol;
+ bMatched = TRUE;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ RT_TRACE(COMP_CCX, DBG_WARNING, ("Signature length is too long (limit = %d)\n", MAX_SIG_LENGTH));
+ }
+
+ return bMatched;
+}
+
+//
+// Description:
+// Get signature at DataOffset and advance to the begining of
+// next protocol.
+//
+// Arguments:
+// pToken - the parsing token which maintain by parser.
+// DataOffset - start offset of signature.
+// HeaderLength -length of current protocol.
+// pDataBuffer - buffer to store the read signature.
+// DataBufLength - lenght of signature to be read.
+//
+// Return:
+// TRUE if read success.
+// FALSE if read failed.
+//
+// Note:
+// If pDataBuffer is NULL or DataBufLength is zero, this routine will
+// just advance to DataOffset and doesn't read any data.
+//
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GetSignatureAndAdvanceToNextProtocol(
+ IN PGPPARSE_TOKEN pToken,
+ IN u4Byte DataOffset,
+ IN u4Byte HeaderLength,
+ IN PVOID pDataBuffer,
+ IN u4Byte DataBufLength
+ )
+{
+
+ if (pDataBuffer!=NULL && DataBufLength!=0)
+ {
+ if (AdvanceAndGetDataByOffset(pToken,
+ DataOffset,
+ FALSE,
+ pDataBuffer,
+ DataBufLength))
+ {
+ if (AdvanceAndGetDataByOffset(pToken,
+ HeaderLength-DataOffset,
+ FALSE,
+ NULL,
+ 0))
+ {
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ if (AdvanceAndGetDataByOffset(pToken,
+ HeaderLength,
+ FALSE,
+ NULL,
+ 0))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Get next line of protocol such as SIP, SDP ... which are
+// end with every line a "0x0d 0x0a" seprator. This routine will
+// advance to begining of next line after current line has read
+// according to bNoAdvance flag.
+//
+// Arguments:
+// pToken - the parsing token which maintain by parser.
+// bNoAdvance - TRUE: advance to next line.
+// FALSE: don't advance to next line.
+// pOutBuffer - buffer to store the read data.
+// OutBufferLen - length of pOutBuffer.
+//
+// Return:
+// TRUE if read success.
+// FALSE if read failed.
+//
+// Assumption:
+// pOutBuffer can't be NULL.
+// OutBufferLen can't be zero.
+//
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GetNextLine(
+ IN PGPPARSE_TOKEN pToken,
+ IN BOOLEAN bNoAdvance,
+ OUT pu1Byte pOutBuffer,
+ IN u4Byte OutBufferLen
+ )
+{
+ u4Byte BytesRead = 0;
+ u4Byte i, j;
+ u4Byte start;
+
+ PlatformZeroMemory(pOutBuffer, OutBufferLen);
+
+ for(i = pToken->currBufferIndex; i < pToken->BufferCount; i ++)
+ {
+ if (i == pToken->currBufferIndex)
+ start = pToken->currBufferOffset;
+ else
+ start = 0;
+
+ for (j = start; j < pToken->BufferList[i].Length; j ++)
+ {
+ pOutBuffer[BytesRead ++] = pToken->BufferList[i].VirtualAddress[j];
+
+ if (pOutBuffer[BytesRead-2]==0x0d &&
+ pOutBuffer[BytesRead-1]==0x0a)
+ {
+ if (!bNoAdvance)
+ {
+ if (j == pToken->BufferList[i].Length-1)
+ {
+ if (i + 1 < pToken->BufferCount)
+ {
+ pToken->currBufferIndex = i + 1;
+ pToken->currBufferOffset = 0;
+ }
+ else
+ {
+ pToken->currBufferIndex = i;
+ pToken->currBufferOffset = j;
+ }
+ }
+ else
+ {
+ pToken->currBufferIndex = i;
+ pToken->currBufferOffset = j + 1;
+ }
+ }
+ return TRUE;
+ }
+ if (BytesRead==OutBufferLen)
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Retreat the point back to previous line. This is
+// a reverse operation of GetNextLine.
+//
+// Argument:
+// pToken - the parsing token which maintain by parser.
+//
+// Return:
+// TRUE if retreat success.
+// FALSE if retreat failed.
+//
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+UngetLine(
+ IN PGPPARSE_TOKEN pToken
+ )
+{
+ u4Byte i, j, len;
+ u1Byte found = 0, sta = 0;
+ u4Byte m=0,n=0;
+
+ for (i = pToken->currBufferIndex + 1; i > 0; i --)
+ {
+ if (i==pToken->currBufferIndex+1)
+ len = pToken->currBufferOffset;
+ else
+ len = pToken->BufferList[i-1].Length;
+
+ for (j = len; j > 0; j --)
+ {
+ if (pToken->BufferList[i-1].VirtualAddress[j-1] == 0x0a)
+ {
+ sta++;
+ continue;
+ }
+ if (pToken->BufferList[i-1].VirtualAddress[j-1] == 0x0d)
+ {
+ if (sta == 1)
+ {
+ found++;
+ if (found == 2)
+ {
+ pToken->currBufferIndex = m;
+ pToken->currBufferOffset = n;
+ return TRUE;
+ }
+ }
+ else
+ sta = 0;
+ }
+
+ sta = 0;
+ m = i-1;
+ n = j-1;
+ }
+
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Advance to the offset specific by DataOffset and get following
+// bytes into buffer.
+//
+// Arguments:
+// pToken - the parsing token which maintain by parser.
+// DataOffset - the offset parser will advance before get data.
+// bNoAdvance - TRUE: only get data at DataOffset, not advance to.
+// FALSE: advance to DataOffset, and get data.
+// pDataBuffer -buffer to store the read data.
+// DataBufferLength - lenght of pDataBuffer and bytes to read.
+//
+// Return:
+// TRUE if read success.
+// FALSE if read failed.
+//
+// Note:
+// If pDataBuffer is NULL or DataBufLength is zero, this routine will
+// just advance to DataOffset and doesn't read any data.
+//
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+AdvanceAndGetDataByOffset(
+ IN PGPPARSE_TOKEN pToken,
+ IN u4Byte DataOffset,
+ IN BOOLEAN bNoAdvance,
+ OUT PVOID pDataBuffer,
+ IN u4Byte DataBufLength
+ )
+{
+ BOOLEAN bResult = TRUE;
+ u4Byte BytesRead = 0;
+ u4Byte i;
+ u4Byte offset = 0;
+ pu1Byte pBuffer = (pu1Byte)pDataBuffer;
+ u4Byte len;
+ u4Byte tmpIndex=0, tmpOffset=0;
+ BOOLEAN bOnlyAdvance = (pDataBuffer==NULL || DataBufLength==0) ? TRUE : FALSE;
+ BOOLEAN bOnlyAdvanceComplete = FALSE;
+
+ for(i = pToken->currBufferIndex;i < pToken->BufferCount; i ++)
+ {
+ if(pToken->BufferList[i].Length==0)
+ continue;
+
+ if (i == pToken->currBufferIndex)
+ {
+ len = pToken->BufferList[i].Length - pToken->currBufferOffset;
+ }
+ else
+ {
+ len = pToken->BufferList[i].Length;
+ }
+
+ for (; (BytesRead!=DataBufLength) || bOnlyAdvance; BytesRead ++)
+ {
+ if ( (len + offset) > (DataOffset + BytesRead) )
+ {
+ u4Byte ByteIndexToCopy =
+ (i == pToken->currBufferIndex) ?
+ (DataOffset+BytesRead + pToken->currBufferOffset ) - offset :
+ (DataOffset+BytesRead) - offset;
+
+
+ if (!bOnlyAdvance)
+ pBuffer[BytesRead] = pToken->BufferList[i].VirtualAddress[ByteIndexToCopy];
+
+ if (BytesRead == 0)
+ {
+ tmpIndex = i;
+ tmpOffset = ByteIndexToCopy;
+
+ if (bOnlyAdvance)
+ {
+ bOnlyAdvanceComplete = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ break;
+ }
+
+ if (bOnlyAdvance)
+ {
+ if (bOnlyAdvanceComplete)
+ break;
+ }
+ else
+ {
+ if (BytesRead == DataBufLength)
+ break;
+ }
+ offset += len;
+ }
+
+ if (!bOnlyAdvance && BytesRead != DataBufLength)
+ {
+ RT_TRACE(COMP_CCX, DBG_LOUD, ("AdvanceAndGetDataByOffset(): some data can not be retrived\n"));
+ bResult = FALSE;
+ }
+
+ if (bResult && !bNoAdvance)
+ {
+ pToken->currBufferIndex = tmpIndex;
+ pToken->currBufferOffset = tmpOffset;
+ }
+
+ return bResult;
+}
+
+
+//=============================================================================
+// End of Private utility function.
+//=============================================================================
+
+
+
+
+//=============================================================================
+// Public parser interface.
+//=============================================================================
+
+//
+// Description:
+// Use high performance parser.
+// 2007.07.12, by shien chang.
+//
+VOID
+GPUseHPParser(
+ IN PGENERIC_PARSER pParser
+ )
+{
+ PGP_HP_ENTRY pEntry, pTmpEntry;
+ PGP_HP_NODE pNode;
+ PGP_RULE pRuleSet[2];
+ PGP_RULE pRule;
+ u4Byte i, j;
+ u4Byte entryIndex = 0;
+ u4Byte nodeIndex = 0;
+ u4Byte currNode=0, nextNode=0;
+ PRT_LIST_ENTRY pListEntry;
+
+ if (pParser->pParsingTree == NULL)
+ {
+ pParser->bUseHP = FALSE;
+ return;
+ }
+
+ pRuleSet[0] = GPGlobalRule;
+ pRuleSet[1] = pParser->pParseRules;
+
+ for (i = 0; i < 2; i ++)
+ {
+ for (pRule = pRuleSet[i];
+ (pRule != NULL) && (pRule->CurrProtocol != 0);
+ pRule ++)
+ {
+ for (j = 0; j < nodeIndex; j ++)
+ {
+ pNode = GP_HP_GET_NODE_BY_INDEX(pParser->pParsingTree, j);
+ if (pNode->ProtocolId == pRule->CurrProtocol)
+ {
+ currNode = j;
+ break;
+ }
+ }
+ if (j == nodeIndex)
+ {
+ currNode = nodeIndex;
+ pNode = GP_HP_GET_NODE_BY_INDEX(pParser->pParsingTree, currNode);
+ pNode->ProtocolId = pRule->CurrProtocol;
+ pNode->bUsed = TRUE;
+ RTInitializeListHead(&(pNode->Link));
+ nodeIndex ++;
+ if (nodeIndex == MAX_HP_PROTOCOL_PER_PARSER)
+ {
+ pParser->bUseHP = FALSE;
+ return;
+ }
+ }
+
+ for (j = 0; j < nodeIndex; j ++)
+ {
+ pNode = GP_HP_GET_NODE_BY_INDEX(pParser->pParsingTree, j);
+ if (pNode->ProtocolId == pRule->NextProtocol)
+ {
+ nextNode = j;
+ break;
+ }
+ }
+ if (j == nodeIndex)
+ {
+ nextNode = nodeIndex;
+ pNode = GP_HP_GET_NODE_BY_INDEX(pParser->pParsingTree, nextNode);
+ pNode->ProtocolId = pRule->NextProtocol;
+ pNode->bUsed = TRUE;
+ RTInitializeListHead(&(pNode->Link));
+ nodeIndex++;
+ if (nodeIndex == MAX_HP_PROTOCOL_PER_PARSER)
+ {
+ pParser->bUseHP = FALSE;
+ return;
+ }
+ }
+
+ pEntry = GP_HP_GET_ENTRY_BY_INDEX(pParser->pParsingTree, entryIndex);
+ pNode = GP_HP_GET_NODE_BY_INDEX(pParser->pParsingTree, currNode);
+
+ // Check overwrite.
+ for (pListEntry = (&pNode->Link)->Flink;
+ pListEntry != &pNode->Link;
+ pListEntry = pListEntry->Flink)
+ {
+ pTmpEntry = (PGP_HP_ENTRY)pListEntry;
+ if ( (pTmpEntry->pRule->CurrProtocol == pRule->CurrProtocol) &&
+ (pTmpEntry->pRule->NextProtocol == pRule->NextProtocol) )
+ {
+ RTRemoveEntryList(pListEntry);
+ break;
+ }
+ }
+
+ pEntry->pRule = pRule;
+ pEntry->index = (u1Byte)nextNode;
+ RTInsertTailList(&(pNode->Link), &(pEntry->Link));
+ entryIndex++;
+ if (entryIndex == MAX_HP_RULES_PER_PARSER)
+ {
+ pParser->bUseHP = FALSE;
+ return;
+ }
+
+ }
+ }
+
+ pParser->bUseHP = TRUE;
+}
+
+//
+// Description:
+// This routine parse ethernet header.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserHandlerEthernet(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u2Byte typeLength;
+ BOOLEAN bResult = FALSE;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+ if (pSigBuffer == NULL) return FALSE;
+
+ typeLength = N2H2BYTE( *((UNALIGNED pu2Byte)pSigBuffer) );
+
+ switch (NextProtocol)
+ {
+ case PROTO_IP:
+ if (typeLength == 0x0800)
+ {
+ *AdvBytes = PROTO_ETHERNET_HDRLEN;
+ bResult = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return bResult;
+}
+
+//
+// Description:
+// This routine parse 802.11 wlan header.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserHandlerWlan(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ u4Byte QosCtrlLen = 0;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+ if (pSigBuffer == NULL)
+ return FALSE;
+
+ if ( IsDataFrame(pSigBuffer) )
+ {
+ if( IsQoSDataFrame( pToken->BufferList[0].VirtualAddress ) )
+ {
+ QosCtrlLen = sQoSCtlLng;
+ }
+
+ *AdvBytes = sMacHdrLng+QosCtrlLen+pMgntInfo->SecurityInfo.EncryptionHeadOverhead;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// This routine parse 802.11 wlan LLC header.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserHandlerWlanLlc(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u2Byte typeLength;
+ BOOLEAN bResult = FALSE;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+ if (pSigBuffer == NULL)
+ return FALSE;
+ typeLength = N2H2BYTE( *((UNALIGNED pu2Byte)pSigBuffer) );
+
+ switch (NextProtocol)
+ {
+ case PROTO_IP:
+ if (typeLength == 0x0800)
+ {
+ *AdvBytes = PROTO_WLAN_LLC_HDRLEN;
+ bResult = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return bResult;
+}
+
+//
+// Description:
+// This routine parse ip header.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserHandlerIP(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u1Byte type = *pSigBuffer;
+ BOOLEAN bResult = FALSE;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+ if (pSigBuffer == NULL)
+ return FALSE;
+
+ switch (NextProtocol)
+ {
+ case PROTO_TCP:
+ if (type == 0x06)
+ {
+ *AdvBytes = PROTO_IP_HDRLEN;
+ bResult = TRUE;
+ }
+ break;
+
+ case PROTO_UDP:
+ if (type == 0x11)
+ {
+ *AdvBytes = PROTO_IP_HDRLEN;
+ bResult = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return bResult;
+}
+
+//
+// Description:
+// Allocate a parser and associate the parser with a gate
+// routine which checks parsing criteria and a action routine
+// which decides how to handle the parsed packet.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPAllocateParser(
+ IN PADAPTER Adapter,
+ IN u1Byte Pid,
+ IN const char* strParserName,
+ IN ifAllocateParser AllocateRoutine,
+ IN GPParserGate ParserGateRoutine,
+ IN GPParserAction ParserActionRoutine,
+ IN BOOLEAN bUseHP
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ RT_STATUS Status;
+ u4Byte i;
+ BOOLEAN bFound = FALSE;
+ PGENERIC_PARSER pParser;
+
+ //
+ // Allocate global data structure first.
+ //
+ if (pMgntInfo->pGenericParser == NULL)
+ {
+ Status = PlatformAllocateMemory(
+ Adapter,
+ &(pMgntInfo->pGenericParser),
+ sizeof(PGENERIC_PARSER) * MAX_PARSER_NUM);
+ if (Status != RT_STATUS_SUCCESS)
+ {
+ RT_TRACE(COMP_CCX, DBG_SERIOUS, ("GPAllocateParser(): Failed to allocate parsers\n"));
+ return FALSE;
+ }
+
+ PlatformZeroMemory(pMgntInfo->pGenericParser,
+ sizeof(PGENERIC_PARSER) * MAX_PARSER_NUM);
+ }
+
+ //
+ // Try to allocate parser.
+ //
+ for (i = 0; i < MAX_PARSER_NUM; i ++)
+ {
+ if ( *(((PGENERIC_PARSER*)pMgntInfo->pGenericParser) + i) == NULL)
+ {
+ //
+ // Allocate parser
+ //
+ Status = PlatformAllocateMemory(
+ Adapter,
+ (PVOID*)&pParser,
+ sizeof(GENERIC_PARSER));
+ if (Status != RT_STATUS_SUCCESS)
+ {
+ RT_TRACE(COMP_CCX, DBG_SERIOUS, ("GPAllocateParser(): Failed to allocate parser\n"));
+ return FALSE;
+ }
+
+ PlatformZeroMemory(pParser, sizeof(GENERIC_PARSER));
+
+ pParser->PID = Pid;
+ PlatformZeroMemory(pParser->ParserName, MAX_PARSER_NAME);
+ if (strParserName)
+ {
+ ASCII_STR_COPY(pParser->ParserName, strParserName, MAX_PARSER_NAME);
+ }
+ pParser->Gate = ParserGateRoutine;
+ pParser->Action = ParserActionRoutine;
+ pParser->bUseHP = bUseHP;
+
+ if (bUseHP)
+ {
+ //
+ // Allocate HP rule structure.
+ //
+ Status = PlatformAllocateMemory(
+ Adapter,
+ (PVOID*)&pParser->pParsingTree,
+ MAX_HP_PROTOCOL_PER_PARSER * sizeof(GP_HP_NODE) +
+ MAX_HP_RULES_PER_PARSER * sizeof(GP_HP_ENTRY));
+ if (Status != RT_STATUS_SUCCESS)
+ {
+ pParser->pParsingTree = NULL;
+ }
+
+ PlatformZeroMemory(pParser->pParsingTree,
+ MAX_HP_PROTOCOL_PER_PARSER * sizeof(GP_HP_NODE) +
+ MAX_HP_RULES_PER_PARSER * sizeof(GP_HP_ENTRY));
+ }
+ else
+ {
+ pParser->pParsingTree = NULL;
+ }
+
+ //
+ // Allocate specific data.
+ //
+ if (AllocateRoutine)
+ {
+ if (! AllocateRoutine(Adapter, pParser))
+ {
+ GPFreeParser(Adapter, Pid, NULL);
+ return FALSE;
+ }
+ }
+
+ *(((PGENERIC_PARSER*)pMgntInfo->pGenericParser) + i) = pParser;
+
+ bFound = TRUE;
+ break;
+ }
+ }
+
+ return bFound;
+}
+
+//
+// Description:
+// Deallocate parser allocated at GPAllocateParser.
+// 2007.07.10, by shien chang.
+//
+VOID
+GPFreeParser(
+ IN PADAPTER Adapter,
+ IN u1Byte Pid,
+ IN ifFreeParser FreeRoutine
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ BOOLEAN bClear = TRUE;
+ u4Byte i;
+ PGENERIC_PARSER pParser;
+
+ if (pMgntInfo->pGenericParser == NULL)
+ return;
+
+ //
+ // Try to free parser.
+ //
+ for (i = 0; i < MAX_PARSER_NUM; i++)
+ {
+ pParser = *(((PGENERIC_PARSER*)pMgntInfo->pGenericParser) + i);
+ if (pParser)
+ {
+ if (pParser->PID == Pid)
+ {
+ if (FreeRoutine)
+ FreeRoutine(Adapter, pParser);
+
+ if (pParser->pParsingTree)
+ {
+ PlatformFreeMemory(
+ pParser->pParsingTree,
+ MAX_HP_PROTOCOL_PER_PARSER * sizeof(GP_HP_NODE) +
+ MAX_HP_RULES_PER_PARSER * sizeof(GP_HP_ENTRY));
+ }
+
+ PlatformFreeMemory(pParser, sizeof(GENERIC_PARSER));
+
+ *(((PGENERIC_PARSER*)pMgntInfo->pGenericParser)+i) = NULL;
+ break;
+ }
+ }
+ }
+
+ //
+ // Free all pointer if no parser.
+ //
+ for (i=0; i < MAX_PARSER_NUM; i++)
+ {
+ pParser = *(((PGENERIC_PARSER*)pMgntInfo->pGenericParser) + i);
+ if (pParser)
+ {
+ bClear = FALSE;
+ break;
+ }
+ }
+
+ if (bClear)
+ {
+ PlatformFreeMemory(pMgntInfo->pGenericParser,
+ sizeof(PGENERIC_PARSER) * MAX_PARSER_NUM);
+ }
+}
+
+
+
+//
+// Description:
+// Parse Tx packet which started as InitProtocol.
+// 2007.07.10, by shien chang.
+//
+TR_ACTION
+GPParseTCB(
+ IN PADAPTER Adapter,
+ IN PRT_TCB pTcb,
+ IN PROTO_ID InitProtocol
+ )
+{
+ GPPARSE_TOKEN token;
+ PGPPARSE_TOKEN pToken = &token;
+
+ PlatformZeroMemory(pToken, sizeof(GPPARSE_TOKEN));
+
+ PlatformMoveMemory(pToken->BufferList,
+ pTcb->BufferList,
+ sizeof(SHARED_MEMORY) * MAX_PER_PACKET_BUFFER_LIST_LENGTH);
+ pToken->BufferCount = pTcb->BufferCount;
+ pToken->currBufferIndex = 0;
+ pToken->currBufferOffset = 0;
+ pToken->currProtocol = InitProtocol;
+ pToken->pDataObj = pTcb;
+ pToken->gpFlag = GPFLAG_TX;
+
+ return ParseBuffer(Adapter, pToken);
+
+}
+
+//
+// Description:
+// Parse Rx packet which started as InitProtocol.
+// 2007.07.10, by shien chang.
+//
+TR_ACTION
+GPParseRFD(
+ IN PADAPTER Adapter,
+ IN PRT_RFD pRfd,
+ IN PROTO_ID InitProtocol
+ )
+{
+ GPPARSE_TOKEN token;
+ PGPPARSE_TOKEN pToken = &token;
+
+ PlatformZeroMemory(pToken, sizeof(GPPARSE_TOKEN));
+
+ pToken->BufferList[0].VirtualAddress = pRfd->Buffer.VirtualAddress + pRfd->FragOffset;
+ pToken->BufferList[0].Length = pRfd->FragLength;
+ pToken->BufferCount = 1;
+ pToken->currBufferIndex = 0;
+ pToken->currBufferOffset = 0;
+ pToken->currProtocol = InitProtocol;
+ pToken->pDataObj = pRfd;
+ pToken->gpFlag = GPFLAG_RX;
+
+ return ParseBuffer(Adapter, pToken);
+
+}
+
+
+//=============================================================================
+// End of Public parser interface.
+//=============================================================================
+
+//=============================================================================
+// Custom parser routines.
+//=============================================================================
+
+//
+// Description:
+// Gate routine of VOWLAN parser.
+// If return TRUE, parser rules will be driven.
+// If return FALSE, parser will skip it's work.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserGateVoWlanSIP(
+ IN PADAPTER Adapter,
+ IN PVOID pParser
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ PSTA_QOS pStaQos = pMgntInfo->pStaQos;
+
+ //
+ // Check if WMM is enabled, CCX is version 4
+ //
+ if (pMgntInfo->mAssoc)
+ {
+ if ( (pMgntInfo->pStaQos->CurrentQosMode & QOS_WMM) ||
+ (pMgntInfo->pStaQos->CurrentQosMode & QOS_WMMSA) )
+ {
+ u1Byte CurrCcxVerNumber = 0;
+
+ CCX_QueryVersionNum(Adapter, &CurrCcxVerNumber);
+
+ if ( CurrCcxVerNumber >= 4 )
+ {
+ pu1Byte param = GET_WMM_PARAM_ELE_AC_PARAM(pStaQos->WMMParamEle);
+ u1Byte acmVO = GET_WMM_AC_PARAM_ACM(param + AC3_VO * 4);
+
+ if (acmVO)
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Allocation routine of VOWLAN parser.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPAllocateParserVoWlanSIP(
+ IN PADAPTER Adapter,
+ IN PGENERIC_PARSER pParser
+ )
+{
+ PGP_VOWLAN_CONTEXT pContext;
+ RT_STATUS Status;
+
+ Status = PlatformAllocateMemory(Adapter,
+ (PVOID*)&pContext,
+ sizeof(GP_VOWLAN_CONTEXT));
+ if (Status != RT_STATUS_SUCCESS)
+ {
+ RT_TRACE(COMP_CCX, DBG_SERIOUS, ("GPAllocateParserVoWlanSIP(): Failed to allocate memory\n"));
+ return FALSE;
+ }
+
+ PlatformZeroMemory(pContext, sizeof(GP_VOWLAN_CONTEXT));
+
+ GP_REGISTER_RULES(pParser, GPVoWlanSipRule);
+ GP_BIND_CONTEXT(pParser, pContext);
+
+ if (pParser->pParsingTree && pParser->bUseHP)
+ GPUseHPParser(pParser);
+
+ return TRUE;
+}
+
+//
+// Description:
+// Deallocation routine of VOWLAN parser.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPFreeParserVoWlanSIP(
+ IN PADAPTER Adapter,
+ IN PGENERIC_PARSER pParser
+ )
+{
+ PGP_VOWLAN_CONTEXT pContext;
+
+ pContext = (PGP_VOWLAN_CONTEXT)GP_GET_CONTEXT(pParser);
+ if (pContext)
+ {
+ PlatformFreeMemory(pContext, sizeof(GP_VOWLAN_CONTEXT));
+ }
+
+ GP_UNBIND_CONTEXT(pParser);
+ GP_UNREGISTER_RULES(pParser);
+
+ return TRUE;
+}
+
+//
+// Description:
+// Action routine of VOWLAN parser.
+// 2007.07.10, by shien chang.
+//
+TR_ACTION
+GPParserActionVoWlanSIP(
+ IN PADAPTER Adapter,
+ IN PGPPARSE_TOKEN pToken,
+ IN PVOID pParser
+ )
+{
+ TR_ACTION trAction = TR_ACTION_CONTINUE;
+ //PGENERIC_PARSER pGPParser = (PGENERIC_PARSER)pParser;
+ //PGP_VOWLAN_CONTEXT pContext = (PGP_VOWLAN_CONTEXT)pGPParser->ParserContext;
+
+ return trAction;
+}
+
+
+//
+// Description:
+// Custom routine to parse UDP to SIP.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleUDP2SIP(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ PSTA_QOS pStaQos = pMgntInfo->pStaQos;
+ u1Byte line[256];
+ const char* InviteSig = "INVITE sip:";
+ const char* StatusSig = "SIP/2.0";
+ const char* ByeSig = "BYE sip:";
+ const char* NotifySig = "NOTIFY sip:";
+ const char* AckSig = "ACK sip:";
+ BOOLEAN bReturn = FALSE;
+ RT_SPINLOCK_TYPE SpinLockType;
+ BOOLEAN bQosData = FALSE;
+ BOOLEAN bRejectData = FALSE;
+
+ RT_ASSERT( ((pToken->gpFlag == GPFLAG_TX)||(pToken->gpFlag == GPFLAG_RX)),
+ ("GPParserCustomHandleUDP2SIP(): Parser flag must either be GPFLAG_TX or GPFLAG_RX\n"));
+
+ if (pToken->gpFlag == GPFLAG_TX)
+ SpinLockType = RT_TX_SPINLOCK;
+ else if (pToken->gpFlag == GPFLAG_RX)
+ SpinLockType = RT_RX_SPINLOCK;
+ else
+ return bReturn;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ if (!GetNextLine(pToken, TRUE, line, sizeof(line)) )
+ return FALSE;
+
+ switch (NextProtocol)
+ {
+ case PROTO_SIP_INVITE:
+ if (PlatformCompareMemory(
+ &(line[PROTO_UDP_HDRLEN]), (PVOID)InviteSig, 11) == 0)
+ {
+ RT_TRACE(COMP_CCX , DBG_LOUD, ("GPParserCustomHandleUDP2SIP(): PROTO_SIP_INVITE, pToken->gpFlag = %02X\n", pToken->gpFlag));
+ CCX_GPParserCustomHandleUDP2SIP(Adapter, SpinLockType, &bQosData, &bReturn, &bRejectData);
+ }
+ break;
+
+ case PROTO_SIP_STATUS:
+ if (PlatformCompareMemory(
+ &line[PROTO_UDP_HDRLEN],
+ (PVOID)StatusSig,
+ 7) == 0)
+ {
+ if (CCX_CAC_IsVoiceTsExist(Adapter))
+ {
+ bQosData = TRUE;
+ bReturn = TRUE;
+ }
+ else if(pToken->gpFlag == GPFLAG_TX)
+ { // Reject the status packet responding to the in-call.
+ bRejectData = TRUE;
+ }
+ }
+ break;
+
+ case PROTO_SIP_BYE:
+ if (PlatformCompareMemory(
+ &line[PROTO_UDP_HDRLEN],
+ (PVOID)ByeSig,
+ 8) == 0)
+ {
+ PlatformReleaseSpinLock(Adapter, SpinLockType);
+ RT_TRACE(COMP_CCX, DBG_LOUD, ("GPParserCustomHandleUDP2SIP(): PROTO_SIP_BYE, pToken->gpFlag = %02X\n", pToken->gpFlag));
+ CCX_CAC_DelTs(Adapter);
+ PlatformAcquireSpinLock(Adapter, SpinLockType);
+ bReturn = TRUE;
+ }
+ break;
+
+ case PROTO_SIP_NOTIFY:
+ if (PlatformCompareMemory(
+ &line[PROTO_UDP_HDRLEN],
+ (PVOID)NotifySig,
+ 11) == 0)
+ {
+ //if (CCX_CAC_IsSignalTsExist(Adapter))
+ if (CCX_CAC_IsVoiceTsExist(Adapter))
+ bQosData = TRUE;
+ bReturn = TRUE;
+ }
+ break;
+
+ case PROTO_SIP_ACK:
+ if (PlatformCompareMemory(
+ &line[PROTO_UDP_HDRLEN],
+ (PVOID)AckSig,
+ 8) == 0)
+ {
+ //if (CCX_CAC_IsSignalTsExist(Adapter))
+ if (CCX_CAC_IsVoiceTsExist(Adapter))
+ bQosData = TRUE;
+ bReturn = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (bQosData)
+ {
+ *AdvBytes = PROTO_UDP_HDRLEN;
+ if (pToken->gpFlag == GPFLAG_TX)
+ {
+ PQOS_TSTREAM pTs = NULL;
+ PRT_TCB pTcb = (PRT_TCB)pToken->pDataObj;
+ pu1Byte pHeader = pTcb->BufferList[0].VirtualAddress;
+ if (pTcb)
+ {
+ pTcb->DataRate = RT_CCX_CAC_MIN_PHY_RATE(Adapter);
+ pTcb->TSID = 0;
+ pTcb->priority = 6;
+ SET_80211_HDR_QOS_EN(pHeader, 1);
+
+ if (!ACTING_AS_AP(Adapter))
+ {
+ pTs = &(pStaQos->StaTsArray[pTcb->TSID]);
+ if (pTs && pTs->bUsed)
+ {
+ pTcb->DataRate = QosGetNPR(Adapter, pTs);
+ }
+ }
+ }
+ }
+ }
+ else if (bRejectData)
+ {
+ PRT_TCB pTcb = (PRT_TCB)pToken->pDataObj;
+ if (pTcb) pTcb->TSID = SESSION_REJECT_TSID;
+ }
+
+ return bReturn;
+}
+
+//
+// Description:
+// Custom routine to parse SIP to SDP.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleSIP2SDP(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u1Byte line[256];
+ const char* AudioSig = "m=audio";
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ while (GetNextLine(pToken, FALSE, line, sizeof(line)) )
+ {
+ if (PlatformCompareMemory(line, (PVOID)AudioSig, 7) == 0)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Custom routine to handle SIP STATUS message.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleSIPSTATUS(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u1Byte line[256];
+ u1Byte callId[MAX_SESSION_ID];
+ u4Byte callIdLen;
+ RT_SPINLOCK_TYPE SpinLockType;
+
+ RT_ASSERT( ((pToken->gpFlag == GPFLAG_TX)||(pToken->gpFlag == GPFLAG_RX)),
+ ("GPParserCustomHandleUDP2SIP(): Parser flag must either be GPFLAG_TX or GPFLAG_RX\n"));
+
+ if (pToken->gpFlag == GPFLAG_TX)
+ SpinLockType = RT_TX_SPINLOCK;
+ else if (pToken->gpFlag == GPFLAG_RX)
+ SpinLockType = RT_RX_SPINLOCK;
+ else
+ return FALSE;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ if (GetNextLine(pToken, TRUE, line, sizeof(line)) )
+ {
+ //
+ // SIP reponse status code:
+ // 1XX Provisional 100 Trying
+ // 2XX Successful 200 OK
+ // 3XX Redirection 302 Moved Temporarily
+ // 4XX Client Error 404 Not Found
+ // 5XX Server Error 504 Server Time-out
+ // 6XX Global Failure 603 Decline
+ // By Bruce, 2008-03-17.
+ //
+ if ( (line[8] == '4') || (line[8] == '5' || (line[8] == '6') ))
+ {
+ if (GetCallId(pToken, FALSE, callId, &callIdLen))
+ {
+ RemoveSession((PGP_VOWLAN_CONTEXT)pParserContext, callId, callIdLen);
+ }
+
+ PlatformReleaseSpinLock(Adapter, SpinLockType);
+ RT_TRACE(COMP_CCX, DBG_LOUD, ("GPParserCustomHandleSIPSTATUS(): Remove Session(reason = %02X), pToken->gpFlag = %02X\n", line[8], pToken->gpFlag));
+ CCX_CAC_DelTs(Adapter);
+ PlatformAcquireSpinLock(Adapter, SpinLockType);
+
+ if (pToken->gpFlag == GPFLAG_TX)
+ {
+ PRT_TCB pTcb = (PRT_TCB)pToken->pDataObj;
+ pu1Byte pHeader = pTcb->BufferList[0].VirtualAddress;
+ if (pTcb)
+ {
+ pTcb->TSID = DEFAULT_TSID;
+ pTcb->priority = 0;
+ SET_80211_HDR_QOS_EN(pHeader, 0);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//
+// Description:
+// Get call id which is contained in SIP message.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GetCallId(
+ IN PGPPARSE_TOKEN pToken,
+ IN BOOLEAN bNoAdvance,
+ OUT pu1Byte callId,
+ OUT pu4Byte callIdLen
+ )
+{
+ u1Byte buf[256];
+ u4Byte i;
+ const char* CallSig = "Call-ID:";
+
+ while (GetNextLine(pToken, bNoAdvance, buf, sizeof(buf)))
+ {
+ if (PlatformCompareMemory(buf, (PVOID)CallSig, 8) == 0)
+ {
+ for (i=9; i<sizeof(buf); i++)
+ {
+ if (buf[i] == 0x2e)
+ {
+ PlatformMoveMemory(callId, &(buf[9]), i-9);
+ *callIdLen = i-9;
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Session Management - remove a session.
+// 2007.07.10, by shien chang.
+//
+VOID
+RemoveSession(
+ IN PGP_VOWLAN_CONTEXT pContext,
+ IN pu1Byte sessionId,
+ IN u4Byte sessionIdLen
+ )
+{
+ u4Byte i;
+
+ if (sessionIdLen > MAX_SESSION_ID)
+ return;
+
+ for (i = 0; i < MAX_SESSION; i ++)
+ {
+ if ( (pContext->Session[i].bUsed == TRUE) &&
+ (pContext->Session[i].sessionIdLen == sessionIdLen) &&
+ (PlatformCompareMemory(
+ pContext->Session[i].sessionId,
+ sessionId,
+ sessionIdLen) == 0) )
+ {
+ RT_PRINT_STR(COMP_CCX, DBG_LOUD, "RemoveSession():\n", pContext->Session[i].sessionId, pContext->Session[i].sessionIdLen);
+ pContext->Session[i].bUsed = FALSE;
+ break;
+ }
+ }
+
+}
+
+//
+// Description:
+// Custom routine to handle SDP.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleSDP(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u1Byte line[256];
+ u2Byte port = 0;
+ u2Byte type = 65535;
+ u1Byte charTable[] = { '0','1','2','3','4','5','6','7','8','9' };
+ u4Byte i,j;
+ u1Byte callId[MAX_SESSION_ID];
+ u4Byte callIdLen;
+ BOOLEAN bReturn = FALSE;
+ u4Byte hdrLen=0;
+ const char* RtpSig = "RTP/AVP";
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ if (GetCallId(pToken, FALSE, callId, &callIdLen))
+ {
+ if (!AddSession((PGP_VOWLAN_CONTEXT)pParserContext, callId, callIdLen))
+ {
+ RT_TRACE(COMP_CCX, DBG_LOUD, ("GPParserCustomHandleUDP2SIP(): Failed to add a call\n"));
+ return FALSE;
+ }
+ }
+ else
+ return FALSE;
+
+ if (GPParserCustomHandleSIP2SDP(Adapter,
+ pParserContext,
+ CurrProtocol,
+ NextProtocol,
+ pSigBuffer,
+ SigBufferLen,
+ pToken,
+ &hdrLen))
+ {
+ if (!UngetLine(pToken))
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ if (!GetNextLine(pToken, TRUE, line, sizeof(line)) )
+ return FALSE;
+
+ // get port num
+ for (i = 8; i < sizeof(line); i ++)
+ {
+ for (j = 0; j < sizeof(charTable); j ++)
+ {
+ if (line[i] == charTable[j])
+ break;
+ }
+
+ if (j==sizeof(charTable))
+ break;
+
+ port = (port*10)+(u2Byte)j;
+ }
+
+ if (port)
+ {
+ i ++;
+ if ((i + 7 < 256) && PlatformCompareMemory(
+ &(line[i]),
+ (PVOID)RtpSig,
+ 7) == 0)
+ {
+ i += 7;
+ while (line[i] != 0x0d)
+ {
+ i ++;
+ type = 65535;
+
+ for (; i < sizeof(line); i ++)
+ {
+ for (j = 0; j < sizeof(charTable); j ++)
+ {
+ if (line[i] == charTable[j])
+ break;
+ }
+
+ if (j==sizeof(charTable))
+ break;
+
+ if (type==65535)
+ type=0;
+ type = (type*10) + (u2Byte)j;
+ }
+
+ if (type == 0 || type == 8)
+ {
+ if (pToken->gpFlag == GPFLAG_TX)
+ { // Update Port Num
+ UpdateSessionInfo((PGP_VOWLAN_CONTEXT)pParserContext, callId, callIdLen, port, 0);
+ bReturn = TRUE;
+ }
+ else if (pToken->gpFlag == GPFLAG_RX)
+ {
+ // Update Port Num
+ UpdateSessionInfo((PGP_VOWLAN_CONTEXT)pParserContext, callId, callIdLen, 0, port);
+ bReturn = TRUE;
+ }
+ else
+ {
+ RT_TRACE(COMP_CCX, DBG_LOUD, ("GPParserCustomHandleSDP(): Invalid flag\n"));
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ return bReturn;
+}
+
+//
+// Description:
+// Session Management - add a new session.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+AddSession(
+ IN PGP_VOWLAN_CONTEXT pContext,
+ IN pu1Byte sessionId,
+ IN u4Byte sessionIdLen
+ )
+{
+ u4Byte i;
+
+ if (sessionIdLen > MAX_SESSION_ID)
+ {
+ RT_TRACE(COMP_CCX, DBG_WARNING, ("AddSession(): Failed, sessionIDLen(%d) > Max(%d)\n", sessionIdLen, MAX_SESSION_ID));
+ return FALSE;
+ }
+
+ RT_PRINT_STR(COMP_CCX, DBG_LOUD, "AddSession():\n", sessionId, sessionIdLen);
+
+ //
+ // Check if an call can be added.
+ //
+ for (i = 0; i < MAX_SESSION; i ++)
+ {
+ if (pContext->Session[i].bUsed)
+ {
+ if ( (sessionIdLen == pContext->Session[i].sessionIdLen) &&
+ (PlatformCompareMemory(sessionId,
+ pContext->Session[i].sessionId,
+ sessionIdLen) == 0) )
+ {
+ RT_TRACE(COMP_CCX, DBG_LOUD, ("AddSession(): This session has been existed!\n"));
+ return TRUE;
+ }
+ }
+
+ if (!pContext->Session[i].bUsed) break;
+ }
+
+ if (i != MAX_SESSION)
+ {
+ PlatformZeroMemory(pContext->Session[i].sessionId, MAX_SESSION_ID);
+ PlatformMoveMemory(pContext->Session[i].sessionId, sessionId, sessionIdLen);
+ pContext->Session[i].sessionIdLen = sessionIdLen;
+ pContext->Session[i].bUsed = TRUE;
+ return TRUE;
+ }
+
+ RT_TRACE(COMP_CCX, DBG_WARNING, ("AddSession(): Add Session Failed SessionNum = %d > Max(%d) \n", i, MAX_SESSION));
+
+ return FALSE;
+}
+
+//
+// Description:
+// Session Management - update a session information.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+UpdateSessionInfo(
+ IN PGP_VOWLAN_CONTEXT pContext,
+ IN pu1Byte sessionId,
+ IN u4Byte sessionIdLen,
+ IN u2Byte srcPort,
+ IN u2Byte dstPort
+ )
+{
+ u4Byte i;
+
+ if (sessionIdLen > MAX_SESSION_ID)
+ return FALSE;
+
+ for (i = 0; i < MAX_SESSION; i ++)
+ {
+ if ( (pContext->Session[i].bUsed == TRUE) &&
+ (pContext->Session[i].sessionIdLen == sessionIdLen) &&
+ (PlatformCompareMemory(
+ pContext->Session[i].sessionId,
+ sessionId,
+ sessionIdLen) == 0) )
+ {
+ if (srcPort)
+ pContext->Session[i].srcPort = srcPort;
+ if (dstPort)
+ pContext->Session[i].dstPort = dstPort;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Session Management - match a session by port.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+MatchSession(
+ IN PGP_VOWLAN_CONTEXT pContext,
+ IN u2Byte Port,
+ IN u1Byte Flag
+ )
+{
+ u4Byte i;
+
+ if ( (Flag != GPFLAG_TX) && (Flag != GPFLAG_RX) )
+ return FALSE;
+ if (Port == 0)
+ return FALSE;
+
+ for (i = 0; i < MAX_SESSION; i ++)
+ {
+ if (pContext->Session[i].bUsed)
+ {
+ if ( (Flag == GPFLAG_TX) && (pContext->Session[i].srcPort == Port) )
+ return TRUE;
+ if ( (Flag == GPFLAG_RX) && (pContext->Session[i].dstPort == Port) )
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+//
+// Description:
+// Custom routine to handle SIP BYE message.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleSIPBYE(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u1Byte callId[MAX_SESSION_ID];
+ u4Byte callIdLen;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ if (GetCallId(pToken, FALSE, callId, &callIdLen))
+ {
+ RemoveSession((PGP_VOWLAN_CONTEXT)pParserContext, callId, callIdLen);
+ }
+
+ return TRUE;
+}
+
+//
+// Description:
+// Custom routine to parse UDP to RTP.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleUDP2RTP(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u2Byte PortBuf=0;
+ u2Byte Port;
+ u4Byte offset;
+ BOOLEAN bReturn = FALSE;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ if ( (pToken->gpFlag == GPFLAG_TX) || (pToken->gpFlag == GPFLAG_RX) )
+ {
+ offset = 0;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (AdvanceAndGetDataByOffset(pToken,
+ offset,
+ TRUE,
+ (pu1Byte)&PortBuf,
+ sizeof(PortBuf)) )
+ {
+ Port = N2H2BYTE(PortBuf);
+ if ( MatchSession((PGP_VOWLAN_CONTEXT)pParserContext, Port, pToken->gpFlag) )
+ {
+ *AdvBytes = PROTO_UDP_HDRLEN;
+ bReturn = TRUE;
+ }
+ }
+
+ return bReturn;
+}
+
+//
+// Description:
+// Custom routine to parse RTP to G.711.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleRTP2G711(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ u1Byte type;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+
+ if (AdvanceAndGetDataByOffset(pToken,
+ 1,
+ TRUE,
+ &type,
+ sizeof(type)) )
+ {
+ //
+ // RTP payload types:
+ // 0x0: PCMU(mu-law G.711) Audio Clock rate = 8000
+ // 0x08: PCMA(A-law G.711) Audio Clock rate = 8000
+ // By Bruce, 2008-03-18.
+ //
+ if (type==0x00 || type==0x08)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//
+// Description:
+// Custom routine to handle G.711 packet.
+// 2007.07.10, by shien chang.
+//
+BOOLEAN
+GPParserCustomHandleG711(
+ IN PADAPTER Adapter,
+ IN PVOID pParserContext,
+ IN PROTO_ID CurrProtocol,
+ IN PROTO_ID NextProtocol,
+ OUT pu1Byte pSigBuffer,
+ IN u4Byte SigBufferLen,
+ IN PGPPARSE_TOKEN pToken,
+ OUT pu4Byte AdvBytes
+ )
+{
+ PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
+ PSTA_QOS pStaQos = pMgntInfo->pStaQos;
+ PQOS_TSTREAM pTs = NULL;
+
+ *AdvBytes = PROTO_UNKNOWN_HDRLEN;
+ if (pToken->gpFlag == GPFLAG_TX)
+ {
+ PRT_TCB pTcb = (PRT_TCB)pToken->pDataObj;
+ pu1Byte pHeader = pTcb->BufferList[0].VirtualAddress;
+ if (pTcb)
+ {
+ pTcb->DataRate = RT_CCX_CAC_MIN_PHY_RATE(Adapter);
+ pTcb->TSID = 0;
+ pTcb->priority = 6;
+ SET_80211_HDR_QOS_EN(pHeader, 1);
+
+ if (!ACTING_AS_AP(Adapter))
+ {
+ pTs = &(pStaQos->StaTsArray[pTcb->TSID]);
+ if (pTs && pTs->bUsed)
+ {
+ pTcb->DataRate = QosGetNPR(Adapter, pTs);
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+//
+// Must call After TranslateHandleRxDot11FrameHeader
+// Note : No Qos , IV , HTC 802.11 frame !!
+// And Data frame !!
+//
+
+BOOLEAN
+GPGetParseRFDInfo(
+ IN PADAPTER Adapter,
+ IN PRT_RFD pRfd,
+ IN PRX_FILTER_INFO pRxfiterInfo
+ )
+{
+ /*
+ typedef struct _RX_FILTER_INFO{
+ // MAC
+ pu1Byte pDA;
+ pu1Byte pSA;
+ u1Byte PacketType; // RX_PACKET_TYPE
+ pu1Byte pEtherType; // 2 bytes : IPv4 , IPv6 , ARP ...
+ // IP
+ u1Byte ARPOption; // Request or Response
+ pu1Byte ARPSPA; // ARP Sender IP
+ pu1Byte ARPTPA; // ARP Target IP
+ u1Byte Protocol; // UDP : 0x11 , TCP : 0x06
+ //UDP
+ pu1Byte pDestinationPort; // 2 bytes
+ }RX_FILTER_INFO,*PRX_FILTER_INFO;
+ */
+ OCTET_STRING frame;
+ //PRX_FILTER_INFO pRxfiterInfo = &(pRfd->D0FilterCoalPktInfo);
+ pu1Byte pCurrentbuf;
+ u1Byte ArpType[2] = {0x08 ,0x06};
+ u1Byte IPv4Type[2] = {0x08 ,0x00};
+ u1Byte IPv6Type[2] = {0x86 ,0xdd};
+
+ FillOctetString(frame, pRfd->Buffer.VirtualAddress+PLATFORM_GET_FRAGOFFSET(pRfd), pRfd->PacketLength);
+
+ PlatformZeroMemory(pRxfiterInfo, sizeof(RX_FILTER_INFO));
+
+ // Just for Data packet !!
+ if(!IsDataFrame(frame.Octet))
+ {
+ pRxfiterInfo->PacketType = RXPacketTypeUndefined;
+ return FALSE;
+ }
+
+ // MAC !!
+ pRxfiterInfo->pDA = Frame_pDaddr(frame);
+ pRxfiterInfo->pSA = Frame_pSaddr(frame);
+
+ if( MacAddr_isBcst(pRxfiterInfo->pDA))
+ {
+ pRxfiterInfo->PacketType = RXPacketTypeBroadcast;
+ }
+ else if( MacAddr_isMulticast(pRxfiterInfo->pDA) )
+ {
+ pRxfiterInfo->PacketType = RXPacketTypeMulticast;
+ }
+ else
+ {
+ pRxfiterInfo->PacketType = RXPacketTypeUnicast;
+ return TRUE;
+ }
+ /*
+ if( Frame_ValidAddr4(frame) )
+ {
+ offset += 6; May no Address4 frame !!
+ }
+ */
+
+ //RT_PRINT_DATA(COMP_TEST, DBG_LOUD, "===> GPGetParseRFDInfo:\n", frame.Octet, frame.Length);
+ pRxfiterInfo->pEtherType = frame.Octet + sMacHdrLng + LLC_HEADER_SIZE;
+
+ pCurrentbuf = frame.Octet + sMacHdrLng + LLC_HEADER_SIZE + TYPE_LENGTH_FIELD_SIZE;
+
+ // IP !!
+ if( PlatformCompareMemory(pRxfiterInfo->pEtherType , ArpType, 2) == 0)
+ {
+ // ARP
+ pRxfiterInfo->ARPOption = pCurrentbuf + 6;
+ pRxfiterInfo->ARPSPA = pCurrentbuf + 6 + 2 + 6; // 6 Option offset , 2 Option Len , 6 SPA Mac Len
+ pRxfiterInfo->ARPTPA = pCurrentbuf + 6 + 2 + 6 + 4 + 6 ; // // 6 Option offset , 2 Option Len , 6 SPA Mac Len , 4 SPA len , 6 TPA Mac Len
+ }
+ else if(PlatformCompareMemory(pRxfiterInfo->pEtherType , IPv4Type, 2) == 0)
+ {
+ pRxfiterInfo->Protocol = pCurrentbuf[9];
+ // UDP !!
+ if(pRxfiterInfo->Protocol == 0x11)
+ {
+ u1Byte IPv4len = (pCurrentbuf[0]&0x0f) * 4;
+ pRxfiterInfo->pDestinationPort = pCurrentbuf + IPv4len + 2; // (pCurrentbuf[0]>>4) IPv4 Heard len 2 Source Port
+ //RT_PRINT_DATA(COMP_TEST, DBG_LOUD, "IPV4 pRxfiterInfo->pDestinationPort :\n", pRxfiterInfo->pDestinationPort, 2);
+ }
+ //RT_TRACE(COMP_TEST, DBG_LOUD , ("===> pRfd nTotalSubframe (%d) \n" , pRfd->nTotalSubframe) );
+ }
+ else if(PlatformCompareMemory(pRxfiterInfo->pEtherType , IPv6Type, 2) == 0)
+ {
+
+ pRxfiterInfo->Protocol = pCurrentbuf[6];
+ // UDP !!
+ if(pRxfiterInfo->Protocol == 0x11)
+ {
+ pRxfiterInfo->pDestinationPort = pCurrentbuf + 40 + 2; // 40 IPv6 Len , 2 Source Port
+ //RT_PRINT_DATA(COMP_TEST, DBG_LOUD, "IPV6 pRxfiterInfo->pDestinationPort :\n", pRxfiterInfo->pDestinationPort, 2);
+ }
+ //RT_TRACE(COMP_TEST, DBG_LOUD , ("===> pRfd nTotalSubframe (%d) \n" , pRfd->nTotalSubframe) );
+ }
+
+
+ return TRUE;
+
+}
+
+
+//=============================================================================
+// End of Custom parser routines.
+//=============================================================================
+