359 lines
8.4 KiB
C
359 lines
8.4 KiB
C
/****************************************************************/
|
|
/* RTP Implementation Program */
|
|
/* Version 9.0.1 */
|
|
/* Designed By Ying Min */
|
|
/* Last Update: 2007-3-19 */
|
|
/****************************************************************/
|
|
|
|
#include "./include/rtp_pub.h"
|
|
#include "./include/rtp.h"
|
|
#include "./include/rtp_const.h"
|
|
#include "./include/rtp_def.h"
|
|
#include "./include/rtp_struct.h"
|
|
#include "./include/rtp_msg.h"
|
|
|
|
int rtp_get_local_ip(void)
|
|
{
|
|
struct hostent *host;
|
|
char hostName[64];
|
|
char hostIp[32];
|
|
|
|
if (gethostname(hostName, 50) == -1)
|
|
{
|
|
printf("RTP gethostname fail!\n");
|
|
exit(3);
|
|
}
|
|
|
|
if ((host = gethostbyname(hostName)) == NULL)
|
|
{
|
|
printf("RTP gethostbyname fail!\n");
|
|
exit(4);
|
|
}
|
|
else
|
|
{
|
|
sprintf(hostIp, "%d.%d.%d.%d",
|
|
(BYTE)host->h_addr_list[0][0],
|
|
(BYTE)host->h_addr_list[0][1],
|
|
(BYTE)host->h_addr_list[0][2],
|
|
(BYTE)host->h_addr_list[0][3]);
|
|
rtpHostIp = inet_addr(hostIp); // Network byte order host_ip, like 0xE60012AC
|
|
printf("RTP host IP: %s (0x%lX)\n", hostIp, rtpHostIp);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void rtp_init(void)
|
|
{
|
|
WORD i;
|
|
|
|
printf("RTP Init Start!\n");
|
|
|
|
rtp_get_local_ip();
|
|
|
|
memset((BYTE *) rtpSap, 0, sizeof(RTP_SAP) * RTP_MAX_NUM_OF_SAP);
|
|
memset((BYTE *) rtpPort, 0, RTP_MAX_NUM_OF_PORT / 8);
|
|
memset((BYTE *) rtpHdlPort, 0, sizeof(RTP_PORT) * RTP_MAX_NUM_OF_PORT);
|
|
memset((BYTE *) rtpHdlPortFd, -1, sizeof(int) * RTP_MAX_NUM_OF_PORT);
|
|
for (i = 0; i < RTP_MAX_NUM_OF_PORT; i++)
|
|
rtpHdlPort[i].fd = -1;
|
|
|
|
rtpHdlPortSelect = 0;
|
|
rtpPortSelect = 0;
|
|
RTP_BASE_UDP_PORT = RTP_BASE_UDP_PORT_CONST;
|
|
/*
|
|
{
|
|
FILE *fp=NULL;
|
|
unsigned short base_port=25000;
|
|
char s[80]="";
|
|
|
|
fp = fopen("./conf/rtp.conf","r");
|
|
if(fp != NULL)
|
|
{
|
|
while(fgets(s,1024,fp) !=(char *)0)
|
|
{
|
|
if( (int *)strchr(s,'#') !=NULL) continue;
|
|
if( !strlen(s) ) continue;
|
|
if(strncasecmp(s,"base port=",10)==0)
|
|
{
|
|
base_port = atoi(&s[10]);
|
|
if(base_port>1000 && base_port<32768)
|
|
RTP_BASE_UDP_PORT = base_port;
|
|
else
|
|
break;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
fclose(fp);
|
|
}
|
|
|
|
} */
|
|
printf("RTP Init Complete!\n");
|
|
}
|
|
|
|
// Called every 10 ms
|
|
void rtp_timer(void)
|
|
{
|
|
rtp_recv_udp_msg();
|
|
}
|
|
|
|
void rtp_sap_init(BYTE sapIndex)
|
|
{
|
|
memset((BYTE *) &rtpSap[sapIndex], 0, sizeof(RTP_SAP));
|
|
}
|
|
|
|
void rtp_port_init(WORD port)
|
|
{
|
|
memset((BYTE *) &rtpHdlPort[port], 0, sizeof(RTP_PORT));
|
|
rtpHdlPort[port].fd = -1;
|
|
rtpHdlPortFd[port] = -1;
|
|
}
|
|
|
|
int rtp_init_udp_socket(struct sockaddr_in saddr, int multicast)
|
|
{
|
|
int sock;
|
|
long sockBuf = 40*1024;
|
|
int on = 1, timeout = 20;
|
|
|
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
if (sock < 0)
|
|
{
|
|
fprintf(stderr, "Socket() failed\n");
|
|
return -3;
|
|
}
|
|
|
|
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
|
|
&sockBuf, sizeof(sockBuf)) != 0)
|
|
{
|
|
fprintf(stderr, "RTP set socket buffer failed\n");
|
|
return -4;
|
|
}
|
|
|
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
|
|
&on,sizeof(on)) != 0)
|
|
{
|
|
fprintf(stderr, "RTP set addr reusable failed\n");
|
|
return -5;
|
|
}
|
|
|
|
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
|
|
&timeout, sizeof(timeout)) != 0)
|
|
{
|
|
fprintf(stderr, "RTP set keepalive failed\n");
|
|
return -6;
|
|
}
|
|
|
|
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
|
|
{
|
|
fprintf(stderr, "RTP set nonblock failed\n");
|
|
return -7;
|
|
}
|
|
|
|
if (bind(sock, (struct sockaddr *) &saddr, sizeof(struct sockaddr)) < 0)
|
|
{
|
|
fprintf(stderr, "RTP binding failed, port: %d\n", htons(saddr.sin_port));
|
|
close(sock);
|
|
return -2;
|
|
}
|
|
|
|
return sock;
|
|
}
|
|
|
|
int rtp_init_socket(WORD hdlPort, WORD udpPort)
|
|
{
|
|
struct sockaddr_in sinAddr;
|
|
int fd;
|
|
|
|
memset(&sinAddr, 0, sizeof(struct sockaddr));
|
|
sinAddr.sin_family = AF_INET;
|
|
sinAddr.sin_port = htons(udpPort);
|
|
sinAddr.sin_addr.s_addr = rtpHostIp; // INADDR_ANY;
|
|
memset(&(sinAddr.sin_zero), 0, 8);
|
|
|
|
fd = rtp_init_udp_socket(sinAddr, 0);
|
|
if (fd < 0)
|
|
{
|
|
printf("RTP UDP Socket(%d) failed\n", udpPort);
|
|
return -1;
|
|
}
|
|
|
|
rtpHdlPort[hdlPort].fd = fd;
|
|
rtpHdlPortFd[hdlPort] = fd;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rtp_get_udp_port(WORD hdlPort)
|
|
{
|
|
WORD port = rtpPortSelect;
|
|
WORD i, index1, index2;
|
|
|
|
for (i = 0; i < RTP_MAX_NUM_OF_PORT; i++)
|
|
{
|
|
index1 = port / 32;
|
|
index2 = port % 32;
|
|
|
|
if (((rtpPort[index1] >> index2) & 1) == 1)
|
|
{
|
|
if (++port >= RTP_MAX_NUM_OF_PORT)
|
|
port = 0;
|
|
continue;
|
|
}
|
|
|
|
if (rtp_init_socket(hdlPort, port * 2 + RTP_BASE_UDP_PORT) < 0)
|
|
return -1;
|
|
|
|
rtpPort[index1] |= 1 << index2;
|
|
rtpPortSelect = (port + 1) & RTP_MAX_NUM_OF_PORT_1;
|
|
|
|
rtpHdlPort[hdlPort].rtpPort = port;
|
|
return port;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int rtp_release_udp_port(WORD hdlPort)
|
|
{
|
|
WORD port = rtpHdlPort[hdlPort].rtpPort;
|
|
int fd = rtpHdlPort[hdlPort].fd;
|
|
WORD index1, index2;
|
|
|
|
if (port >= RTP_MAX_NUM_OF_PORT)
|
|
return -1;
|
|
|
|
index1 = port / 32;
|
|
index2 = port % 32;
|
|
rtpPort[index1] = rtpPort[index1] & (~(1 << index2));
|
|
|
|
if (fd >= 0)
|
|
close(fd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rtp_get_hdl_port()
|
|
{
|
|
WORD port = rtpHdlPortSelect;
|
|
WORD i;
|
|
|
|
for (i = 0; i < RTP_MAX_NUM_OF_PORT; i++)
|
|
{
|
|
if (rtpHdlPort[port].flag != 0)
|
|
{
|
|
if (++port >= RTP_MAX_NUM_OF_PORT)
|
|
port = 0;
|
|
continue;
|
|
}
|
|
return port;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int rtp_allocate_port(BYTE sapIndex, WORD usrPort, WORD *rtpPort)
|
|
{
|
|
int hdlPort, udpPort;
|
|
|
|
if (sapIndex >= RTP_MAX_NUM_OF_SAP)
|
|
return -1;
|
|
|
|
if ((hdlPort = rtp_get_hdl_port()) < 0)
|
|
return -1;
|
|
|
|
if ((udpPort = rtp_get_udp_port(hdlPort)) < 0)
|
|
return -1;
|
|
|
|
rtpHdlPort[hdlPort].flag = 1;
|
|
rtpHdlPort[hdlPort].sapIndex = sapIndex;
|
|
rtpHdlPort[hdlPort].usrPort = usrPort;
|
|
rtpHdlPort[hdlPort].timer = RTP_HANDSHAKE_TIMER;
|
|
|
|
rtpHdlPortSelect = (hdlPort + 1) & RTP_MAX_NUM_OF_PORT_1;
|
|
|
|
*rtpPort = udpPort * 2 + RTP_BASE_UDP_PORT;
|
|
return hdlPort;
|
|
}
|
|
|
|
int rtp_release_port(BYTE sapIndex, WORD usrPort, WORD rtpPort, WORD hdlPort)
|
|
{
|
|
if (hdlPort >= RTP_MAX_NUM_OF_PORT)
|
|
return -1;
|
|
|
|
if (rtpHdlPort[hdlPort].sapIndex != sapIndex)
|
|
return -2;
|
|
else if (rtpHdlPort[hdlPort].usrPort != usrPort)
|
|
return -3;
|
|
else if ((rtpHdlPort[hdlPort].rtpPort * 2 + RTP_BASE_UDP_PORT) != rtpPort)
|
|
return -4;
|
|
|
|
rtp_release_udp_port(hdlPort);
|
|
|
|
rtp_port_init(hdlPort);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rtp_sess_update(BYTE sapIndex, WORD usrPort, WORD hdlPort, RTP_SESSION *sess)
|
|
{
|
|
if (hdlPort >= RTP_MAX_NUM_OF_PORT)
|
|
return -1;
|
|
|
|
if ((rtpHdlPort[hdlPort].sapIndex != sapIndex) ||
|
|
(rtpHdlPort[hdlPort].usrPort != usrPort))
|
|
return -1;
|
|
|
|
memcpy((BYTE *) &rtpHdlPort[hdlPort].sess, (BYTE *) sess, sizeof(RTP_SESSION));
|
|
|
|
rtpHdlPort[hdlPort].inc = rtpHdlPort[hdlPort].sess.interval * 8;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rtp_set_mode(BYTE sapIndex, WORD usrPort, WORD hdlPort, BYTE mode)
|
|
{
|
|
if ((hdlPort >= RTP_MAX_NUM_OF_PORT) || (mode > RTP_MODE_SENDRECV))
|
|
return -1;
|
|
|
|
if ((rtpHdlPort[hdlPort].sapIndex != sapIndex) ||
|
|
(rtpHdlPort[hdlPort].usrPort != usrPort))
|
|
return -1;
|
|
|
|
rtpHdlPort[hdlPort].mode = mode;
|
|
return 0;
|
|
}
|
|
|
|
int rtp_bind(RTP_SAP *sap)
|
|
{
|
|
BYTE i;
|
|
|
|
if ((sap == NULL) || (sap->rtp_handshake == NULL))
|
|
return -1;
|
|
|
|
for (i = 0; i < RTP_MAX_NUM_OF_SAP; i++)
|
|
{
|
|
if (rtpSap[i].rtp_handshake != NULL)
|
|
continue;
|
|
memcpy((BYTE *) &rtpSap[i], sap, sizeof(RTP_SAP));
|
|
rtpSap[i].name[RTP_MAX_USER_NAME_LEN - 1] = '\0';
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int rtp_unbind(RTP_SAP *sap, BYTE sapIndex)
|
|
{
|
|
if ((sap == NULL) || (sapIndex >= RTP_MAX_NUM_OF_SAP))
|
|
return -1;
|
|
|
|
if (strcmp(sap->name, rtpSap[sapIndex].name) != 0)
|
|
return -1;
|
|
|
|
rtp_sap_init(sapIndex);
|
|
|
|
return 0;
|
|
}
|