/****************************************************************************** * FILE: RtpApp2.cpp * Description: * Implement for CRtpApp2 class. * * Modified Code History * Mark Date By Modification Reason ******************************************************************************* * 01 2010-10-3 songxw Initial creation. ******************************************************************************/ #include #include #include "RtpApp2.h" CRtpApp2::CRtpApp2() { tsunit = 1.0 / 8000.0; bSendTo = false; struct timezone tzone; gettimeofday(&RunTime, &tzone); SeqNum = 0; SendTimeForNAT = 0; } CRtpApp2::~CRtpApp2() { } /****************************************************************************** * Function: * Create rtp session and be ready for receiving data. ******************************************************************************/ int CRtpApp2::CreateSession(UINT16 ListenPort, UINT32 nSsrc, bool usethread) { SessParams.SetUsePollThread(usethread); SessParams.SetOwnTimestampUnit(tsunit); SessParams.SetAcceptOwnPackets(true); TransParams.SetPortbase(ListenPort); SessParams.SetMaximumPacketSize(60*1024); if(nSsrc > 0) { SessParams.SetUsePredefinedSSRC(true); SessParams.SetPredefinedSSRC(nSsrc); } int iErrNum = Create(SessParams, &TransParams); if (iErrNum < 0) { string RtpError = RTPGetErrorString(iErrNum); DBGPrint(M_RtpSessMgr, ERROR_LEVEL, "Create RTP Session error! Reason: %s!", RtpError.c_str() ); return -1; } SetDefaultPayloadType(0); SetDefaultMark(false); SetDefaultTimestampIncrement(0); // IncrementTimestampDefault(); // IncrementTimestamp(1); return 0; } /****************************************************************************** * Function: * Set source ip address, port and session ID. Send several packets to traverse * NAT. ******************************************************************************/ int CRtpApp2::NatMappingControl(char IpStr[], UINT16 port, int SSId) { SessionID = SSId; RTPIPv4Address RtpAddr( ntohl(inet_addr(IpStr) ), port); int iErrNum = AddDestination(RtpAddr); if (iErrNum != 0) { string RtpError = RTPGetErrorString(iErrNum); DBGPrint(M_RtpSessMgr, ERROR_LEVEL, "AddDestination <%s: %d> fail! Reason: %s!", IpStr, port, RtpError.c_str() ); return -1; } SendNatMappingPacket(); usleep(1000); SendNatMappingPacket(); usleep(1000); SendNatMappingPacket(); return 0; } /****************************************************************************** * Function: * Hook function of receiving a rtp packet. ******************************************************************************/ void CRtpApp2::CBRtpRecv2() { } /****************************************************************************** * Function: * Rtp session data poll function. ******************************************************************************/ void CRtpApp2::OnPollThreadStep() { CBRtpRecv2(); } /****************************************************************************** * Function: * Bye operation of rtp session. ******************************************************************************/ void CRtpApp2::RtpDestroy() { BYEDestroy(RTPTime(1, 0), 0, 0); } /****************************************************************************** * Function: * Send a packet to traverse NAT and keep mapping status to let rtp data come. ******************************************************************************/ void CRtpApp2::SendNatMappingPacket(void) { UINT8 data[48+1] = {0}; //Set version and payload type data[0] = 0x80; data[1] = 0x30; //Mark is always true. 0xb0 = 0x80 + 0x30 //Set sequence number *( (UINT16 *)&data[2] ) = htons(SeqNum++); struct timeval CurrTVal; struct timezone tzone; gettimeofday(&CurrTVal, &tzone); int timestamp = (CurrTVal.tv_sec - RunTime.tv_sec) * 1000 + (CurrTVal.tv_usec - RunTime.tv_usec) / 1000; //(ms) //Set timestamp *( (UINT32 *)&data[4] ) = htonl(timestamp); //Set SSRC *( (UINT32 *)&data[8] ) = htonl(SessionID); //Set payload data snprintf( (char *)&data[12], 36, "%s", "A Packet to traverse NAT."); SendPacketIntegratedData(data, 48); }