[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