mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 00:04:53 +00:00
Merged revisions 307879 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r307879 | rmudgett | 2011-02-15 10:13:55 -0600 (Tue, 15 Feb 2011) | 37 lines No response sent for SIP CC subscribe/resubscribe request. Asterisk does not send a response if we try to subscribe for call completion after we have received a 180 Ringing. You can only subscribe for call completion when the call has been cleared. When we receive the 180 Ringing, for this call, its call-completion state is 'CC_AVAILABLE'. If we then send a subscribe message to Asterisk, it trys to change the call-completion state to 'CC_CALLER_REQUESTED'. Because this is an invalid state change, it just ignores the message. The only state Asterisk will accept our subscribe message is in the 'CC_CALLER_OFFERED' state. Asterisk will go into the 'CC_CALLER_OFFERED' when the SIP client clears the call by sending a CANCEL. Asterisk should always send a response. Even if its a negative one. The fix is to allow for the CCSS core to notify a CC agent that a failure has occurred when CC is requested. The "ack" callback is replaced with a "respond" callback. The "respond" callback has a parameter indicating either a successful response or a specific type of failure that may need to be communicated to the requester. (closes issue #18336) Reported by: GeorgeKonopacki Tested by: mmichelson, rmudgett JIRA SWP-2633 (closes issue #18337) Reported by: GeorgeKonopacki Tested by: mmichelson JIRA SWP-2634 ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@307883 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1614,7 +1614,7 @@ struct ast_channel_tech sip_tech_info;
|
||||
static int sip_cc_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan);
|
||||
static int sip_cc_agent_start_offer_timer(struct ast_cc_agent *agent);
|
||||
static int sip_cc_agent_stop_offer_timer(struct ast_cc_agent *agent);
|
||||
static void sip_cc_agent_ack(struct ast_cc_agent *agent);
|
||||
static void sip_cc_agent_respond(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason);
|
||||
static int sip_cc_agent_status_request(struct ast_cc_agent *agent);
|
||||
static int sip_cc_agent_start_monitoring(struct ast_cc_agent *agent);
|
||||
static int sip_cc_agent_recall(struct ast_cc_agent *agent);
|
||||
@@ -1625,7 +1625,7 @@ static struct ast_cc_agent_callbacks sip_cc_agent_callbacks = {
|
||||
.init = sip_cc_agent_init,
|
||||
.start_offer_timer = sip_cc_agent_start_offer_timer,
|
||||
.stop_offer_timer = sip_cc_agent_stop_offer_timer,
|
||||
.ack = sip_cc_agent_ack,
|
||||
.respond = sip_cc_agent_respond,
|
||||
.status_request = sip_cc_agent_status_request,
|
||||
.start_monitoring = sip_cc_agent_start_monitoring,
|
||||
.callee_available = sip_cc_agent_recall,
|
||||
@@ -1726,14 +1726,30 @@ static int sip_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sip_cc_agent_ack(struct ast_cc_agent *agent)
|
||||
static void sip_cc_agent_respond(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
|
||||
{
|
||||
struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
|
||||
|
||||
sip_pvt_lock(agent_pvt->subscribe_pvt);
|
||||
ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
|
||||
transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq);
|
||||
transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED);
|
||||
if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) {
|
||||
/* The second half of this if statement may be a bit hard to grasp,
|
||||
* so here's an explanation. When a subscription comes into
|
||||
* chan_sip, as long as it is not malformed, it will be passed
|
||||
* to the CC core. If the core senses an out-of-order state transition,
|
||||
* then the core will call this callback with the "reason" set to a
|
||||
* failure condition.
|
||||
* However, an out-of-order state transition will occur during a resubscription
|
||||
* for CC. In such a case, we can see that we have already generated a notify_uri
|
||||
* and so we can detect that this isn't a *real* failure. Rather, it is just
|
||||
* something the core doesn't recognize as a legitimate SIP state transition.
|
||||
* Thus we respond with happiness and flowers.
|
||||
*/
|
||||
transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq);
|
||||
transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED);
|
||||
} else {
|
||||
transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq);
|
||||
}
|
||||
sip_pvt_unlock(agent_pvt->subscribe_pvt);
|
||||
agent_pvt->is_available = TRUE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user