mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-03 03:02:15 +00:00
mer feb 12 14:56:57 CET 2003
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@612 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
69
rtp.c
69
rtp.c
@@ -61,6 +61,10 @@ struct ast_rtp {
|
||||
ast_rtp_callback callback;
|
||||
};
|
||||
|
||||
int ast_rtp_fd(struct ast_rtp *rtp)
|
||||
{
|
||||
return rtp->s;
|
||||
}
|
||||
|
||||
static int g723_len(unsigned char buf)
|
||||
{
|
||||
@@ -106,7 +110,7 @@ void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
|
||||
rtp->callback = callback;
|
||||
}
|
||||
|
||||
static void send_dtmf(struct ast_rtp *rtp)
|
||||
static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
|
||||
{
|
||||
printf("Sending dtmf: %d (%c)\n", rtp->resp, rtp->resp);
|
||||
rtp->f.frametype = AST_FRAME_DTMF;
|
||||
@@ -116,15 +120,15 @@ static void send_dtmf(struct ast_rtp *rtp)
|
||||
rtp->f.mallocd = 0;
|
||||
rtp->f.src = "RTP";
|
||||
rtp->resp = 0;
|
||||
if (rtp->callback)
|
||||
rtp->callback(rtp, &rtp->f, rtp->data);
|
||||
return &rtp->f;
|
||||
|
||||
}
|
||||
|
||||
static void process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
{
|
||||
unsigned int event;
|
||||
char resp = 0;
|
||||
struct ast_frame *f = NULL;
|
||||
event = ntohl(*((unsigned int *)(data)));
|
||||
event >>= 24;
|
||||
#if 0
|
||||
@@ -140,16 +144,17 @@ static void process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
resp = 'A' + (event - 12);
|
||||
}
|
||||
if (rtp->resp && (rtp->resp != resp)) {
|
||||
send_dtmf(rtp);
|
||||
f = send_dtmf(rtp);
|
||||
}
|
||||
rtp->resp = resp;
|
||||
rtp->dtmfcount = dtmftimeout;
|
||||
return f;
|
||||
}
|
||||
|
||||
static void process_type121(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
static struct ast_frame *process_type121(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
{
|
||||
char resp = 0;
|
||||
|
||||
struct ast_frame *f = NULL;
|
||||
unsigned char b0,b1,b2,b3,b4,b5,b6,b7;
|
||||
|
||||
b0=*(data+0);b1=*(data+1);b2=*(data+2);b3=*(data+3);
|
||||
@@ -169,7 +174,7 @@ static void process_type121(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
resp='A'+(b3-12);
|
||||
}
|
||||
rtp->resp=resp;
|
||||
send_dtmf(rtp);
|
||||
f = send_dtmf(rtp);
|
||||
}
|
||||
}
|
||||
if (b2==3) {
|
||||
@@ -178,11 +183,23 @@ static void process_type121(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||
if (b2==0) {
|
||||
// printf("Stop(0) %d\n",b3);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
static int rtpread(int *id, int fd, short events, void *cbdata)
|
||||
{
|
||||
struct ast_rtp *rtp = cbdata;
|
||||
struct ast_frame *f;
|
||||
f = ast_rtp_read(rtp);
|
||||
if (f) {
|
||||
if (rtp->callback)
|
||||
rtp->callback(rtp, f, rtp->data);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
|
||||
{
|
||||
int res;
|
||||
struct sockaddr_in sin;
|
||||
int len;
|
||||
@@ -191,6 +208,7 @@ static int rtpread(int *id, int fd, short events, void *cbdata)
|
||||
int hdrlen = 12;
|
||||
unsigned int timestamp;
|
||||
unsigned int *rtpheader;
|
||||
static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
|
||||
|
||||
len = sizeof(sin);
|
||||
|
||||
@@ -202,11 +220,11 @@ static int rtpread(int *id, int fd, short events, void *cbdata)
|
||||
ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
|
||||
if (errno == EBADF)
|
||||
CRASH;
|
||||
return 1;
|
||||
return &null_frame;
|
||||
}
|
||||
if (res < hdrlen) {
|
||||
ast_log(LOG_WARNING, "RTP Read too short\n");
|
||||
return 1;
|
||||
return &null_frame;
|
||||
}
|
||||
/* Get fields */
|
||||
seqno = ntohl(rtpheader[0]);
|
||||
@@ -219,19 +237,23 @@ static int rtpread(int *id, int fd, short events, void *cbdata)
|
||||
rtp->f.frametype = AST_FRAME_VOICE;
|
||||
rtp->f.subclass = rtp2ast(payloadtype);
|
||||
if (rtp->f.subclass < 0) {
|
||||
f = NULL;
|
||||
if (payloadtype == 101) {
|
||||
/* It's special -- rfc2833 process it */
|
||||
process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
||||
f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
||||
} else if (payloadtype == 121) {
|
||||
/* CISCO proprietary DTMF bridge */
|
||||
process_type121(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
||||
f = process_type121(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
||||
} else if (payloadtype == 100) {
|
||||
/* CISCO's notso proprietary DTMF bridge */
|
||||
process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
||||
f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
|
||||
} else {
|
||||
ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
|
||||
}
|
||||
return 1;
|
||||
if (f)
|
||||
return f;
|
||||
else
|
||||
return &null_frame;
|
||||
}
|
||||
|
||||
if (!rtp->lastrxts)
|
||||
@@ -253,10 +275,8 @@ static int rtpread(int *id, int fd, short events, void *cbdata)
|
||||
|
||||
/* Send any pending DTMF */
|
||||
if (rtp->resp && !rtp->dtmfcount) {
|
||||
send_dtmf(rtp);
|
||||
/* Setup the voice frame again */
|
||||
rtp->f.frametype = AST_FRAME_VOICE;
|
||||
rtp->f.subclass = rtp2ast(payloadtype);
|
||||
printf("Sending pending DTMF\n");
|
||||
return send_dtmf(rtp);
|
||||
}
|
||||
rtp->f.mallocd = 0;
|
||||
rtp->f.datalen = res - hdrlen;
|
||||
@@ -287,9 +307,7 @@ static int rtpread(int *id, int fd, short events, void *cbdata)
|
||||
break;
|
||||
}
|
||||
rtp->f.src = "RTP";
|
||||
if (rtp->callback)
|
||||
rtp->callback(rtp, &rtp->f, rtp->data);
|
||||
return 1;
|
||||
return &rtp->f;
|
||||
}
|
||||
|
||||
static struct {
|
||||
@@ -370,9 +388,12 @@ struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
rtp->io = io;
|
||||
rtp->sched = sched;
|
||||
rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
|
||||
if (io && sched) {
|
||||
/* Operate this one in a callback mode */
|
||||
rtp->sched = sched;
|
||||
rtp->io = io;
|
||||
rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
|
||||
}
|
||||
return rtp;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user