[asterisk-commits] file: branch file/gulp_transfer r387928 - /team/file/gulp_transfer/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed May 8 07:41:59 CDT 2013
Author: file
Date: Wed May 8 07:41:57 2013
New Revision: 387928
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387928
Log:
Get attended transfers via REFER w/ replaces working as expected, and add some experimental code for handling INVITE w/ Replaces.
Modified:
team/file/gulp_transfer/res/res_sip_refer.c
Modified: team/file/gulp_transfer/res/res_sip_refer.c
URL: http://svnview.digium.com/svn/asterisk/team/file/gulp_transfer/res/res_sip_refer.c?view=diff&rev=387928&r1=387927&r2=387928
==============================================================================
--- team/file/gulp_transfer/res/res_sip_refer.c (original)
+++ team/file/gulp_transfer/res/res_sip_refer.c Wed May 8 07:41:57 2013
@@ -353,6 +353,7 @@
response = 500;
break;
case AST_BRIDGE_TRANSFER_SUCCESS:
+ response = 200;
attended->transferer->defer_terminate = 1;
break;
}
@@ -555,7 +556,80 @@
return 503;
}
-static int refer_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+/*! \brief Structure used to retrieve channel from another session */
+struct invite_replaces {
+ /*! \brief Session we want the channel from */
+ struct ast_sip_session *session;
+ /*! \brief Channel from the session (with reference) */
+ struct ast_channel *channel;
+};
+
+/*! \brief Task for invite replaces */
+static int invite_replaces(void *data)
+{
+ struct invite_replaces *invite = data;
+
+ if (!invite->session->channel) {
+ return -1;
+ }
+
+ ast_channel_ref(invite->session->channel);
+ invite->channel = invite->session->channel;
+
+ return 0;
+}
+
+static int refer_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+ pjsip_dialog *other_dlg = NULL;
+ pjsip_tx_data *packet;
+ int response = 0;
+ RAII_VAR(struct ast_sip_session *, other_session, NULL, ao2_cleanup);
+ struct invite_replaces invite;
+ RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
+
+ /* If a Replaces header is present make sure it is valid */
+ if (pjsip_replaces_verify_request(rdata, &other_dlg, PJ_TRUE, &packet) != PJ_SUCCESS) {
+ response = packet->msg->line.status.code;
+ pjsip_tx_data_dec_ref(packet);
+ goto end;
+ }
+
+ /* If no other dialog exists then this INVITE request does not have a Replaces header */
+ if (!other_dlg) {
+ return 0;
+ }
+
+ other_session = ast_sip_dialog_get_session(other_dlg);
+ pjsip_dlg_dec_lock(other_dlg);
+
+ if (!other_session) {
+ response = 481;
+ goto end;
+ }
+
+ invite.session = other_session;
+
+ if (ast_sip_push_task_synchronous(other_session->serializer, invite_replaces, &invite)) {
+ response = 481;
+ goto end;
+ }
+
+end:
+ if (response) {
+ session->defer_terminate = 1;
+ ast_hangup(session->channel);
+ session->channel = NULL;
+
+ if (pjsip_inv_end_session(session->inv_session, response, NULL, &packet) == PJ_SUCCESS) {
+ ast_sip_session_send_response(session, packet);
+ }
+ }
+
+ return 1;
+}
+
+static int refer_incoming_refer_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
{
const pj_str_t str_refer_to = { "Refer-To", 8 };
pjsip_generic_string_hdr *refer_to;
@@ -568,10 +642,6 @@
pjsip_param *replaces;
int response;
- if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_refer_method())) {
- return 0;
- }
-
/* A Refer-To header is required */
if (!(refer_to = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL))) {
pjsip_dlg_respond(session->inv_session->dlg, rdata, 400, NULL, NULL, NULL);
@@ -634,6 +704,17 @@
return 0;
}
+static int refer_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+ if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_refer_method())) {
+ return refer_incoming_refer_request(session, rdata);
+ } else if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_invite_method)) {
+ return refer_incoming_invite_request(session, rdata);
+ } else {
+ return 0;
+ }
+}
+
static void refer_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
{
const char *replaces;
@@ -649,6 +730,7 @@
}
static struct ast_sip_session_supplement refer_supplement = {
+ .priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL + 1,
.incoming_request = refer_incoming_request,
.outgoing_request = refer_outgoing_request,
};
More information about the asterisk-commits
mailing list