[asterisk-commits] file: branch 12 r413117 - in /branches/12: channels/ res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Apr 30 07:31:26 CDT 2014
Author: file
Date: Wed Apr 30 07:31:07 2014
New Revision: 413117
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=413117
Log:
chan_pjsip: Add support for picking up calls in the configured pickup group.
AST-1363
Review: https://reviewboard.asterisk.org/r/3478/
Modified:
branches/12/channels/chan_pjsip.c
branches/12/res/res_pjsip_session.c
Modified: branches/12/channels/chan_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/channels/chan_pjsip.c?view=diff&rev=413117&r1=413116&r2=413117
==============================================================================
--- branches/12/channels/chan_pjsip.c (original)
+++ branches/12/channels/chan_pjsip.c Wed Apr 30 07:31:07 2014
@@ -58,6 +58,8 @@
#include "asterisk/stasis_channels.h"
#include "asterisk/indications.h"
#include "asterisk/threadstorage.h"
+#include "asterisk/features_config.h"
+#include "asterisk/pickup.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
@@ -1967,6 +1969,49 @@
return 0;
}
+static int call_pickup_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+ struct ast_features_pickup_config *pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
+ struct ast_channel *chan;
+
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
+ return 0;
+ }
+
+ if (strcmp(session->exten, pickup_cfg->pickupexten)) {
+ ao2_ref(pickup_cfg, -1);
+ return 0;
+ }
+ ao2_ref(pickup_cfg, -1);
+
+ /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
+ * changing the channel pointer in session to a different channel. To ensure we work on the right channel
+ * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
+ */
+ chan = ast_channel_ref(session->channel);
+ if (ast_pickup_call(chan)) {
+ ast_channel_hangupcause_set(chan, AST_CAUSE_CALL_REJECTED);
+ } else {
+ ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
+ }
+ /* A hangup always occurs because the pickup operation will have either failed resulting in the call
+ * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
+ * the channel that was replaced, which should be hung up since it is literally in limbo not connected
+ * to anything at all.
+ */
+ ast_hangup(chan);
+ ast_channel_unref(chan);
+
+ return 1;
+}
+
+static struct ast_sip_session_supplement call_pickup_supplement = {
+ .method = "INVITE",
+ .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST - 1,
+ .incoming_request = call_pickup_incoming_request,
+};
+
static int pbx_start_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
{
int res;
@@ -2106,9 +2151,16 @@
goto end;
}
+ if (ast_sip_session_register_supplement(&call_pickup_supplement)) {
+ ast_log(LOG_ERROR, "Unable to register PJSIP call pickup supplement\n");
+ ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
+ goto end;
+ }
+
if (ast_sip_session_register_supplement(&pbx_start_supplement)) {
ast_log(LOG_ERROR, "Unable to register PJSIP pbx start supplement\n");
ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
+ ast_sip_session_unregister_supplement(&call_pickup_supplement);
goto end;
}
@@ -2116,6 +2168,7 @@
ast_log(LOG_ERROR, "Unable to register PJSIP ACK supplement\n");
ast_sip_session_unregister_supplement(&pbx_start_supplement);
ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
+ ast_sip_session_unregister_supplement(&call_pickup_supplement);
goto end;
}
@@ -2154,6 +2207,7 @@
ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
ast_sip_session_unregister_supplement(&pbx_start_supplement);
ast_sip_session_unregister_supplement(&chan_pjsip_ack_supplement);
+ ast_sip_session_unregister_supplement(&call_pickup_supplement);
ast_custom_function_unregister(&media_offer_function);
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
Modified: branches/12/res/res_pjsip_session.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip_session.c?view=diff&rev=413117&r1=413116&r2=413117
==============================================================================
--- branches/12/res/res_pjsip_session.c (original)
+++ branches/12/res/res_pjsip_session.c Wed Apr 30 07:31:07 2014
@@ -43,6 +43,8 @@
#include "asterisk/sdp_srtp.h"
#include "asterisk/dsp.h"
#include "asterisk/acl.h"
+#include "asterisk/features_config.h"
+#include "asterisk/pickup.h"
#define SDP_HANDLER_BUCKETS 11
@@ -1349,12 +1351,27 @@
{
pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
pjsip_sip_uri *sip_ruri;
+ struct ast_features_pickup_config *pickup_cfg;
+ const char *pickupexten;
+
if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
return SIP_GET_DEST_UNSUPPORTED_URI;
}
+
sip_ruri = pjsip_uri_get_uri(ruri);
ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten));
- if (ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) {
+
+ pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ pickupexten = ast_strdupa(pickup_cfg->pickupexten);
+ ao2_ref(pickup_cfg, -1);
+ }
+
+ if (!strcmp(session->exten, pickupexten) ||
+ ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) {
return SIP_GET_DEST_EXTEN_FOUND;
}
/* XXX In reality, we'll likely have further options so that partial matches
More information about the asterisk-commits
mailing list