Thu Mar 13 07:00:01 CET 2003

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@642 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Matteo Brancaleoni 23 years ago
parent 66a57e51e3
commit 4ebaef0e1c

@ -277,13 +277,13 @@ struct chan_iax2_pvt {
/* Expirey (optional) */ /* Expirey (optional) */
int expirey; int expirey;
/* Next outgoing sequence number */ /* Next outgoing sequence number */
unsigned short oseqno; unsigned char oseqno;
/* Next sequence number they have not yet acknowledged */ /* Next sequence number they have not yet acknowledged */
unsigned short rseqno; unsigned char rseqno;
/* Next incoming sequence number */ /* Next incoming sequence number */
unsigned short iseqno; unsigned char iseqno;
/* Last incoming sequence number we have acknowledged */ /* Last incoming sequence number we have acknowledged */
unsigned short aseqno; unsigned char aseqno;
/* Peer name */ /* Peer name */
char peer[80]; char peer[80];
/* Default Context */ /* Default Context */
@ -606,9 +606,9 @@ void showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx,
subclass = subclass2; subclass = subclass2;
} }
ast_verbose( ast_verbose(
"%s-Frame Retry[%s] -- OSeqno: %4.4d ISeqno: %4.4d Type: %s Subclass: %s\n", "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
(rx ? "Rx" : "Tx"), (rx ? "Rx" : "Tx"),
retries, ntohs(fh->oseqno), ntohs(fh->iseqno), class, subclass); retries, fh->oseqno, fh->iseqno, class, subclass);
fprintf(stderr, fprintf(stderr,
" Timestamp: %05dms SCall: %5.5d DCall: %5.5d [%s:%d]\n", " Timestamp: %05dms SCall: %5.5d DCall: %5.5d [%s:%d]\n",
ntohl(fh->ts), ntohl(fh->ts),
@ -1163,7 +1163,7 @@ static int update_packet(struct ast_iax2_frame *f)
fh->dcallno = ntohs(AST_FLAG_RETRANS | f->dcallno); fh->dcallno = ntohs(AST_FLAG_RETRANS | f->dcallno);
/* Update iseqno */ /* Update iseqno */
f->iseqno = iaxs[f->callno]->iseqno; f->iseqno = iaxs[f->callno]->iseqno;
fh->iseqno = ntohs(f->iseqno); fh->iseqno = f->iseqno;
return 0; return 0;
} }
@ -1398,7 +1398,7 @@ static int forward_delivery(struct ast_iax2_frame *fr)
} }
#endif #endif
static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver) static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int updatehistory)
{ {
int ms,x; int ms,x;
int drops[MEMORY_SIZE]; int drops[MEMORY_SIZE];
@ -1423,10 +1423,12 @@ static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver)
/* Rotate our history queue of "lateness". Don't worry about those initial /* Rotate our history queue of "lateness". Don't worry about those initial
zeros because the first entry will always be zero */ zeros because the first entry will always be zero */
for (x=0;x<MEMORY_SIZE - 1;x++) if (updatehistory) {
iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1]; for (x=0;x<MEMORY_SIZE - 1;x++)
/* Add a history entry for this one */ iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1];
iaxs[fr->callno]->history[x] = ms; /* Add a history entry for this one */
iaxs[fr->callno]->history[x] = ms;
}
/* Initialize the minimum to reasonable values. It's too much /* Initialize the minimum to reasonable values. It's too much
work to do the same for the maximum, repeatedly */ work to do the same for the maximum, repeatedly */
@ -2177,9 +2179,9 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
int res; int res;
unsigned int lastsent; unsigned int lastsent;
/* Allocate an ast_iax2_frame */ /* Allocate an ast_iax2_frame */
if (now) if (now) {
fr = &fr2; fr = &fr2;
else } else
fr = ast_iax2_frame_new(DIRECTION_OUTGRESS, f->datalen); fr = ast_iax2_frame_new(DIRECTION_OUTGRESS, f->datalen);
if (!fr) { if (!fr) {
ast_log(LOG_WARNING, "Out of memory\n"); ast_log(LOG_WARNING, "Out of memory\n");
@ -2220,8 +2222,8 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
fh->scallno = htons(fr->callno | AST_FLAG_FULL); fh->scallno = htons(fr->callno | AST_FLAG_FULL);
fh->ts = htonl(fr->ts); fh->ts = htonl(fr->ts);
fh->oseqno = htons(fr->oseqno); fh->oseqno = fr->oseqno;
fh->iseqno = htons(fr->iseqno); fh->iseqno = fr->iseqno;
/* Keep track of the last thing we've acknowledged */ /* Keep track of the last thing we've acknowledged */
pvt->aseqno = fr->iseqno; pvt->aseqno = fr->iseqno;
fh->type = fr->af.frametype & 0xFF; fh->type = fr->af.frametype & 0xFF;
@ -3491,6 +3493,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
int res; int res;
int updatehistory=1;
int new = NEW_PREVENT; int new = NEW_PREVENT;
char buf[4096]; char buf[4096];
int len = sizeof(sin); int len = sizeof(sin);
@ -3568,10 +3571,13 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
iaxs[fr.callno]->peercallno = (short)(ntohs(mh->callno) & ~AST_FLAG_FULL); iaxs[fr.callno]->peercallno = (short)(ntohs(mh->callno) & ~AST_FLAG_FULL);
if (ntohs(mh->callno) & AST_FLAG_FULL) { if (ntohs(mh->callno) & AST_FLAG_FULL) {
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", ntohs(fh->oseqno), f.frametype, f.subclass); ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
/* Check if it's out of order (and not an ACK or INVAL) */ /* Check if it's out of order (and not an ACK or INVAL) */
fr.oseqno = ntohs(fh->oseqno); fr.oseqno = fh->oseqno;
fr.iseqno = ntohs(fh->iseqno); fr.iseqno = fh->iseqno;
fr.ts = ntohl(fh->ts);
if (ntohs(fh->dcallno) & AST_FLAG_RETRANS)
updatehistory = 0;
if ((iaxs[fr.callno]->iseqno != fr.oseqno) && if ((iaxs[fr.callno]->iseqno != fr.oseqno) &&
(iaxs[fr.callno]->iseqno || (iaxs[fr.callno]->iseqno ||
((f.subclass != AST_IAX2_COMMAND_TXCNT) && ((f.subclass != AST_IAX2_COMMAND_TXCNT) &&
@ -3684,7 +3690,6 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
f.data = empty; f.data = empty;
memset(&ies, 0, sizeof(ies)); memset(&ies, 0, sizeof(ies));
} }
fr.ts = ntohl(fh->ts);
if (f.frametype == AST_FRAME_VOICE) { if (f.frametype == AST_FRAME_VOICE) {
if (f.subclass != iaxs[fr.callno]->voiceformat) { if (f.subclass != iaxs[fr.callno]->voiceformat) {
iaxs[fr.callno]->voiceformat = f.subclass; iaxs[fr.callno]->voiceformat = f.subclass;
@ -3713,7 +3718,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
/* Go through the motions of delivering the packet without actually doing so, /* Go through the motions of delivering the packet without actually doing so,
unless this is a lag request since it will be done for real */ unless this is a lag request since it will be done for real */
if (f.subclass != AST_IAX2_COMMAND_LAGRQ) if (f.subclass != AST_IAX2_COMMAND_LAGRQ)
schedule_delivery(&fr, 0); schedule_delivery(&fr, 0, updatehistory);
switch(f.subclass) { switch(f.subclass) {
case AST_IAX2_COMMAND_ACK: case AST_IAX2_COMMAND_ACK:
/* Do nothing */ /* Do nothing */
@ -3963,7 +3968,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
f.offset = 0; f.offset = 0;
f.samples = 0; f.samples = 0;
ast_iax2_frame_wrap(&fr, &f); ast_iax2_frame_wrap(&fr, &f);
schedule_delivery(iaxfrdup2(&fr), 1); schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
#ifdef BRIDGE_OPTIMIZATION #ifdef BRIDGE_OPTIMIZATION
} }
#endif #endif
@ -4239,10 +4244,10 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
if (iaxs[fr.callno]->bridgecallno) { if (iaxs[fr.callno]->bridgecallno) {
forward_delivery(&fr); forward_delivery(&fr);
} else { } else {
schedule_delivery(iaxfrdup2(&fr), 1); schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
} }
#else #else
schedule_delivery(iaxfrdup2(&fr), 1); schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
#endif #endif
/* Always run again */ /* Always run again */
ast_pthread_mutex_unlock(&iaxsl[fr.callno]); ast_pthread_mutex_unlock(&iaxsl[fr.callno]);

@ -867,14 +867,14 @@ static int process_sdp(struct mgcp_endpoint *p, struct mgcp_request *req)
printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
#endif #endif
// Scan through the RTP payload types specified in a "m=" line: // Scan through the RTP payload types specified in a "m=" line:
rtp_pt_init(p->rtp); ast_rtp_pt_clear(p->rtp);
codecs = m + len; codecs = m + len;
while(strlen(codecs)) { while(strlen(codecs)) {
if (sscanf(codecs, "%d %n", &codec, &len) != 1) { if (sscanf(codecs, "%d %n", &codec, &len) != 1) {
ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
return -1; return -1;
} }
rtp_set_m_type(p->rtp, codec); ast_rtp_set_m_type(p->rtp, codec);
codecs += len; codecs += len;
} }
@ -883,20 +883,14 @@ static int process_sdp(struct mgcp_endpoint *p, struct mgcp_request *req)
sdpLineNum_iterator_init(&iterator); sdpLineNum_iterator_init(&iterator);
while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
char* mimeSubtype = strdup(a); // ensures we have enough space char* mimeSubtype = strdup(a); // ensures we have enough space
int subtypeLen, i;
if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
// Note: should really look at the 'freq' and '#chans' params too // Note: should really look at the 'freq' and '#chans' params too
subtypeLen = strlen(mimeSubtype); ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
// Convert the MIME subtype to upper case, for ease of searching:
for (i = 0; i < subtypeLen; ++i) {
mimeSubtype[i] = toupper(mimeSubtype[i]);
}
rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
free(mimeSubtype); free(mimeSubtype);
} }
// Now gather all of the codecs that were asked for: // Now gather all of the codecs that were asked for:
rtp_get_current_formats(p->rtp, ast_rtp_get_current_formats(p->rtp,
&peercapability, &peerNonCodecCapability); &peercapability, &peerNonCodecCapability);
p->capability = capability & peercapability; p->capability = capability & peercapability;
if (mgcpdebug) { if (mgcpdebug) {
@ -1065,11 +1059,11 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_endpoint *p, struct as
if (p->capability & x) { if (p->capability & x) {
if (mgcpdebug) if (mgcpdebug)
ast_verbose("Answering with capability %d\n", x); ast_verbose("Answering with capability %d\n", x);
codec = rtp_lookup_code(p->rtp, 1, x); codec = ast_rtp_lookup_code(p->rtp, 1, x);
if (codec > -1) { if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec); snprintf(costr, sizeof(costr), " %d", codec);
strcat(m, costr); strcat(m, costr);
snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, rtp_lookup_mime_subtype(1, x)); snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
strcat(a, costr); strcat(a, costr);
} }
} }
@ -1078,11 +1072,11 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_endpoint *p, struct as
if (p->nonCodecCapability & x) { if (p->nonCodecCapability & x) {
if (mgcpdebug) if (mgcpdebug)
ast_verbose("Answering with non-codec capability %d\n", x); ast_verbose("Answering with non-codec capability %d\n", x);
codec = rtp_lookup_code(p->rtp, 0, x); codec = ast_rtp_lookup_code(p->rtp, 0, x);
if (codec > -1) { if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec); snprintf(costr, sizeof(costr), " %d", codec);
strcat(m, costr); strcat(m, costr);
snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, rtp_lookup_mime_subtype(0, x)); snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x));
strcat(a, costr); strcat(a, costr);
if (x == AST_RTP_DTMF) { if (x == AST_RTP_DTMF) {
/* Indicate we support DTMF... Not sure about 16, but MSN supports it so dang it, we will too... */ /* Indicate we support DTMF... Not sure about 16, but MSN supports it so dang it, we will too... */
@ -1121,7 +1115,7 @@ static int transmit_modify_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp
snprintf(local, sizeof(local), "p:20"); snprintf(local, sizeof(local), "p:20");
for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
if (p->capability & x) { if (p->capability & x) {
snprintf(tmp, sizeof(tmp), ", a:%s", rtp_lookup_mime_subtype(1, x)); snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
strcat(local, tmp); strcat(local, tmp);
} }
} }
@ -1146,7 +1140,7 @@ static int transmit_connect_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rt
snprintf(local, sizeof(local), "p:20"); snprintf(local, sizeof(local), "p:20");
for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
if (p->capability & x) { if (p->capability & x) {
snprintf(tmp, sizeof(tmp), ", a:%s", rtp_lookup_mime_subtype(1, x)); snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
strcat(local, tmp); strcat(local, tmp);
} }
} }

@ -1422,14 +1422,14 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
#endif #endif
// Scan through the RTP payload types specified in a "m=" line: // Scan through the RTP payload types specified in a "m=" line:
rtp_pt_init(p->rtp); ast_rtp_pt_clear(p->rtp);
codecs = m + len; codecs = m + len;
while(strlen(codecs)) { while(strlen(codecs)) {
if (sscanf(codecs, "%d %n", &codec, &len) != 1) { if (sscanf(codecs, "%d %n", &codec, &len) != 1) {
ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
return -1; return -1;
} }
rtp_set_m_type(p->rtp, codec); ast_rtp_set_m_type(p->rtp, codec);
codecs += len; codecs += len;
} }
@ -1438,20 +1438,14 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
sdpLineNum_iterator_init(&iterator); sdpLineNum_iterator_init(&iterator);
while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
char* mimeSubtype = strdup(a); // ensures we have enough space char* mimeSubtype = strdup(a); // ensures we have enough space
int subtypeLen, i;
if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
// Note: should really look at the 'freq' and '#chans' params too // Note: should really look at the 'freq' and '#chans' params too
subtypeLen = strlen(mimeSubtype); ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
// Convert the MIME subtype to upper case, for ease of searching:
for (i = 0; i < subtypeLen; ++i) {
mimeSubtype[i] = toupper(mimeSubtype[i]);
}
rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
free(mimeSubtype); free(mimeSubtype);
} }
// Now gather all of the codecs that were asked for: // Now gather all of the codecs that were asked for:
rtp_get_current_formats(p->rtp, ast_rtp_get_current_formats(p->rtp,
&peercapability, &peerNonCodecCapability); &peercapability, &peerNonCodecCapability);
p->capability = capability & peercapability; p->capability = capability & peercapability;
p->nonCodecCapability = nonCodecCapability & peerNonCodecCapability; p->nonCodecCapability = nonCodecCapability & peerNonCodecCapability;
@ -1861,11 +1855,11 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
if (p->capability & cur->codec) { if (p->capability & cur->codec) {
if (sipdebug) if (sipdebug)
ast_verbose("Answering with preferred capability %d\n", cur->codec); ast_verbose("Answering with preferred capability %d\n", cur->codec);
codec = rtp_lookup_code(p->rtp, 1, cur->codec); codec = ast_rtp_lookup_code(p->rtp, 1, cur->codec);
if (codec > -1) { if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec); snprintf(costr, sizeof(costr), " %d", codec);
strcat(m, costr); strcat(m, costr);
snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, rtp_lookup_mime_subtype(1, cur->codec)); snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, cur->codec));
strcat(a, costr); strcat(a, costr);
} }
} }
@ -1877,11 +1871,11 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
if ((p->capability & x) && !(alreadysent & x)) { if ((p->capability & x) && !(alreadysent & x)) {
if (sipdebug) if (sipdebug)
ast_verbose("Answering with capability %d\n", x); ast_verbose("Answering with capability %d\n", x);
codec = rtp_lookup_code(p->rtp, 1, x); codec = ast_rtp_lookup_code(p->rtp, 1, x);
if (codec > -1) { if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec); snprintf(costr, sizeof(costr), " %d", codec);
strcat(m, costr); strcat(m, costr);
snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, rtp_lookup_mime_subtype(1, x)); snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
strcat(a, costr); strcat(a, costr);
} }
} }
@ -1890,11 +1884,11 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
if (p->nonCodecCapability & x) { if (p->nonCodecCapability & x) {
if (sipdebug) if (sipdebug)
ast_verbose("Answering with non-codec capability %d\n", x); ast_verbose("Answering with non-codec capability %d\n", x);
codec = rtp_lookup_code(p->rtp, 0, x); codec = ast_rtp_lookup_code(p->rtp, 0, x);
if (codec > -1) { if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec); snprintf(costr, sizeof(costr), " %d", codec);
strcat(m, costr); strcat(m, costr);
snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, rtp_lookup_mime_subtype(0, x)); snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x));
strcat(a, costr); strcat(a, costr);
if (x == AST_RTP_DTMF) { if (x == AST_RTP_DTMF) {
/* Indicate we support DTMF... Not sure about 16, but MSN supports it so dang it, we will too... */ /* Indicate we support DTMF... Not sure about 16, but MSN supports it so dang it, we will too... */
@ -2894,7 +2888,7 @@ static int sip_show_channel(int fd, int argc, char *argv[])
} }
ast_pthread_mutex_unlock(&iflock); ast_pthread_mutex_unlock(&iflock);
if (!cur) if (!cur)
ast_cli(fd, "No such SIP Call ID '%s'\n", cur->callid); ast_cli(fd, "No such SIP Call ID '%s'\n", argv[3]);
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
@ -4281,7 +4275,7 @@ static int reload_config(void)
} else { } else {
hp = gethostbyname(ourhost); hp = gethostbyname(ourhost);
if (!hp) { if (!hp) {
ast_log(LOG_WARNING, "Unable to get our IP address, SIP disabled\n"); ast_log(LOG_WARNING, "Unable to get IP address for %s, SIP disabled\n", ourhost);
return 0; return 0;
} }
memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); memcpy(&__ourip, hp->h_addr, sizeof(__ourip));

@ -107,12 +107,12 @@ struct ast_iax2_full_hdr {
unsigned short scallno; /* Source call number -- high bit must be 1 */ unsigned short scallno; /* Source call number -- high bit must be 1 */
unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */ unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */
unsigned int ts; /* 32-bit timestamp in milliseconds (from 1st transmission) */ unsigned int ts; /* 32-bit timestamp in milliseconds (from 1st transmission) */
unsigned short oseqno; /* Packet number (outgoing) */ unsigned char oseqno; /* Packet number (outgoing) */
unsigned short iseqno; /* Packet number (next incoming expected) */ unsigned char iseqno; /* Packet number (next incoming expected) */
char type; /* Frame type */ char type; /* Frame type */
unsigned char csub; /* Compressed subclass */ unsigned char csub; /* Compressed subclass */
unsigned char iedata[0]; unsigned char iedata[0];
}; } __attribute__ ((__packed__));
/* Mini header is used only for voice frames -- delivered unreliably */ /* Mini header is used only for voice frames -- delivered unreliably */
struct ast_iax2_mini_hdr { struct ast_iax2_mini_hdr {
@ -121,6 +121,6 @@ struct ast_iax2_mini_hdr {
/* Frametype implicitly VOICE_FRAME */ /* Frametype implicitly VOICE_FRAME */
/* subclass implicit from last ast_iax2_full_hdr */ /* subclass implicit from last ast_iax2_full_hdr */
unsigned char iedata[0]; unsigned char iedata[0];
}; } __attribute__ ((__packed__));
#endif #endif

@ -70,20 +70,22 @@ int ast_rtp_senddigit(struct ast_rtp *rtp, char digit);
int ast_rtp_settos(struct ast_rtp *rtp, int tos); int ast_rtp_settos(struct ast_rtp *rtp, int tos);
// Setting RTP payload types from lines in a SDP description: // Setting RTP payload types from lines in a SDP description:
void rtp_pt_init(struct ast_rtp* rtp); void ast_rtp_pt_clear(struct ast_rtp* rtp);
void rtp_set_m_type(struct ast_rtp* rtp, int pt); /* Set payload types to defaults */
void rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt, void ast_rtp_pt_default(struct ast_rtp* rtp);
void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt);
void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
char* mimeType, char* mimeSubtype); char* mimeType, char* mimeSubtype);
// Mapping between RTP payload format codes and Asterisk codes: // Mapping between RTP payload format codes and Asterisk codes:
struct rtpPayloadType rtp_lookup_pt(struct ast_rtp* rtp, int pt); struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
int rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code); int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
void rtp_get_current_formats(struct ast_rtp* rtp, void ast_rtp_get_current_formats(struct ast_rtp* rtp,
int* astFormats, int* nonAstFormats); int* astFormats, int* nonAstFormats);
// Mapping an Asterisk code into a MIME subtype (string): // Mapping an Asterisk code into a MIME subtype (string):
char* rtp_lookup_mime_subtype(int isAstFormat, int code); char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code);
void ast_rtp_setnat(struct ast_rtp *rtp, int nat); void ast_rtp_setnat(struct ast_rtp *rtp, int nat);

43
rtp.c

@ -39,7 +39,7 @@
static int dtmftimeout = 300; /* 300 samples */ static int dtmftimeout = 300; /* 300 samples */
// The value of each RTP payload format mapping: // The value of each payload format mapping:
struct rtpPayloadType { struct rtpPayloadType {
int isAstFormat; // whether the following code is an AST_FORMAT int isAstFormat; // whether the following code is an AST_FORMAT
int code; int code;
@ -276,7 +276,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
printf("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len = %d)\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); printf("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len = %d)\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
#endif #endif
rtp->f.frametype = AST_FRAME_VOICE; rtp->f.frametype = AST_FRAME_VOICE;
rtpPT = rtp_lookup_pt(rtp, payloadtype); rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
if (!rtpPT.isAstFormat) { if (!rtpPT.isAstFormat) {
// This is special in-band data that's not one of our codecs // This is special in-band data that's not one of our codecs
if (rtpPT.code == AST_RTP_DTMF) { if (rtpPT.code == AST_RTP_DTMF) {
@ -370,7 +370,7 @@ static struct {
{{1, AST_FORMAT_LPC10}, "audio", "LPC"}, {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
{{1, AST_FORMAT_G729A}, "audio", "G729"}, {{1, AST_FORMAT_G729A}, "audio", "G729"},
{{1, AST_FORMAT_SPEEX}, "audio", "SPEEX"}, {{1, AST_FORMAT_SPEEX}, "audio", "SPEEX"},
{{0, AST_RTP_DTMF}, "audio", "TELEPHONE-EVENT"}, {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
{{0, AST_RTP_CN}, "audio", "CN"}, {{0, AST_RTP_CN}, "audio", "CN"},
{{1, AST_FORMAT_JPEG}, "video", "JPEG"}, {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
{{1, AST_FORMAT_PNG}, "video", "PNG"}, {{1, AST_FORMAT_PNG}, "video", "PNG"},
@ -397,9 +397,11 @@ static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
[26] = {1, AST_FORMAT_JPEG}, [26] = {1, AST_FORMAT_JPEG},
[31] = {1, AST_FORMAT_H261}, [31] = {1, AST_FORMAT_H261},
[34] = {1, AST_FORMAT_H263}, [34] = {1, AST_FORMAT_H263},
[101] = {0, AST_RTP_DTMF},
}; };
void rtp_pt_init(struct ast_rtp* rtp) { void ast_rtp_pt_clear(struct ast_rtp* rtp)
{
int i; int i;
for (i = 0; i < MAX_RTP_PT; ++i) { for (i = 0; i < MAX_RTP_PT; ++i) {
@ -412,10 +414,24 @@ void rtp_pt_init(struct ast_rtp* rtp) {
rtp->rtp_lookup_code_cache_result = 0; rtp->rtp_lookup_code_cache_result = 0;
} }
void ast_rtp_pt_default(struct ast_rtp* rtp)
{
int i;
/* Initialize to default payload types */
for (i = 0; i < MAX_RTP_PT; ++i) {
rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
}
rtp->rtp_lookup_code_cache_isAstFormat = 0;
rtp->rtp_lookup_code_cache_code = 0;
rtp->rtp_lookup_code_cache_result = 0;
}
// Make a note of a RTP payload type that was seen in a SDP "m=" line. // Make a note of a RTP payload type that was seen in a SDP "m=" line.
// By default, use the well-known value for this type (although it may // By default, use the well-known value for this type (although it may
// still be set to a different value by a subsequent "a=rtpmap:" line): // still be set to a different value by a subsequent "a=rtpmap:" line):
void rtp_set_m_type(struct ast_rtp* rtp, int pt) { void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type
if (static_RTP_PT[pt].code != 0) { if (static_RTP_PT[pt].code != 0) {
@ -425,15 +441,15 @@ void rtp_set_m_type(struct ast_rtp* rtp, int pt) {
// Make a note of a RTP payload type (with MIME type) that was seen in // Make a note of a RTP payload type (with MIME type) that was seen in
// a SDP "a=rtpmap:" line. // a SDP "a=rtpmap:" line.
void rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt, void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
char* mimeType, char* mimeSubtype) { char* mimeType, char* mimeSubtype) {
int i; int i;
if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type
for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) { for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
if (strcmp(mimeSubtype, mimeTypes[i].subtype) == 0 && if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
strcmp(mimeType, mimeTypes[i].type) == 0) { strcasecmp(mimeType, mimeTypes[i].type) == 0) {
rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType; rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
return; return;
} }
@ -442,7 +458,7 @@ void rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
// Return the union of all of the codecs that were set by rtp_set...() calls // Return the union of all of the codecs that were set by rtp_set...() calls
// They're returned as two distinct sets: AST_FORMATs, and AST_RTPs // They're returned as two distinct sets: AST_FORMATs, and AST_RTPs
void rtp_get_current_formats(struct ast_rtp* rtp, void ast_rtp_get_current_formats(struct ast_rtp* rtp,
int* astFormats, int* nonAstFormats) { int* astFormats, int* nonAstFormats) {
int pt; int pt;
@ -456,7 +472,7 @@ void rtp_get_current_formats(struct ast_rtp* rtp,
} }
} }
struct rtpPayloadType rtp_lookup_pt(struct ast_rtp* rtp, int pt) { struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) {
if (pt < 0 || pt > MAX_RTP_PT) { if (pt < 0 || pt > MAX_RTP_PT) {
struct rtpPayloadType result; struct rtpPayloadType result;
result.isAstFormat = result.code = 0; result.isAstFormat = result.code = 0;
@ -465,7 +481,7 @@ struct rtpPayloadType rtp_lookup_pt(struct ast_rtp* rtp, int pt) {
return rtp->current_RTP_PT[pt]; return rtp->current_RTP_PT[pt];
} }
int rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) { int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
int pt; int pt;
if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat && if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
@ -486,7 +502,7 @@ int rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
return -1; return -1;
} }
char* rtp_lookup_mime_subtype(int isAstFormat, int code) { char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code) {
int i; int i;
for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) { for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
@ -540,6 +556,7 @@ struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io)
rtp->io = io; rtp->io = io;
rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp); rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
} }
ast_rtp_pt_default(rtp);
return rtp; return rtp;
} }
@ -733,7 +750,7 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
return -1; return -1;
} }
codec = rtp_lookup_code(rtp, 1, _f->subclass); codec = ast_rtp_lookup_code(rtp, 1, _f->subclass);
if (codec < 0) { if (codec < 0) {
ast_log(LOG_WARNING, "Don't know how to send format %d packets with RTP\n", _f->subclass); ast_log(LOG_WARNING, "Don't know how to send format %d packets with RTP\n", _f->subclass);
return -1; return -1;

Loading…
Cancel
Save