SIP hold improvements (bug #4290)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5702 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming 2005-05-16 16:16:41 +00:00
parent 507ceb1a29
commit 252bf2d652
1 changed files with 38 additions and 12 deletions

View File

@ -2136,7 +2136,7 @@ static int sip_answer(struct ast_channel *ast)
return res;
}
/*--- sip_write: Send response, support audio media ---*/
/*--- sip_write: Send frame to media channel (rtp) ---*/
static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
{
struct sip_pvt *p = ast->tech_pvt;
@ -2151,6 +2151,7 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
if (p) {
ast_mutex_lock(&p->lock);
if (p->rtp) {
/* If channel is not up, activate early media session */
if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
ast_set_flag(p, SIP_PROGRESS_SENT);
@ -2165,6 +2166,7 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
if (p) {
ast_mutex_lock(&p->lock);
if (p->vrtp) {
/* Activate video early media */
if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) {
transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0);
ast_set_flag(p, SIP_PROGRESS_SENT);
@ -2562,7 +2564,7 @@ static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p
default:
f = &null_frame;
}
/* Don't send RFC2833 if we're not supposed to */
/* Don't forward RFC2833 if we're not supposed to */
if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833))
return &null_frame;
if (p->owner) {
@ -2953,7 +2955,7 @@ static void parse(struct sip_request *req)
ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
}
/*--- process_sdp: Process SIP SDP ---*/
/*--- process_sdp: Process SIP SDP and activate RTP channels---*/
static int process_sdp(struct sip_pvt *p, struct sip_request *req)
{
char *m;
@ -3161,7 +3163,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
ast_log(LOG_NOTICE, "No compatible codecs!\n");
return -1;
}
if (p->owner) {
if (p->owner) { /* There's an open channel owning us */
struct ast_channel *bridgepeer = NULL;
if (!(p->owner->nativeformats & p->jointcapability)) {
const unsigned slen=512;
char s1[slen], s2[slen];
@ -3172,28 +3175,49 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
ast_set_read_format(p->owner, p->owner->readformat);
ast_set_write_format(p->owner, p->owner->writeformat);
}
if (ast_bridged_channel(p->owner)) {
if ((bridgepeer=ast_bridged_channel(p->owner))) {
/* We have a bridge */
/* Turn on/off music on hold if we are holding/unholding */
if (sin.sin_addr.s_addr && !sendonly) {
ast_moh_stop(ast_bridged_channel(p->owner));
ast_moh_stop(bridgepeer);
/* Indicate UNHOLD status to the other channel */
ast_indicate(bridgepeer, AST_CONTROL_UNHOLD);
append_history(p, "Unhold", req->data);
if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) {
manager_event(EVENT_FLAG_CALL, "Unhold",
"Channel: %s\r\n"
"Uniqueid: %s\r\n",
p->owner->name,
p->owner->uniqueid);
ast_clear_flag(p, SIP_CALL_ONHOLD);
}
ast_clear_flag(p, SIP_CALL_ONHOLD);
/* Somehow, we need to check if we need to re-invite here */
/* If this call had a native bridge, it's broken
now and we need to start all over again.
The bridged peer, if SIP, now listens
to RTP from Asterisk instead of from
the peer
So IF we had a native bridge before
the HOLD, we need to somehow re-invite
into a NATIVE bridge afterwards...
*/
} else {
/* No address for RTP, we're on hold */
append_history(p, "Hold", req->data);
if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) {
manager_event(EVENT_FLAG_CALL, "Hold",
"Channel: %s\r\n"
"Uniqueid: %s\r\n",
p->owner->name,
p->owner->uniqueid);
ast_set_flag(p, SIP_CALL_ONHOLD);
}
ast_moh_start(ast_bridged_channel(p->owner), NULL);
ast_set_flag(p, SIP_CALL_ONHOLD);
/* Indicate HOLD status to the other channel */
ast_indicate(bridgepeer, AST_CONTROL_HOLD);
ast_moh_start(bridgepeer, NULL);
if (sendonly)
ast_rtp_stop(p->rtp);
}
@ -10734,7 +10758,7 @@ static int reload_config(void)
return 0;
}
/*--- sip_get_rtp_peer: Returns null if we can't reinvite */
/*--- sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface) */
static struct ast_rtp *sip_get_rtp_peer(struct ast_channel *chan)
{
struct sip_pvt *p;
@ -10749,6 +10773,7 @@ static struct ast_rtp *sip_get_rtp_peer(struct ast_channel *chan)
return rtp;
}
/*--- sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface) */
static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan)
{
struct sip_pvt *p;
@ -10764,7 +10789,8 @@ static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan)
return rtp;
}
/*--- sip_set_rtp_peer: Set the RTP peer for this call ---*/
/*--- sip_set_rtp_peer: Set the data needed to RE-INVITE this call
so that the peers media go between them, outside of Asterisk. ---*/
static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs)
{
struct sip_pvt *p;
@ -11042,7 +11068,7 @@ static int sip_sipredirect(struct sip_pvt *p, const char *dest)
return -1;
}
/*--- sip_get_codec: Return peers codec ---*/
/*--- sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---*/
static int sip_get_codec(struct ast_channel *chan)
{
struct sip_pvt *p = chan->tech_pvt;