#include "p_apps.h"
#include "p_dsp.h"
#include "my_mgcp.h"

void MgcpSdpMsg(BOOLEAN bOffer)
{
	PXCHAR_D pLocalIP;
	PXCHAR_D pBuf;

	pBuf = p_line_get_buf();
	//Init Local Connection Descriptor
	pLocalIP = ProxyGetLocalIP(Sys_pServiceIP);

	p_line_add_c(Sdp_cV0);
	p_line_add_newline();
	p_line_add_c((PCCHAR)"o=- 0 0 IN IP4");
	p_line_add_space();

	p_line_add_ip(pLocalIP);
	p_line_add_newline();

	p_line_add_c((PCCHAR)"s=-");
	p_line_add_newline();
	p_line_add_c((PCCHAR)"c=IN IP4");
	p_line_add_space();

	p_line_add_ip(pLocalIP);
	p_line_add_newline();

	p_line_add_c((PCCHAR)"t=0 0");
	p_line_add_newline();
	p_line_add_c(Sdp_cMAudio);
	p_line_add_space();
	p_line_add_val(Sys_iRtpPort);
	p_line_add_space();
	p_line_add_c((PCCHAR)"RTP/AVP");
	p_line_add_space();

	if (bOffer)
	{
		SdpAddAudioCode();
	}
	else
	{
		p_line_add_val(RtpGetLocalRtpType(Sys_iAudioType));
	}

	if (Sys_iDtmfType == DTMF_RFC2833)
	{
		p_line_add_space();
		p_line_add_val(Rtp_iDtmfPayloadType);
	}
	p_line_add_newline();

	if (bOffer)
	{
		SdpAddRtpMapList();
	}
	else
	{
		SdpAddRtpMap(Sys_iAudioType);
	}
	if (Sys_iDtmfType == DTMF_RFC2833)
	{
		SdpAddDtmfType(Rtp_iDtmfPayloadType);
	}

	p_strcpy_x2x((PXCHAR)Sdram_pDataCache, pBuf);
	SdramWriteString(PROTOCOL_SDRAM_POS+MGCP_PARAM_LC);
}

BOOLEAN MgcpHandleSdp(UCHAR iRecvSdpNum)
{
	DCHAR i, iTemp, iAudioType, iDtmfPType;
	PXCHAR_D pCur;
	PXCHAR_D pTemp;
	XCHAR iIlbcPType;
	XCHAR pDstIP[IP_ALEN];
	DSHORT iDstPort, iRtcpPort;
	BOOLEAN bValidIP;
	BOOLEAN bMediaAudio;

	if (!iRecvSdpNum)	return FALSE;

	if (Sys_iServiceType == SERVICE_TYPE_ZTE)
	{
		iDtmfPType = 97;
	}
	else
	{
		iDtmfPType = Rtp_iDtmfPayloadType;
	}
	iAudioType = CODEC_NULL;
	iIlbcPType = Rtp_iPeerIlbcPType;
	iDstPort = 0;
	iRtcpPort = 0;
	bValidIP = FALSE;
	bMediaAudio = FALSE;
	p_memset_x(pDstIP, 0, IP_ALEN);

	for (i = 0; i < iRecvSdpNum; i ++)
	{
		SdramReadString((USHORT)(PROTOCOL_SDRAM_POS+MGCP_RECV_SDP_LO + i));
		pCur = (PXCHAR)Sdram_pDataCache;

		switch (pCur[0])
		{
		case 'v':
			if (p_memcmp_c2x(pCur, Sdp_cV0, V0_LABEL_LEN))
			{
				return FALSE;
			}
			break;
		case 'o':	// o=<username> <session id> <version> <network type> <address type> <address> 
			// o=<username>
			if (!bValidIP)
			{
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <session id>
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <version>
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <network type>
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <address type>
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <address>
				if (!p_String2IP(pCur, pDstIP))
				{
					// address is a domain name;
					DebugString(pCur);
					return FALSE;
				}
			}
			break;
		case 'c':	// c=<network type> <address type> <connection address>
			// c=<network type>
			if (!bValidIP)
			{
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <address type>
				pTemp = p_strchr_x(pCur, ' ');
				if (!pTemp)		return FALSE;
				pCur = pTemp;
				pCur ++;
				// <connection address>
				if (!p_String2IP(pCur, pDstIP))
				{
					// address is a domain name;
					DebugString(pCur);
					return FALSE;
				}
				else
				{
					bValidIP = TRUE;
				}
			}
			break;
		case 'm':	// m=<media> <port> <transport> <fmt list>
			// m=<media>
			pTemp = p_strchr_x(pCur, ' ');
			if (!pTemp)		return FALSE;
			pTemp[0] = 0;
			if (!p_strcmp_c2x(pCur, Sdp_cMAudio))
			{
				bMediaAudio = TRUE;
			}
			else
			{
				bMediaAudio = FALSE;
				break;
			}
			pCur = pTemp;
			pCur ++;
			// <port>
			pTemp = p_strchr_x(pCur, ' ');
			if (!pTemp)		return FALSE;
			pTemp[0] = 0;
			iDstPort = p_atoi(pCur, 10);
			pCur = pTemp;
			pCur ++;
			// <transport>
			pTemp = p_strchr_x(pCur, ' ');
			if (!pTemp)		return FALSE;
			pCur = pTemp;
			pCur ++;
			// <fmt list>
			do
			{
				pTemp = p_strchr_x(pCur, ' ');
				if (pTemp)	pTemp[0] = 0;
				iTemp = (UCHAR)p_atoi(pCur, 10);
				iTemp = RtpGetAudioType(iTemp);
				iTemp = SdpAudioMatch(iTemp);
				if (iTemp != CODEC_NULL)
				{
					iAudioType = iTemp;
					break;
				}
				if (pTemp)
				{
					pCur = pTemp;
					pCur ++;
				}
			}while (pTemp);			
			break;
		case 'a':
			if (bMediaAudio)
			{
				if (p_memcmp_nocase_c2x(pCur, Sdp_cRtpmap, RTPMAP_LABEL_LEN))
				{
					pCur += RTPMAP_LABEL_LEN;
					iTemp = (UCHAR)p_atoi(pCur, 10);
					pTemp = p_strchr_x(pCur, ' ');
					if (!pTemp)		break;
					pCur = pTemp;
					pCur ++;
					if (p_memcmp_nocase_c2x(pCur, Sdp_cTelEvent, TELEVENT_LABEL_LEN))
					{
						iDtmfPType = iTemp;
					}
					else if (p_memcmp_nocase_c2x(pCur, Sdp_cAudioMap[CODEC_ILBC], p_strlen_c(Sdp_cAudioMap[CODEC_ILBC])))
					{
						iIlbcPType = iTemp;
						if (iAudioType == CODEC_NULL)
						{
							iTemp = SdpAudioMatch(CODEC_ILBC);
							if (iTemp != CODEC_NULL)		iAudioType = iTemp;
						}
					}
					break;
				}
				if (p_memcmp_nocase_c2x(pCur, Sdp_cRtcp, RTCP_LABEL_LEN))
				{
					pCur += RTCP_LABEL_LEN;
					iRtcpPort = (UCHAR)p_atoi(pCur, 10);
					break;
				}
			}
			break;
		}
	}

	if (iAudioType == CODEC_NULL)	
		return FALSE;

	if (!iRtcpPort)
	{
		iRtcpPort = iDstPort + 1;
	}

	p_memcpy_ip(Sys_pRemoteIP, pDstIP);
	Rtp_iDstPort = iDstPort;
	Rtcp_iDstPort = iRtcpPort;
	Sys_iAudioType = iAudioType;
	Rtp_iDtmfPayloadType = iDtmfPType;
	Rtp_iPeerIlbcPType = iIlbcPType;
	return TRUE;
}
