📄 rtp.c
字号:
context_list[context_num]->time_elapsed = 0;
context_list[context_num]->version = 0;
context_list[context_num]->marker = 0;
context_list[context_num]->padding = 0;
context_list[context_num]->pt = 0;
context_list[context_num]->hdr_extension = NULL;
if (nb_context == 1)
{
MEM_ALLOC(tab_ssrc);
tab_ssrc[0] = context_list[context_num]->my_ssrc;
}
else
{
tab_ssrc = realloc(tab_ssrc, sizeof(u_int32) * nb_context);
tab_ssrc[nb_context - 1] = context_list[context_num]->my_ssrc;
}
return (0);
}
/**
** Create the context
**/
int RTP_Context_Create(context *cid)
{
context i;
if (nb_context < above_context)
{
for (i = 0; i < above_context; i++)
{
if (context_list[i] == NULL)
break;
}
}
else if (context_list == NULL)
{
i = above_context;
above_context = MAX_CONTEXT;
context_list = (sess_context_t**) calloc(MAX_CONTEXT, sizeof(sess_context_t*));
}
else
{
i = above_context;
above_context += 10;
context_list = realloc(context_list, sizeof(sess_context_t*) *above_context);
}
context_list[i] = malloc(sizeof(sess_context_t));
nb_context++;
Init_Context(i, nb_context);
*cid = i;
return (0);
}
/**
** Destroy the context
**/
int RTP_Context_destroy(context cid)
{
int i1;
int i2;
if (nb_context == 1)
{
free(tab_ssrc);
nb_context--;
}
else
{
for (i1 = 0; i1 < nb_context; i1++)
{
if (context_list[cid]->my_ssrc == tab_ssrc[i1])
{
for (i2 = i1; i2 < nb_context; i2++)
tab_ssrc[i2] = tab_ssrc[i2 + 1];
tab_ssrc[nb_context - 1] = 0;
nb_context--;
tab_ssrc = realloc(tab_ssrc, sizeof(u_int32) * nb_context);
break;
}
}
}
if (context_list[cid]->CSRCList)
free(context_list[cid]->CSRCList);
if (context_list[cid]->hdr_extension)
free(context_list[cid]->hdr_extension);
free(context_list[cid]);
context_list[cid] = NULL;
return (0);
}
/**
** Send the packet
**/
int RTP_Sd_Pkt(context cid, u_int32 ts, u_int8 marker, u_int16 pti, u_int8 *payload, int len, u_int8 padd_len)
{
rtp_pkt *rtp_packet;
int padding = 0;
int ext = 0;
u_int8 csrc_len = 0;
u_int8 csrc_sz = 0;
SOCKADDR_IN sin;
u_int8 *sd_buffer = NULL;
u_int8 hd_len = 12;
u_int16 hd_ext_len = 0;
conx_context_t *conx_cc = NULL;
remote_address_t *remote_dev = NULL;
int sd_buffer_len;
MEM_ALLOC(rtp_packet);
MEM_ALLOC(rtp_packet->RTP_header);
if (context_list[cid]->CSRClen)
{
csrc_len = context_list[cid]->CSRClen;
csrc_sz = csrc_len * 4;
MEM_SALLOC(rtp_packet->RTP_header->csrc, csrc_sz);
rtp_packet->RTP_header->csrc = context_list[cid]->CSRCList;
}
MEM_SALLOC(rtp_packet->payload, len + padd_len);
rtp_packet->payload = payload;
rtp_packet->payload_len = len;
RTP_Session_Restore_Cxinfo(cid, (void **)&conx_cc);
hd_len += csrc_sz;
if (padd_len > 0)
padding = 1;
if (context_list[cid]->hdr_extension)
{
ext = 1;
hd_ext_len = 4 * (1 + ntohs(context_list[cid]->hdr_extension->ext_len));
hd_len += hd_ext_len;
MEM_SALLOC(rtp_packet->RTP_extension, hd_ext_len);
rtp_packet->RTP_extension = context_list[cid]->hdr_extension;
}
sd_buffer = (u_int8 *) malloc(hd_len + len + padd_len);
sd_buffer_len = hd_len + len + padd_len;
RTP_Build_Header(cid, rtp_packet->RTP_header, padding, marker, ext, context_list[cid], pti, ts);
memcpy(sd_buffer, rtp_packet->RTP_header, 12);
memcpy(sd_buffer + 12, rtp_packet->RTP_header->csrc, csrc_sz);
memcpy(sd_buffer + 12 + csrc_sz, rtp_packet->RTP_extension, 4);
memcpy(sd_buffer + 16 + csrc_sz, rtp_packet->RTP_extension->hd_ext, (hd_ext_len - 4));
memcpy(sd_buffer + hd_len, rtp_packet->payload, rtp_packet->payload_len);
memset(sd_buffer + hd_len + len, 0, padd_len);
if (padd_len > 0)
sd_buffer[sd_buffer_len - 1] = padd_len;
remote_dev = conx_cc->send_addr_list;
while (remote_dev)
{
sin.sin_addr.s_addr = inet_addr(remote_dev->address);
sin.sin_family = AF_INET;
sin.sin_port = htons(remote_dev->port);
sendto(remote_dev->socket, sd_buffer, sd_buffer_len, 0,(SOCKADDR *)&sin, sizeof(sin));
remote_dev = remote_dev->next;
}
free(sd_buffer);
return (0);
}
u_int8 Get_Padding(rtp_hdr *rtp_hdr_msg, char *msg, int sz)
{
char padding;
u_int8 len_padding;
/*
* Gestion du padding.
*/
padding = (rtp_hdr_msg->flags & 0x20) >> 5;
if (padding)
memcpy(&len_padding, msg + (sz - 1), 1);
else
len_padding = 0;
return (len_padding);
}
rtp_pkt *Get_RTP_Hdr(char *msg, int sz)
{
char cc;
char ext;
u_int16 hdr_sz;
u_int8 len_padding;
rtp_hdr *rtp_hdr_msg;
rtp_ext *rtp_ext_msg;
rtp_pkt *rtp_pkt_msg;
/*
* Recuperation du rtp_header.
*/
MEM_SALLOC(rtp_hdr_msg, sizeof(rtp_hdr));
memcpy(rtp_hdr_msg, msg, 12);
hdr_sz = 12;
/*
* Recuperation du csrc.
*/
cc = (rtp_hdr_msg->flags) & 0x0f;
if (cc)
{
MEM_SALLOC(rtp_hdr_msg->csrc, (cc * 4));
memcpy(rtp_hdr_msg->csrc, msg + 12, (cc * 4));
hdr_sz += (cc * 4);
}
/*
* Recuperation de Ext_type et Ext_len, puis des Ext.
*/
ext = (rtp_hdr_msg->flags & 0x10) >> 4;
if (ext)
{
MEM_ALLOC(rtp_ext_msg);
memcpy(rtp_ext_msg, msg + 12 + (cc * 4), 4);
MEM_SALLOC(rtp_ext_msg->hd_ext, 4 * rtp_ext_msg->ext_len);
memcpy(rtp_ext_msg->hd_ext, msg + 16 + (cc * 4), (rtp_ext_msg->ext_len * 4));
hdr_sz += (ntohs(rtp_ext_msg->ext_len) * 4) + 4;
}
/*
* Gestion du padding.
*/
len_padding = Get_Padding(rtp_hdr_msg, msg, sz);
/*
* Revoie du packet.
*/
MEM_ALLOC(rtp_pkt_msg);
rtp_pkt_msg->RTP_header = rtp_hdr_msg;
rtp_pkt_msg->RTP_extension = rtp_ext_msg;
rtp_pkt_msg->payload_len = sz - (hdr_sz + len_padding);
MEM_SALLOC(rtp_pkt_msg->payload, rtp_pkt_msg->payload_len);
memcpy(rtp_pkt_msg->payload, msg + hdr_sz, rtp_pkt_msg->payload_len);
return (rtp_pkt_msg);
}
void Free_Tmp_Mem(rtp_pkt *pkt)
{
/*
* Free Memoire.
*/
free(pkt->RTP_extension->hd_ext);
free(pkt->RTP_extension);
free(pkt->RTP_header->csrc);
free(pkt->RTP_header);
free(pkt);
return;
}
void Put_Pkt_in_Context(rtp_pkt *pkt, char *msg, int cid, int sz)
{
int i;
/* SSRC number - send/receive */
context_list[cid]->my_ssrc = ntohl(pkt->RTP_header->ssrc);
/* Number of packets sent - send/receive */
context_list[cid]->sending_pkt_count++;
/* Number of bytes sent - send/receive */
context_list[cid]->sending_octet_count += sz;
/* Version - receive */
context_list[cid]->version = (pkt->RTP_header->flags & 0xd0) >> 6;
/* Marker flag - receive */
context_list[cid]->marker = (pkt->RTP_header->mk_pt & 0x10) >> 7;
/* Padding length - receive */
context_list[cid]->padding = Get_Padding(pkt->RTP_header, msg, sz);
/* CSRC length - send/receive */
context_list[cid]->CSRClen = (pkt->RTP_header->flags & 0x0f);
/* Payload type - send/receive */
context_list[cid]->pt = (pkt->RTP_header->mk_pt & 0x7f);
/* CSRC list - send/receive */
MEM_SALLOC(context_list[cid]->CSRCList, (context_list[cid]->CSRClen * 4));
memcpy(context_list[cid]->CSRCList, pkt->RTP_header->csrc, (context_list[cid]->CSRClen * 4));
/* current value of timestamp - receive */
context_list[cid]->RTP_timestamp = ntohl(pkt->RTP_header->ts);
/* First value of timestamp - send/receive */
if (context_list[cid]->sending_pkt_count == 1)
context_list[cid]->init_RTP_timestamp = context_list[cid]->RTP_timestamp;
/* Time elapsed since the beginning - send/receive */
if (context_list[cid]->sending_pkt_count == 1)
context_list[cid]->time_elapsed = 0;
else
context_list[cid]->time_elapsed = context_list[cid]->RTP_timestamp - context_list[cid]->init_RTP_timestamp;
/* Current sequence number - send/receive */
context_list[cid]->seq_no = ntohs(pkt->RTP_header->sq_nb);
/* First sequence number - send/receive */
if (context_list[cid]->sending_pkt_count == 1)
context_list[cid]->init_seq_no = context_list[cid]->seq_no;
/* Extension header - send/receive */
MEM_ALLOC(context_list[cid]->hdr_extension);
context_list[cid]->hdr_extension->ext_len = ntohs(pkt->RTP_extension->ext_len);
context_list[cid]->hdr_extension->ext_type = ntohs(pkt->RTP_extension->ext_type);
if (context_list[cid]->hdr_extension->ext_len)
{
MEM_SALLOC(context_list[cid]->hdr_extension->hd_ext, (4 * context_list[cid]->hdr_extension->ext_len));
memcpy(context_list[cid]->hdr_extension->hd_ext, pkt->RTP_extension->hd_ext, (4 * context_list[cid]->hdr_extension->ext_len));
for(i = 0; i < context_list[cid]->hdr_extension->ext_len; i++)
context_list[cid]->hdr_extension->hd_ext[i] = ntohl(context_list[cid]->hdr_extension->hd_ext[i]);
}
}
int RTP_Receive(context cid, int fd, char *payload, int *len, struct sockaddr *sin)
{
char *msg;
int sin_len;
int sz;
char buf[MAX_PACKET_LEN];
rtp_pkt *pkt;
/*
* Reception du paquets.
*/
sin_len = sizeof(struct sockaddr_in);
sz = recvfrom(fd, buf, MAX_PACKET_LEN, 0, sin, &sin_len);
/*
* Stockage du paquets.
*/
MEM_SALLOC(msg, sz);
memcpy(msg, buf, sz);
bzero(buf,MAX_PACKET_LEN);
/*
* Recuperation du RTP_Header, RTP_extension, Payload.
*/
pkt = Get_RTP_Hdr(msg, sz);
/*
* Integration du paquets dans le context.
*/
Put_Pkt_in_Context(pkt, msg, cid, sz);
/*
* Gestion du payload.
*/
*len = pkt->payload_len;
memcpy(payload, pkt->payload, *len);
/*
* Print Structure.
*
* print_hdr(pkt);
*/
/*
* Free Memoire.
*/
Free_Tmp_Mem(pkt);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -