⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dspoutrtp.cpp

📁 kphone-4.2,SHELL协议的VOIP电话
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <g711.h>#include <qsettings.h>#include <qtimer.h>#include "../dissipate2/sipuri.h"#include "../dissipate2/sipclient.h"#include "audiobuffer.h"#include "rtpdataheader.h"#include "dspoutrtp.h"#include "kphone.h"short ILBCencode_20( iLBC_Enc_Inst_t *iLBCenc_inst,short *encoded_data, short *data);short ILBCdecode_20( iLBC_Dec_Inst_t *iLBCdec_inst,short *decoded_data, short *encoded_data, short mode);short ILBCencode_30( iLBC_Enc_Inst_t *iLBCenc_inst,short *encoded_data, short *data);short ILBCdecode_30( iLBC_Dec_Inst_t *iLBCdec_inst,short *decoded_data, short *encoded_data, short mode);DspOutRtp::DspOutRtp( const codecType newCodec, int newCodecNum, const QString &hostName, UDPMessageSocket *s )	: portnum(0)	, curseq(0)	, qlen(0)	, numunsend(0)	, fixedrtplen(160)	, deb_frag(0L)	, deb_rtp(0L)	, ssrc(10)	, ref_sec(0)	, ref_usec(0)	, dsize(4096)	, useStun(false)	, destroySocket(false){	#ifdef SRTP	QSettings settings;	if(settings.readEntry("/kphone/SRTP/Enable", "") == "Yes"){		wrapper = SRTPWrapper::getInstance();	} else{		wrapper = 0;		}	#endif	codec = newCodec;	codecNum = newCodecNum;	if (s) {		socket = s;	} else {		socket = new UDPMessageSocket();		destroySocket = true;		if (socket == 0) {			printf( QObject::tr("DspOutRtp:: Can't create socket") + "\n" );			abort();		}	}	if( hostName != QString::null && !socket->setHostname( hostName.latin1() ) ) {		printf( QObject::tr("DspOutRtp::Hostname lookup failed") + "\n" );	}	if( !( gsmInstEnc = gsm_create() ) ) {		printf( "DspOutRtp::GSM_CREATE -error !\n" );	}	if( !( gsmInstDec = gsm_create() ) ) {		printf( "DspOutRtp::GSM_CREATE -error !\n" );	}	packetbuf = new unsigned char[ sizeof( rtp_hdr_t ) + dsize ];	bufunsend = new unsigned char[ dsize ];	outbuf = new unsigned char[ dsize ];	tmpbuf = new unsigned char[ dsize ];	quebuf = new unsigned char[ dsize ];	initEncode(&ilbcEncInst_20, 20 );	initDecode(&ilbcDecInst_20, 20, 1);	initEncode(&ilbcEncInst_30, 30 );	initDecode(&ilbcDecInst_30, 30, 1);	audio_buf.resize( dsize * sizeof( short )  );	setDeviceName("rtp");}DspOutRtp::~DspOutRtp( void ){	if( gsmInstEnc ) gsm_destroy( gsmInstEnc );	if( gsmInstDec ) gsm_destroy( gsmInstDec );	delete[] static_cast<unsigned char *>( packetbuf );	delete[] static_cast<unsigned char *>( bufunsend );	delete[] static_cast<unsigned char *>( outbuf );	delete[] static_cast<unsigned char *>( tmpbuf );	delete[] static_cast<unsigned char *>( quebuf );	if (destroySocket) delete socket;	#ifdef SRTP	if(!wrapper == 0){		wrapper->dispose();	}	#endif}bool DspOutRtp::openDevice( DeviceMode mode ){	int min, max;	QSettings settings;	min = settings.readNumEntry("/kphone/Media/MinPort", constMinPort);	max = settings.readNumEntry("/kphone/Media/MaxPort", constMaxPort);	devmode = mode;	if( devmode == ReadOnly ) {		socket->listenOnEvenPort(min, max);		portnum = socket->getPortNumber();		/* Use STUN to rewrite port number only if the user		 * didn't set a static port range which is being forwarded		 * on the NAT		 */		if ((min == 0) && (max == 0)) {			if ( sendStunRequest( socket ) ) {				portnum = receiveStunResponse( socket );				if( portnum > 0 ) {					socket->forcePortNumber( portnum );				}			}		}//------------------------------// Linux kernels 2.4.x// Do not allow any double binds even when same user and REUSEADDR./*		UDPMessageSocket *socketVideo = new UDPMessageSocket() ;		socketVideo->forcePortNumber( videoPortnum );		socketVideo->listenOnEvenPortForVideo();		videoPortnum = socketVideo->getPortNumber();		socketVideo->forcePortNumber( videoPortnum );		if( sendStunRequest( *socketVideo ) ) {			videoPortnum = receiveStunResponse( *socketVideo );		}		delete socketVideo;*/		videoPortnum = portnum + 20;//------------------------------	} else {          if( socket->connect( portnum ) ) {            if ( socket->SetTOS() )              return false ;            }          else             return false;        }	devstate = DeviceOpened;	return true;}#define PCMUCODEC 0#define GSMCODEC 3#define PCMACODEC 8typedef struct cb {unsigned char (*func)( int frombuf );} cb_t;bool DspOutRtp::writeBuffer( void ){	short *s;	short *frombuf;	unsigned char *databuf;	rtp_hdr_t *h = (rtp_hdr_t *) packetbuf;	size_t fromsize;	unsigned char *wlbuf;	size_t bytesnew;	size_t bytesgot;	int tmpsize;	unsigned int i;	bytesnew = audio_buf.getSize() / sizeof( short );	fromsize = audio_buf.getSize() / sizeof( short );	inbuf = (unsigned char*)audio_buf.getData();	frombuf = (short *)inbuf;	if( codec == codecGSM ) {		short *frombuf_test;		frombuf_test = frombuf;		s = (short *)inbuf;		for( i=0; i<fromsize; ++i) {			s[i] = (short)(*frombuf_test);			++frombuf_test;		}		tmpsize = writeGSMBuffer( gsmInstEnc, inbuf, outbuf, tmpbuf, quebuf, &qlen, fromsize );		h->version = 2;		h->p = 0;		h->x = 0;		h->cc = 0;		h->m = 0;		h->pt = GSMCODEC;		while( tmpsize > 0 ) {			h->seq = htons( ++curseq );			h->ts = htonl( ts );			ts += GSM_DEC_SAMPLES;			h->ssrc = ssrc;			databuf = packetbuf + sizeof( rtp_hdr_t );			for( int i = 0; i < tmpsize; ++i ) {				databuf[ i ] = outbuf[ i ];			}			#ifdef SRTP			int* length = new int(sizeof( rtp_hdr_t ) + tmpsize);			if(!wrapper == 0){				wrapper->protect(packetbuf, length);			}			if( socket->send( (char *) packetbuf, *length) < 0 ) {			#else			if( socket->send( (char *) packetbuf, sizeof( rtp_hdr_t ) + tmpsize ) < 0 ) {			#endif				printf("DspOutRtp::writeBuffer: %s\n", strerror(errno));				return false;			}			tmpsize = writeGSMBuffer( gsmInstEnc, inbuf, outbuf, tmpbuf, quebuf, &qlen, 0 );		}	}	else if( codec == codecILBC_20 || codec == codecILBC_30 ) {		short *frombuf_test;		frombuf_test = frombuf;		s = (short *)inbuf;		for( i=0; i<fromsize; ++i) {			s[i] = (short)(*frombuf_test);			++frombuf_test;		}		if( codec == codecILBC_20 ) {			tmpsize = writeILBCBuffer_20( &ilbcEncInst_20, inbuf, outbuf, tmpbuf, quebuf, &qlen, fromsize );		} else {			tmpsize = writeILBCBuffer_30( &ilbcEncInst_30, inbuf, outbuf, tmpbuf, quebuf, &qlen, fromsize );		}		h->version = 2;		h->p = 0;		h->x = 0;		h->cc = 0;		h->m = 0;		h->pt = codecNum;		while( tmpsize > 0 ) {			h->seq = htons( ++curseq );			h->ts = htonl( ts );			if( codec == codecILBC_20 ) {				ts += BLOCKL_20MS;			} else {				ts += BLOCKL_30MS;			}			h->ssrc = ssrc;			databuf = packetbuf + sizeof( rtp_hdr_t );			for( int i = 0; i < tmpsize; ++i ) {				databuf[ i ] = outbuf[ i ];			}			#ifdef SRTP			int* length = new int(sizeof( rtp_hdr_t ) + tmpsize);			if(!wrapper == 0){				wrapper->protect(packetbuf, length);			}			if( socket->send( (char *) packetbuf, *length) < 0 ) {			#else			if( socket->send( (char *) packetbuf, sizeof( rtp_hdr_t ) + tmpsize ) < 0 ) {			#endif				printf("DspOutRtp::writeBuffer: %s\n", strerror(errno));				return false;			}			if( codec == codecILBC_20 ) {				tmpsize = writeILBCBuffer_20( &ilbcEncInst_20, inbuf, outbuf, tmpbuf, quebuf, &qlen, 0 );			} else {				tmpsize = writeILBCBuffer_30( &ilbcEncInst_30, inbuf, outbuf, tmpbuf, quebuf, &qlen, 0 );			}		}	}	else if( codec == codecPCMA || codec == codecPCMU ) {		cb_t callb;		wlbuf = bufunsend;		h->version = 2;		h->p = 0;		h->x = 0;		h->cc = 0;		h->m = 0;		switch ( codec ) {          case codecPCMU:			  h->pt = PCMUCODEC;			  callb.func = &linear2ulaw;			  break;		  case codecPCMA:			  h->pt = PCMACODEC;			  callb.func = &linear2pcma;		  default:			  break;		}		while(bytesnew+numunsend >= fixedrtplen){			++deb_rtp;			h->seq = htons( ++curseq );			h->ts = htonl( ts );			ts += fixedrtplen;			h->ssrc = ssrc;			databuf = packetbuf + sizeof( rtp_hdr_t );			bytesgot = 0;			while( numunsend > 0 ) {				*databuf = *wlbuf;				++databuf;				++wlbuf;				--numunsend;				++bytesgot;			}			wlbuf = bufunsend;			while( bytesgot < fixedrtplen ) {				*databuf = callb.func( *frombuf );				++databuf;				++frombuf;				--bytesnew;				++bytesgot;			}			#ifdef SRTP			int* length = new int(sizeof( rtp_hdr_t ) + fixedrtplen);			if(!wrapper == 0){				wrapper->protect(packetbuf, length);			}			if( socket->send( (char *) packetbuf, *length ) < 0 ) {			#else			if( socket->send( (char *) packetbuf, sizeof( rtp_hdr_t ) + fixedrtplen ) < 0 ) {			#endif				printf("DspOutRtp::writeBuffer: %s\n", strerror(errno));				return false;			}		}		if( bytesnew > 0 ) {			wlbuf = bufunsend + numunsend;			numunsend += bytesnew;			while( bytesnew > 0 ){				*wlbuf = callb.func( *frombuf );				++wlbuf;				++frombuf;				--bytesnew;			}		}		++deb_frag;	}	else {       printf("DspOutRtp::writeBuffer: unknown Codec %i\n",codec);	   return false;	}	return true;}bool DspOutRtp::setPortNum( int newport ){	portnum = newport;	return true;}unsigned int DspOutRtp::readableBytes( void ){	struct timeval timeout;	fd_set read_fds;	int highest_fd;	timeout.tv_sec = 0;	timeout.tv_usec = 0;	FD_ZERO( &read_fds );	FD_SET( socket->getFileDescriptor(), &read_fds );	highest_fd = socket->getFileDescriptor() + 1;retry:	if ( select( highest_fd, &read_fds, NULL, NULL, &timeout ) == -1 ) {		if ( errno == EINTR ) goto retry;		perror( "DspOutRtp::doSelect(): select() punted" );		exit( 1 );	}	if ( FD_ISSET( socket->getFileDescriptor(), &read_fds ) ) {		return 1;	}	return 0;}bool DspOutRtp::readBuffer( int bytes ){	unsigned char *inbuf;	short *outbuf;	int recvsize;	int i;	int size;	recvsize = socket->receive( (char *) packetbuf, sizeof( rtp_hdr_t ) + dsize );	rtp_hdr_t *h = (rtp_hdr_t *) packetbuf;	#ifdef SRTP	if(!wrapper == 0){		int* length = new int(recvsize);		wrapper->unprotect(packetbuf, length);		recvsize = *length;	}	#endif	if( h->pt == PCMUCODEC ) {		audio_buf.resize( ( recvsize - (int) sizeof( rtp_hdr_t ) ) * sizeof( short ) );		outbuf = (short *) audio_buf.getData();		inbuf = &packetbuf[ sizeof( rtp_hdr_t ) ];		for( i = 0; i < recvsize - (int) sizeof( rtp_hdr_t ); ++i ) {			*outbuf = (short) ulaw2linear( inbuf[ i ] );			++outbuf;		}	} else if( h->pt == GSMCODEC ) {		audio_buf.resize( GSM_DEC_SAMPLES * sizeof( short ) );		outbuf = (short *) audio_buf.getData();		inbuf = &packetbuf[ sizeof( rtp_hdr_t ) ];		readGSMBuffer( gsmInstDec, inbuf, tmpbuf, false );		short *s = (short *)tmpbuf;		for( i = 0; i < GSM_DEC_SAMPLES; ++i) {			*outbuf = (short)(s[i]);			++outbuf;		}	} else if( h->pt == PCMACODEC ) {		audio_buf.resize( ( recvsize - (int) sizeof( rtp_hdr_t ) ) * sizeof( short ) );		outbuf = (short *) audio_buf.getData();		inbuf = &packetbuf[ sizeof( rtp_hdr_t ) ];		for( i = 0; i < recvsize - (int) sizeof( rtp_hdr_t ); ++i ) {			*outbuf = (short) pcma2linear( inbuf[ i ] );			++outbuf;		}	} else if( codec == codecILBC_20 && (int)h->pt == codecNum ) {		audio_buf.resize( BLOCKL_20MS * sizeof( short ) );		outbuf = (short *) audio_buf.getData();		inbuf = &packetbuf[ sizeof( rtp_hdr_t ) ];		size = readILBCBuffer_20( &ilbcDecInst_20, inbuf, tmpbuf, 1, false );		short *s = (short *)tmpbuf;		for( i = 0; i < size; ++i) {			*outbuf = (short)(s[i]);			++outbuf;		}	} else if( codec == codecILBC_30 && (int)h->pt == codecNum ) {		audio_buf.resize( BLOCKL_30MS * sizeof( short ) );		outbuf = (short *) audio_buf.getData();		inbuf = &packetbuf[ sizeof( rtp_hdr_t ) ];		size = readILBCBuffer_30( &ilbcDecInst_30, inbuf, tmpbuf, 1, false );		short *s = (short *)tmpbuf;		for( i = 0; i < size; i++) {			*outbuf++ = (short)(s[i]);		}	}	return true;}bool DspOutRtp::sendStunRequest( UDPMessageSocket *socketStun ){	SipUri stun;	if( useStun ) {		stun = SipUri( stunSrv );		if( !socketStun->setHostname( stun.getHostname() ) ) {			return false;		}		socketStun->connect( stun.getPortNumber() );		printf( "DspOutRtp: STUN request\n" );		StunRequestSimple req;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -