mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-29 07:24:55 +00:00
Repair offer/answer model (bug #2293), initial CNG work for new frametype
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3658 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1945,6 +1945,7 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
|
|||||||
add_header(&resp, "X", sub->txident);
|
add_header(&resp, "X", sub->txident);
|
||||||
add_header(&resp, "I", sub->cxident);
|
add_header(&resp, "I", sub->cxident);
|
||||||
/*add_header(&resp, "S", "");*/
|
/*add_header(&resp, "S", "");*/
|
||||||
|
ast_rtp_offered_from_local(rtp, 0);
|
||||||
add_sdp(&resp, sub, rtp);
|
add_sdp(&resp, sub, rtp);
|
||||||
/* SC: fill in new fields */
|
/* SC: fill in new fields */
|
||||||
resp.cmd = MGCP_CMD_MDCX;
|
resp.cmd = MGCP_CMD_MDCX;
|
||||||
@@ -1978,6 +1979,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
|
|||||||
/* SC: X header should not be sent. kept for compatibility */
|
/* SC: X header should not be sent. kept for compatibility */
|
||||||
add_header(&resp, "X", sub->txident);
|
add_header(&resp, "X", sub->txident);
|
||||||
/*add_header(&resp, "S", "");*/
|
/*add_header(&resp, "S", "");*/
|
||||||
|
ast_rtp_offered_from_local(rtp, 1);
|
||||||
add_sdp(&resp, sub, rtp);
|
add_sdp(&resp, sub, rtp);
|
||||||
/* SC: fill in new fields */
|
/* SC: fill in new fields */
|
||||||
resp.cmd = MGCP_CMD_CRCX;
|
resp.cmd = MGCP_CMD_CRCX;
|
||||||
|
|||||||
@@ -3511,6 +3511,7 @@ static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_r
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
respprep(&resp, p, msg, req);
|
respprep(&resp, p, msg, req);
|
||||||
|
ast_rtp_offered_from_local(p->rtp, 0);
|
||||||
add_sdp(&resp, p);
|
add_sdp(&resp, p);
|
||||||
return send_response(p, &resp, retrans, seqno);
|
return send_response(p, &resp, retrans, seqno);
|
||||||
}
|
}
|
||||||
@@ -3587,6 +3588,7 @@ static int transmit_reinvite_with_sdp(struct sip_pvt *p)
|
|||||||
reqprep(&req, p, "INVITE", 0, 1);
|
reqprep(&req, p, "INVITE", 0, 1);
|
||||||
|
|
||||||
add_header(&req, "Allow", ALLOWED_METHODS);
|
add_header(&req, "Allow", ALLOWED_METHODS);
|
||||||
|
ast_rtp_offered_from_local(p->rtp, 1);
|
||||||
add_sdp(&req, p);
|
add_sdp(&req, p);
|
||||||
/* Use this as the basis */
|
/* Use this as the basis */
|
||||||
copy_request(&p->initreq, &req);
|
copy_request(&p->initreq, &req);
|
||||||
@@ -3745,6 +3747,7 @@ static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, ch
|
|||||||
}
|
}
|
||||||
add_header(&req, "Allow", ALLOWED_METHODS);
|
add_header(&req, "Allow", ALLOWED_METHODS);
|
||||||
if (sdp) {
|
if (sdp) {
|
||||||
|
ast_rtp_offered_from_local(p->rtp, 1);
|
||||||
add_sdp(&req, p);
|
add_sdp(&req, p);
|
||||||
} else {
|
} else {
|
||||||
add_header(&req, "Content-Length", "0");
|
add_header(&req, "Content-Length", "0");
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ struct ast_frame_chain {
|
|||||||
#define AST_FRAME_CONTROL 4
|
#define AST_FRAME_CONTROL 4
|
||||||
/*! An empty, useless frame */
|
/*! An empty, useless frame */
|
||||||
#define AST_FRAME_NULL 5
|
#define AST_FRAME_NULL 5
|
||||||
/*! Inter Aterisk Exchange private frame type */
|
/*! Inter Asterisk Exchange private frame type */
|
||||||
#define AST_FRAME_IAX 6
|
#define AST_FRAME_IAX 6
|
||||||
/*! Text messages */
|
/*! Text messages */
|
||||||
#define AST_FRAME_TEXT 7
|
#define AST_FRAME_TEXT 7
|
||||||
@@ -126,6 +126,9 @@ struct ast_frame_chain {
|
|||||||
#define AST_FRAME_IMAGE 8
|
#define AST_FRAME_IMAGE 8
|
||||||
/*! HTML Frame */
|
/*! HTML Frame */
|
||||||
#define AST_FRAME_HTML 9
|
#define AST_FRAME_HTML 9
|
||||||
|
/*! Comfort Noise frame (subclass is level of CNG in -dBov),
|
||||||
|
body may include zero or more 8-bit quantization coefficients */
|
||||||
|
#define AST_FRAME_CNG 10
|
||||||
|
|
||||||
/* HTML subclasses */
|
/* HTML subclasses */
|
||||||
/*! Sending a URL */
|
/*! Sending a URL */
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
|
|||||||
// Mapping between RTP payload format codes and Asterisk codes:
|
// Mapping between RTP payload format codes and Asterisk codes:
|
||||||
struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
|
struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
|
||||||
int ast_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 ast_rtp_offered_from_local(struct ast_rtp* rtp, int local);
|
||||||
|
|
||||||
void ast_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);
|
||||||
|
|||||||
66
rtp.c
66
rtp.c
@@ -5,7 +5,7 @@
|
|||||||
* Supports RTP and RTCP with Symmetric RTP support for NAT
|
* Supports RTP and RTCP with Symmetric RTP support for NAT
|
||||||
* traversal
|
* traversal
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999, Mark Spencer
|
* Copyright (C) 1999-2004, Digium, Inc.
|
||||||
*
|
*
|
||||||
* Mark Spencer <markster@digium.com>
|
* Mark Spencer <markster@digium.com>
|
||||||
*
|
*
|
||||||
@@ -99,6 +99,7 @@ struct ast_rtp {
|
|||||||
int rtp_lookup_code_cache_isAstFormat; /* a cache for the result of rtp_lookup_code(): */
|
int rtp_lookup_code_cache_isAstFormat; /* a cache for the result of rtp_lookup_code(): */
|
||||||
int rtp_lookup_code_cache_code;
|
int rtp_lookup_code_cache_code;
|
||||||
int rtp_lookup_code_cache_result;
|
int rtp_lookup_code_cache_result;
|
||||||
|
int rtp_offered_from_local;
|
||||||
struct ast_rtcp *rtcp;
|
struct ast_rtcp *rtcp;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -281,43 +282,28 @@ static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *dat
|
|||||||
/* Convert comfort noise into audio with various codecs. Unfortunately this doesn't
|
/* Convert comfort noise into audio with various codecs. Unfortunately this doesn't
|
||||||
totally help us out becuase we don't have an engine to keep it going and we are not
|
totally help us out becuase we don't have an engine to keep it going and we are not
|
||||||
guaranteed to have it every 20ms or anything */
|
guaranteed to have it every 20ms or anything */
|
||||||
#if 0
|
#if 1
|
||||||
printf("RFC3389: %d bytes, format is %d\n", len, rtp->lastrxformat);
|
printf("RFC3389: %d bytes, level %d...\n", len, rtp->lastrxformat);
|
||||||
#endif
|
#endif
|
||||||
if (!(rtp->flags & FLAG_3389_WARNING)) {
|
if (!(rtp->flags & FLAG_3389_WARNING)) {
|
||||||
ast_log(LOG_NOTICE, "RFC3389 support incomplete. Turn off on client if possible\n");
|
ast_log(LOG_NOTICE, "RFC3389 support incomplete. Turn off on client if possible\n");
|
||||||
rtp->flags |= FLAG_3389_WARNING;
|
rtp->flags |= FLAG_3389_WARNING;
|
||||||
}
|
}
|
||||||
if (!rtp->lastrxformat)
|
/* Must have at least one byte */
|
||||||
return NULL;
|
if (!len)
|
||||||
switch(rtp->lastrxformat) {
|
return NULL;
|
||||||
case AST_FORMAT_ULAW:
|
if (len < 24) {
|
||||||
rtp->f.frametype = AST_FRAME_VOICE;
|
rtp->f.datalen = len - 1;
|
||||||
rtp->f.subclass = AST_FORMAT_ULAW;
|
memcpy(rtp->f.data, data + 1, len - 1);
|
||||||
rtp->f.datalen = 160;
|
} else {
|
||||||
rtp->f.samples = 160;
|
rtp->f.datalen = 0;
|
||||||
memset(rtp->f.data, 0x7f, rtp->f.datalen);
|
|
||||||
f = &rtp->f;
|
|
||||||
break;
|
|
||||||
case AST_FORMAT_ALAW:
|
|
||||||
rtp->f.frametype = AST_FRAME_VOICE;
|
|
||||||
rtp->f.subclass = AST_FORMAT_ALAW;
|
|
||||||
rtp->f.datalen = 160;
|
|
||||||
rtp->f.samples = 160;
|
|
||||||
memset(rtp->f.data, 0x7e, rtp->f.datalen); /* XXX Is this right? XXX */
|
|
||||||
f = &rtp->f;
|
|
||||||
break;
|
|
||||||
case AST_FORMAT_SLINEAR:
|
|
||||||
rtp->f.frametype = AST_FRAME_VOICE;
|
|
||||||
rtp->f.subclass = AST_FORMAT_SLINEAR;
|
|
||||||
rtp->f.datalen = 320;
|
|
||||||
rtp->f.samples = 160;
|
|
||||||
memset(rtp->f.data, 0x00, rtp->f.datalen);
|
|
||||||
f = &rtp->f;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ast_log(LOG_NOTICE, "Don't know how to handle RFC3389 for receive codec %d\n", rtp->lastrxformat);
|
|
||||||
}
|
}
|
||||||
|
rtp->f.frametype = AST_FRAME_CNG;
|
||||||
|
rtp->f.subclass = data[0] & 0x7f;
|
||||||
|
rtp->f.datalen = len - 1;
|
||||||
|
rtp->f.samples = 0;
|
||||||
|
rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
|
||||||
|
f = &rtp->f;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,7 +573,7 @@ static struct {
|
|||||||
{{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
|
{{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
|
||||||
{{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"},
|
||||||
{{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
|
{{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
|
||||||
{{0, AST_RTP_DTMF}, "audio", "telephone-event"},
|
{{0, AST_RTP_DTMF}, "audio", "telephone-event"},
|
||||||
{{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
|
{{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
|
||||||
@@ -698,19 +684,27 @@ void ast_rtp_get_current_formats(struct ast_rtp* rtp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local) {
|
||||||
|
if (rtp)
|
||||||
|
rtp->rtp_offered_from_local = local;
|
||||||
|
else
|
||||||
|
ast_log(LOG_WARNING, "rtp structure is null\n");
|
||||||
|
}
|
||||||
|
|
||||||
struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt)
|
struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt)
|
||||||
{
|
{
|
||||||
struct rtpPayloadType result;
|
struct rtpPayloadType result;
|
||||||
|
|
||||||
|
result.isAstFormat = result.code = 0;
|
||||||
if (pt < 0 || pt > MAX_RTP_PT) {
|
if (pt < 0 || pt > MAX_RTP_PT) {
|
||||||
result.isAstFormat = result.code = 0;
|
|
||||||
return result; /* bogus payload type */
|
return result; /* bogus payload type */
|
||||||
}
|
}
|
||||||
/* Start with the negotiated codecs */
|
/* Start with the negotiated codecs */
|
||||||
result = rtp->current_RTP_PT[pt];
|
if (!rtp->rtp_offered_from_local)
|
||||||
|
result = rtp->current_RTP_PT[pt];
|
||||||
/* If it doesn't exist, check our static RTP type list, just in case */
|
/* If it doesn't exist, check our static RTP type list, just in case */
|
||||||
if (!result.code)
|
if (!result.code)
|
||||||
result = static_RTP_PT[pt];
|
result = static_RTP_PT[pt];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user