[Asterisk-code-review] chan_pjsip, app_transfer: Add TRANSFERSTATUSPROTOCOL variable (asterisk[18])
Dan Cropp
asteriskteam at digium.com
Wed Jan 27 08:35:01 CST 2021
Dan Cropp has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/15377 )
Change subject: chan_pjsip, app_transfer: Add TRANSFERSTATUSPROTOCOL variable
......................................................................
chan_pjsip, app_transfer: Add TRANSFERSTATUSPROTOCOL variable
When a Transfer/REFER is executed, TRANSFERSTATUSPROTOCOL variable is
0 when no protocl specific error
SIP example of failure, 3xx-6xx for the SIP error code received
This allows applications to perform actions based on the failure
reason.
ASTERISK-29252 #close
Reported-by: Dan Cropp
Change-Id: Ia6a94784b4925628af122409cdd733c9f29abfc4
---
M apps/app_transfer.c
M channels/chan_pjsip.c
A doc/CHANGES-staging/app_transferprotocol.txt
M include/asterisk/channel.h
M main/channel.c
5 files changed, 86 insertions(+), 8 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/77/15377/1
diff --git a/apps/app_transfer.c b/apps/app_transfer.c
index 4fe3dca..d152340 100644
--- a/apps/app_transfer.c
+++ b/apps/app_transfer.c
@@ -69,6 +69,14 @@
Transfer unsupported by channel driver.
</value>
</variable>
+ <variable name="TRANSFERSTATUSPROTOCOL">
+ <value name="0">
+ No error.
+ </value>
+ <value name="3xx-6xx">
+ SIP example - Error result code.
+ </value>
+ </variable>
</variablelist>
</description>
</application>
@@ -85,6 +93,8 @@
char *dest = NULL;
char *status;
char *parse;
+ int protocol = 0;
+ char status_protocol[20];
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(dest);
);
@@ -92,6 +102,8 @@
if (ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "Transfer requires an argument ([Tech/]destination)\n");
pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
+ snprintf(status_protocol, sizeof(status_protocol), "%d", protocol);
+ pbx_builtin_setvar_helper(chan, "TRANSFERSTATUSPROTOCOL", status_protocol);
return 0;
} else
parse = ast_strdupa(data);
@@ -106,6 +118,8 @@
/* Allow execution only if the Tech/destination agrees with the type of the channel */
if (strncasecmp(ast_channel_tech(chan)->type, tech, len)) {
pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
+ snprintf(status_protocol, sizeof(status_protocol), "%d", protocol);
+ pbx_builtin_setvar_helper(chan, "TRANSFERSTATUSPROTOCOL", status_protocol);
return 0;
}
}
@@ -113,10 +127,14 @@
/* Check if the channel supports transfer before we try it */
if (!ast_channel_tech(chan)->transfer) {
pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "UNSUPPORTED");
+ snprintf(status_protocol, sizeof(status_protocol), "%d", protocol);
+ pbx_builtin_setvar_helper(chan, "TRANSFERSTATUSPROTOCOL", status_protocol);
return 0;
}
- res = ast_transfer(chan, dest);
+ /* New transfer API returns a protocol code
+ SIP example, 0 = success, 3xx-6xx are sip error codes for the REFER */
+ res = ast_transfer_protocol(chan, dest, &protocol);
if (res < 0) {
status = "FAILURE";
@@ -126,7 +144,11 @@
res = 0;
}
+ snprintf(status_protocol, sizeof(status_protocol), "%d", protocol);
+ ast_debug(1, "ast_transfer channel %s TRANSFERSTATUS=%s, TRANSFERSTATUSPROTOCOL=%s\n",
+ ast_channel_name(chan), status, status_protocol);
pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", status);
+ pbx_builtin_setvar_helper(chan, "TRANSFERSTATUSPROTOCOL", status_protocol);
return res;
}
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 483cd3e..5c19443 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -1982,12 +1982,17 @@
rdata = event->body.tsx_state.src.rdata;
msg = rdata->msg_info.msg;
- if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
- body = msg->body;
- if (body && !pj_stricmp2(&body->content_type.type, "message")
- && !pj_stricmp2(&body->content_type.subtype, "sipfrag")) {
- pjsip_parse_status_line((char *)body->data, body->len, &status_line);
+ if (msg->type == PJSIP_REQUEST_MSG) {
+ if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
+ body = msg->body;
+ if (body && !pj_stricmp2(&body->content_type.type, "message")
+ && !pj_stricmp2(&body->content_type.subtype, "sipfrag")) {
+ pjsip_parse_status_line((char *)body->data, body->len, &status_line);
+ }
}
+ } else {
+ status_line.code = msg->line.status.code;
+ status_line.reason = msg->line.status.reason;
}
} else {
status_line.code = 500;
@@ -2000,12 +2005,16 @@
res = -1;
/* If the subscription has terminated, return AST_TRANSFER_SUCCESS for 2XX.
- * Any other status code returns AST_TRANSFER_FAILED.
+ * Return AST_TRANSFER_FAILED for any code < 200.
+ * Otherwise, return the status code.
* The subscription should not terminate for any code < 200,
* but if it does, that constitutes a failure. */
- if (status_line.code < 200 || status_line.code >= 300) {
+ if (status_line.code < 200) {
message = AST_TRANSFER_FAILED;
+ } else if (status_line.code >= 300) {
+ message = status_line.code;
}
+
/* If subscription not terminated and subscription is finished (status code >= 200)
* terminate it */
if (!is_last) {
diff --git a/doc/CHANGES-staging/app_transferprotocol.txt b/doc/CHANGES-staging/app_transferprotocol.txt
new file mode 100644
index 0000000..5d3521b
--- /dev/null
+++ b/doc/CHANGES-staging/app_transferprotocol.txt
@@ -0,0 +1,6 @@
+Subject: chan_pjsip, app_transfer
+
+Added TRANSFERSTATUSPROTOCOL variable. When transfer is performed,
+transfers can pass a protocol specific error code.
+Example, in SIP 3xx-6xx represent any SIP specific error received when
+performing a REFER.
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index baefedd..40069b0 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -2641,6 +2641,18 @@
int ast_transfer(struct ast_channel *chan, char *dest);
/*!
+ * \brief Transfer a channel (if supported) receieve protocol result.
+ * \retval -1 on error
+ * \retval 0 if not supported
+ * \retval 1 if supported and requested
+ * \param chan current channel
+ * \param dest destination extension for transfer
+ * \param protocol specific error code in case of failure
+ * Example, sip 0 success, else sip error code
+ */
+int ast_transfer_protocol(struct ast_channel *chan, char *dest, int *protocol);
+
+/*!
* \brief Inherits channel variable from parent to child channel
* \param parent Parent channel
* \param child Child channel
diff --git a/main/channel.c b/main/channel.c
index d75c615..986b29a 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -6468,8 +6468,30 @@
*/
int ast_transfer(struct ast_channel *chan, char *dest)
{
+ int protocol;
+ return ast_transfer_protocol(chan, dest, &protocol);
+}
+
+/*!
+ \brief Transfer a call to dest, if the channel supports transfer
+
+ \param chan channel to transfer
+ \param dest destination to transfer to
+ \param protocol is the protocol result
+ SIP example, 0=success, 3xx-6xx is SIP error code
+
+ Called by:
+ \arg app_transfer
+ \arg the manager interface
+*/
+int ast_transfer_protocol(struct ast_channel *chan, char *dest, int *protocol)
+{
int res = -1;
+ if (protocol) {
+ *protocol = 0;
+ }
+
/* Stop if we're a zombie or need a soft hangup */
ast_channel_lock(chan);
if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
@@ -6503,6 +6525,13 @@
res = 1;
} else {
res = -1;
+ /* Message can contain a protocol specific code
+ AST_TRANSFER_SUCCESS indicates success
+ Else, failure. Protocol will be set to the failure reason.
+ SIP example, 0 is success, else error code 3xx-6xx */
+ if (protocol) {
+ *protocol = *message;
+ }
}
ast_frfree(fr);
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/15377
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 18
Gerrit-Change-Id: Ia6a94784b4925628af122409cdd733c9f29abfc4
Gerrit-Change-Number: 15377
Gerrit-PatchSet: 1
Gerrit-Owner: Dan Cropp <dan at amtelco.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210127/9f99647f/attachment.html>
More information about the asterisk-code-review
mailing list