mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
ari/pjsip: Make it possible to control transfers through ARI
Introduce a ChannelTransfer event and the ability to notify progress to
ARI. Implement emitting this event from the PJSIP channel instead of
handling the transfer in Asterisk when configured.
Introduce a dialplan function to the PJSIP channel to switch between the
"core" and "ari-only" behavior.
UserNote: Call transfers on the PJSIP channel can now be controlled by
ARI. This can be enabled by using the PJSIP_TRANSFER_HANDLING(ari-only)
dialplan function.
(cherry picked from commit a0d0c47d06
)
This commit is contained in:
committed by
Asterisk Development Team
parent
ba1626df89
commit
fe5ff3021e
@@ -1851,6 +1851,8 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
|
||||
break;
|
||||
case AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED:
|
||||
break;
|
||||
case AST_CONTROL_TRANSFER:
|
||||
break;
|
||||
case -1:
|
||||
res = -1;
|
||||
break;
|
||||
@@ -3274,6 +3276,11 @@ static struct ast_custom_function session_refresh_function = {
|
||||
.write = pjsip_acf_session_refresh_write,
|
||||
};
|
||||
|
||||
static struct ast_custom_function transfer_handling_function = {
|
||||
.name = "PJSIP_TRANSFER_HANDLING",
|
||||
.write = pjsip_transfer_handling_write,
|
||||
};
|
||||
|
||||
static char *app_pjsip_hangup = "PJSIPHangup";
|
||||
|
||||
/*!
|
||||
@@ -3338,6 +3345,11 @@ static int load_module(void)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ast_custom_function_register(&transfer_handling_function)) {
|
||||
ast_log(LOG_WARNING, "Unable to register PJSIP_TRANSFER_HANDLING dialplan function\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ast_register_application_xml(app_pjsip_hangup, pjsip_app_hangup)) {
|
||||
ast_log(LOG_WARNING, "Unable to register PJSIPHangup dialplan application\n");
|
||||
goto end;
|
||||
@@ -3393,6 +3405,7 @@ end:
|
||||
ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
|
||||
ast_custom_function_unregister(&chan_pjsip_parse_uri_from_function);
|
||||
ast_custom_function_unregister(&session_refresh_function);
|
||||
ast_custom_function_unregister(&transfer_handling_function);
|
||||
ast_unregister_application(app_pjsip_hangup);
|
||||
ast_manager_unregister(app_pjsip_hangup);
|
||||
|
||||
@@ -3426,6 +3439,7 @@ static int unload_module(void)
|
||||
ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
|
||||
ast_custom_function_unregister(&chan_pjsip_parse_uri_from_function);
|
||||
ast_custom_function_unregister(&session_refresh_function);
|
||||
ast_custom_function_unregister(&transfer_handling_function);
|
||||
ast_unregister_application(app_pjsip_hangup);
|
||||
ast_manager_unregister(app_pjsip_hangup);
|
||||
|
||||
|
@@ -1368,3 +1368,36 @@ int pjsip_action_hangup(struct mansession *s, const struct message *m)
|
||||
return ast_manager_hangup_helper(s, m,
|
||||
pjsip_app_hangup_handler, response_code_validator);
|
||||
}
|
||||
|
||||
int pjsip_transfer_handling_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
|
||||
{
|
||||
struct ast_sip_channel_pvt *channel;
|
||||
int ret = 0;
|
||||
|
||||
if (!chan) {
|
||||
ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_channel_lock(chan);
|
||||
if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
|
||||
ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel %s\n", cmd, ast_channel_name(chan));
|
||||
ast_channel_unlock(chan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
channel = ast_channel_tech_pvt(chan);
|
||||
|
||||
if (ast_strlen_zero(value) || !strcmp(value, "core")) {
|
||||
channel->session->transferhandling_ari = 0;
|
||||
} else if (!strcmp(value, "ari-only")) {
|
||||
channel->session->transferhandling_ari = 1;
|
||||
} else {
|
||||
ast_log(AST_LOG_WARNING, "Cannot set unknown transfer handling '%s' on channel '%s', transfer handling will remain unchanged.",
|
||||
value, ast_channel_name(chan));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
ast_channel_unlock(chan);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -405,6 +405,32 @@
|
||||
<para>Parse the contents of the provided variable as a URI and return a specified part of the URI.</para>
|
||||
</description>
|
||||
</function>
|
||||
<function name="PJSIP_TRANSFER_HANDLING" language="en_US">
|
||||
<since>
|
||||
<version>22.3.0</version>
|
||||
<version>21.8.0</version>
|
||||
<version>20.13.0</version>
|
||||
</since>
|
||||
<synopsis>
|
||||
Set how transfers are handled for a PJSIP channel.
|
||||
</synopsis>
|
||||
<syntax>
|
||||
<parameter name="mode" required="false">
|
||||
<para>How transfers are handled for a PJSIP channel. Default is <literal>core</literal>.</para>
|
||||
<enumlist>
|
||||
<enum name="core">
|
||||
<para>Asterisk will handle attended and blind transfers.</para>
|
||||
</enum>
|
||||
<enum name="ari-only">
|
||||
<para>Asterisk will generate ARI events on incoming SIP REFER.</para>
|
||||
</enum>
|
||||
</enumlist>
|
||||
</parameter>
|
||||
</syntax>
|
||||
<description>
|
||||
<para>When written, sets the transferhandling behavior</para>
|
||||
</description>
|
||||
</function>
|
||||
|
||||
<info name="CHANNEL" language="en_US" tech="PJSIP">
|
||||
<enumlist>
|
||||
|
@@ -168,4 +168,16 @@ int pjsip_app_hangup(struct ast_channel *chan, const char *data);
|
||||
*/
|
||||
int pjsip_action_hangup(struct mansession *s, const struct message *m);
|
||||
|
||||
/*!
|
||||
* \brief PJSIP_TRANSFER_HANDLING function write callback
|
||||
* \param chan The channel the function is called on
|
||||
* \param cmd the Name of the function
|
||||
* \param data Arguments passed to the function
|
||||
* \param value Value to be set by the function
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int pjsip_transfer_handling_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
|
||||
|
||||
#endif /* _PJSIP_DIALPLAN_FUNCTIONS */
|
||||
|
Reference in New Issue
Block a user