/*-------------------------------------------------------------------------
   RTP function copy right information

   Copyright (C) 2006-2009. Tang, Li <tangli@palmmicro.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-------------------------------------------------------------------------*/
#include "version.h"
#include "type.h"

#ifdef CALL_SIP

#include "ar168.h"
#include "core.h"
#include "apps.h"
#include "tcpip.h"
#include "bank7.h"
#include "sip.h"

SIP_LCB_HANDLE RtpGetLcb(UDP_SOCKET pUcb)
{
	UCHAR i;
	SIP_LCB_HANDLE pLcb;

	pLcb = Sip_pLCB;
	for (i = 0; i < LCB_TSIZE; i ++, pLcb ++)
	{
		if (pLcb->iState != CALL_STATE_FREE)
		{
			if (pUcb == pLcb->pRtpSocket)
			{
				return pLcb;
			}
		}
	}

	return NULL;
}
		

void RtpRun(UDP_SOCKET pUcb)
{
	UCHAR iType, iLen, iState;
	PCHAR pData;
	SIP_LCB_HANDLE pLcb;

	if (TaskStunRun(pUcb))		return;

	pData = Adapter_pUdpBuf;
#ifdef OEM_IP20
	pLcb = RtpGetLcb(pUcb);
	if (pLcb->brtpSession == 0)
	{
		pLcb->brtpSession = 1;
	}
	if (!pLcb)	
	{
		pLcb = Sip_pActiveLcb;
		memcpy4(pLcb->pRtpDstSSRC, (PCHAR)(pData + RTP_SSRC));
#ifdef __ADSL
		if (pLcb->brtpSession == 0)
		{
			pLcb->brtpSession = 1;
		}
#endif
	}
	else
	{
		if (pLcb != Sip_pActiveLcb)	return;
	}
#else
	pLcb = RtpGetLcb(pUcb);
	if (!pLcb)	return;
	memcpy4(pLcb->pRtpDstSSRC, (PCHAR)(pData + RTP_SSRC));
	if (pLcb != Sip_pActiveLcb)	return;
#endif
	iState = pLcb->iState;
	if (iState != CALL_STATE_CALLING2 && iState != CALL_STATE_TALKING)
	{
		return;
	}
	if (pLcb->bHolding)
	{
		return;
	}
	if (!(pLcb->iLocalMode & AUDIO_MODE_RECVONLY))
	{
		return;
	}
	if (pLcb->iVoiceCoder == VOICE_CODER_NONE || pLcb->iVoiceCoder > VOICE_CODER_NUM)
	{
		return;
	}

	if (iState == CALL_STATE_CALLING2)
	{
		if (pLcb->iRemoteRb != RINGBACK_REMOTE)
		{
			pLcb->iRemoteRb = RINGBACK_REMOTE;
			TaskUIHandler(UI_CALL_DECODE_ENCODE, pLcb->iVoiceCoder);
		}
	}

	iType = pData[RTP_PAYLOAD] & 0x7f;
	// Some device will add RTP padding, we handle it here
	if (pData[RTP_VERSION] & 0x20)
	{
		iLen = pData[pUcb->sLen-1];
		pUcb->sLen -= iLen;
	}

	// handle packet loss or packet misorder here
	if (iType == pLcb->iCoderPayload)
	{
		TaskIncomingData(pUcb->sLen, pData, DATA_TYPE_RTP);
	}
	else
	{
		if (iType != pLcb->iDtmfPayload || OptionsGetByte(OPT_DTMF_TYPE) != DTMF_TYPE_RFC2833)
		{
			return;
		}
/*		
		if (pLcb->bKeyRecved)
		{
			if ((pData[RTP_DATA + 1] & 0x80) == 0x80)
			{
				// DTMF key end
				pLcb->bKeyRecved = FALSE;
				return;
			}
			if (memcmp(pLcb->pKeyTimeStamp, (PCHAR)(pData+RTP_TIMESTAMP), 4))
			{
				pLcb->bKeyRecved = FALSE;
			}
		}
		if (!pLcb->bKeyRecved)
		{
			memcpy4(pLcb->pKeyTimeStamp, (PCHAR)(pData+RTP_TIMESTAMP));
			pLcb->bKeyRecved = TRUE;
			TaskUIHandler(UI_CALL_INCOMING_DTMF, (USHORT)keyid2ascii(pData[RTP_DATA]));
		}
*/
		if (pLcb->bKeyRecved)	// key event active
		{
			if ((pData[RTP_DATA + 1] & 0x80) == 0x80)
			{
				pLcb->bKeyRecved = FALSE;		// end event flag
			}
			else if (memcmp(pLcb->pKeyTimeStamp, (PCHAR)(pData + RTP_TIMESTAMP), 4))	// timestamp differs?
			{
				pLcb->bKeyRecved = FALSE;
			}
		}
		else
		{
			if ((pData[RTP_DATA + 1] & 0x80) != 0x80)	// no end flag set?
			{
				pLcb->bKeyRecved = TRUE;
				memcpy4(pLcb->pKeyTimeStamp, (PCHAR)(pData + RTP_TIMESTAMP));
				TaskUIHandler(UI_CALL_INCOMING_DTMF, (USHORT)keyid2ascii(pData[RTP_DATA]));
			}
		}
	}
}

#endif

