//JRTPLIB sender on ADSP-BF537
//wangsu820@163.com 2008-06-30
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sys/socket.h>
#include "rtpsession.h"
#include "rtpsessionparams.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtperrors.h"
using namespace std;
//调试信息功能
#define DEBUG
void checkerror( int errorcode )
{
if( errorcode < 0 )
{
std::cout<< "ERROR:" << RTPGetErrorString( errorcode ) << std::endl;
exit( -1 );
}
}
void usage( void )
{
std::cout << "Usage: ./bf537_send DestinationIPAddress DestinationPort FilePath" << std::endl;
}
long getfilelen( FILE *fp )
{
long cur_pos;
long len;
if( NULL == fp )
{
printf( "FILE fp is NULL/n" );
exit(-1);
}
cur_pos = ftell( fp );
fseek( fp, 0, SEEK_END );
len = ftell( fp );
fseek( fp, cur_pos, SEEK_SET );
return len;
}
int main( int argc, char **argv )
{
RTPSession rtpsess;
RTPSessionParams sessionparams;
RTPUDPv4TransmissionParams transparams;
unsigned long destip;
int destport, srcport = 8000;
char *filepath;
FILE *fp;
long filelength, templength, maxpacket, sendsize;
unsigned char *mem;
int status;
//命令行参数解析
if( argc != 4 )
{
usage();
return -1;
}
destip = inet_addr( argv[1] );
if( INADDR_NONE == destip )
{
cerr << "Bad IP Address" << endl;
return -1;
}
destip = ntohl( destip );
cout << "Destination IP Address:"
<< argv[1]
<< endl;
destport = atoi( argv[2] );
cout << "Destination Port:"
<< destport
<< endl;
strcpy( filepath, argv[3] );
cout << "FilePath:"
<< filepath
<< endl;
//创建会话
sessionparams.SetOwnTimestampUnit( 1.0 / 8000.0 );
transparams.SetPortbase( srcport );
status = rtpsess.Create( sessionparams, &transparams );
#ifdef DEBUG
cout << "check if Create Session error" << endl;
#endif
checkerror( status );
//将目标地址添加到发送地址列表中
RTPIPv4Address addr( destip, destport );
status = rtpsess.AddDestination( addr );
#ifdef DEBUG
cout << "check if AddDestination error" << endl;
#endif
checkerror( status );
//设置RTP包的默认参数
rtpsess.SetDefaultPayloadType( 0 );
rtpsess.SetDefaultMark( false );
rtpsess.SetDefaultTimestampIncrement( 10 );
//打开文件
fp = fopen( filepath, "rb" );
if( NULL == fp )
{
perror( "fopen:" );
exit(-1);
}
//获取文件大小
filelength = getfilelen( fp );
#ifdef DEBUG
printf( "the size of %s is %ldKB/n", filepath, (filelength / 1024) );
#endif
//获取所允许的最大包的大小
maxpacket = sessionparams.GetMaximumPacketSize();
#ifdef DEBUG
printf( "maximum packet size is %ldKB/n", (maxpacket / 1024) );
#endif
maxpacket -= 12;
#ifdef DEBUG
printf( "maximum payload size per packet is %ldKB(%ldB)/n", (maxpacket / 1024), maxpacket );
#endif
//分配内存空间,存放整个文件
mem = (unsigned char *)malloc( filelength );
#ifdef DEBUG
printf( "memory buffer is 0x%8x/n", (int)mem );
#endif
//读取文件内容到内存
templength = fread( mem, 1, filelength, fp );
if( templength != filelength )
{
printf( "fread error: templength=%ld, filelength=%ld/n", templength, filelength );
exit(-1);
}
#ifdef DEBUG
printf( "Have fread %ldKB/n", (templength / 1024) );
#endif
//关闭文件
fclose( fp );
sendsize = filelength;
//发送文件
if( filelength <= maxpacket )
{
#ifdef DEBUG
printf( "we will send data in a single packet/n" );
#endif
status = rtpsess.SendPacket( mem, filelength );
checkerror( status );
printf( "Sent %s...[%ldKB/%ldKB]", filepath, (filelength / 1024), (filelength / 1024) );
}
else//filelength > maxpacket文件大于最大包大小,须分包发送
{
#ifdef DEBUG
printf( "we will divide data into serval packets to send/n" );
#endif
while(1)
{
if( sendsize <= maxpacket )
{
status = rtpsess.SendPacket( mem, sendsize );
checkerror( status );
printf( "Sent %s...[%ldKB/%ldKB]/n", filepath,
(filelength / 1024), (filelength / 1024) );
break;
}
status = rtpsess.SendPacket( (void *)mem, maxpacket );
checkerror( status );
sendsize -= maxpacket;
printf( "Sent %s...[%ldKB/%ldKB]/n", filepath,
((filelength - sendsize) / 1024), (filelength / 1024) );
mem += maxpacket;
RTPTime::Wait( RTPTime( 0, 200 ) );
}
}
//离开会话
rtpsess.BYEDestroy( RTPTime( 10, 0 ), 0, 0 );
#ifdef DEBUG
cout << "GoodBye RTP Session" << endl;
#endif
return 0;
}