Repair offer/answer model (bug #2293), initial CNG work for new frametype
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@3658 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
78778424f8
commit
3fc6b9c9a5
|
@ -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, "I", sub->cxident);
|
||||
/*add_header(&resp, "S", "");*/
|
||||
ast_rtp_offered_from_local(rtp, 0);
|
||||
add_sdp(&resp, sub, rtp);
|
||||
/* SC: fill in new fields */
|
||||
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 */
|
||||
add_header(&resp, "X", sub->txident);
|
||||
/*add_header(&resp, "S", "");*/
|
||||
ast_rtp_offered_from_local(rtp, 1);
|
||||
add_sdp(&resp, sub, rtp);
|
||||
/* SC: fill in new fields */
|
||||
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;
|
||||
}
|
||||
respprep(&resp, p, msg, req);
|
||||
ast_rtp_offered_from_local(p->rtp, 0);
|
||||
add_sdp(&resp, p);
|
||||
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);
|
||||
|
||||
add_header(&req, "Allow", ALLOWED_METHODS);
|
||||
ast_rtp_offered_from_local(p->rtp, 1);
|
||||
add_sdp(&req, p);
|
||||
/* Use this as the basis */
|
||||
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);
|
||||
if (sdp) {
|
||||
ast_rtp_offered_from_local(p->rtp, 1);
|
||||
add_sdp(&req, p);
|
||||
} else {
|
||||
add_header(&req, "Content-Length", "0");
|
||||
|
|
|
@ -118,7 +118,7 @@ struct ast_frame_chain {
|
|||
#define AST_FRAME_CONTROL 4
|
||||
/*! An empty, useless frame */
|
||||
#define AST_FRAME_NULL 5
|
||||
/*! Inter Aterisk Exchange private frame type */
|
||||
/*! Inter Asterisk Exchange private frame type */
|
||||
#define AST_FRAME_IAX 6
|
||||
/*! Text messages */
|
||||
#define AST_FRAME_TEXT 7
|
||||
|
@ -126,6 +126,9 @@ struct ast_frame_chain {
|
|||
#define AST_FRAME_IMAGE 8
|
||||
/*! HTML Frame */
|
||||
#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 */
|
||||
/*! 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:
|
||||
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);
|
||||
void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local);
|
||||
|
||||
void ast_rtp_get_current_formats(struct ast_rtp* rtp,
|
||||
int* astFormats, int* nonAstFormats);
|
||||
|
|
66
rtp.c
66
rtp.c
|
@ -5,7 +5,7 @@
|
|||
* Supports RTP and RTCP with Symmetric RTP support for NAT
|
||||
* traversal
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
* Copyright (C) 1999-2004, Digium, Inc.
|
||||
*
|
||||
* 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_code;
|
||||
int rtp_lookup_code_cache_result;
|
||||
int rtp_offered_from_local;
|
||||
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
|
||||
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 */
|
||||
#if 0
|
||||
printf("RFC3389: %d bytes, format is %d\n", len, rtp->lastrxformat);
|
||||
#if 1
|
||||
printf("RFC3389: %d bytes, level %d...\n", len, rtp->lastrxformat);
|
||||
#endif
|
||||
if (!(rtp->flags & FLAG_3389_WARNING)) {
|
||||
ast_log(LOG_NOTICE, "RFC3389 support incomplete. Turn off on client if possible\n");
|
||||
rtp->flags |= FLAG_3389_WARNING;
|
||||
}
|
||||
if (!rtp->lastrxformat)
|
||||
return NULL;
|
||||
switch(rtp->lastrxformat) {
|
||||
case AST_FORMAT_ULAW:
|
||||
rtp->f.frametype = AST_FRAME_VOICE;
|
||||
rtp->f.subclass = AST_FORMAT_ULAW;
|
||||
rtp->f.datalen = 160;
|
||||
rtp->f.samples = 160;
|
||||
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);
|
||||
/* Must have at least one byte */
|
||||
if (!len)
|
||||
return NULL;
|
||||
if (len < 24) {
|
||||
rtp->f.datalen = len - 1;
|
||||
memcpy(rtp->f.data, data + 1, len - 1);
|
||||
} else {
|
||||
rtp->f.datalen = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -587,7 +573,7 @@ static struct {
|
|||
{{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
|
||||
{{1, AST_FORMAT_LPC10}, "audio", "LPC"},
|
||||
{{1, AST_FORMAT_G729A}, "audio", "G729"},
|
||||
{{1, AST_FORMAT_SPEEX}, "audio", "SPEEX"},
|
||||
{{1, AST_FORMAT_SPEEX}, "audio", "speex"},
|
||||
{{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
|
||||
{{0, AST_RTP_DTMF}, "audio", "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 result;
|
||||
|
||||
result.isAstFormat = result.code = 0;
|
||||
if (pt < 0 || pt > MAX_RTP_PT) {
|
||||
result.isAstFormat = result.code = 0;
|
||||
return result; /* bogus payload type */
|
||||
}
|
||||
/* 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 (!result.code)
|
||||
result = static_RTP_PT[pt];
|
||||
result = static_RTP_PT[pt];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue