summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--apps/app_macro.c36
-rw-r--r--include/asterisk/channel.h6
-rw-r--r--include/asterisk/res_fax.h22
-rw-r--r--main/bridge_basic.c2
-rw-r--r--main/channel.c2
-rw-r--r--res/res_fax.c109
-rw-r--r--res/res_pjsip/config_global.c26
-rw-r--r--res/res_pjsip_refer.c7
-rw-r--r--res/res_pjsip_t38.c14
10 files changed, 172 insertions, 58 deletions
diff --git a/CHANGES b/CHANGES
index 1dfd445c8..27643f28f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -43,6 +43,12 @@ res_pjsip
when set will override the default user set on Contact headers in outgoing
requests.
+ * If you are using a sorcery realtime backend to store global res_pjsip
+ options (ps_globals table) then you now have to do a res_pjsip reload for
+ changes to these options to take effect. If you are using pjsip.conf to
+ configure these options then you already had to do a reload after making
+ changes.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.10.0 to Asterisk 13.11.0 ----------
------------------------------------------------------------------------------
diff --git a/apps/app_macro.c b/apps/app_macro.c
index d8fd47fb1..ab80fbc38 100644
--- a/apps/app_macro.c
+++ b/apps/app_macro.c
@@ -243,7 +243,7 @@ static int _macro_exec(struct ast_channel *chan, const char *data, int exclusive
int setmacrocontext=0;
int autoloopflag, inhangup = 0;
struct ast_str *tmp_subst = NULL;
-
+ const char *my_macro_exten = NULL;
char *save_macro_exten;
char *save_macro_context;
char *save_macro_priority;
@@ -304,12 +304,32 @@ static int _macro_exec(struct ast_channel *chan, const char *data, int exclusive
}
snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
- if (!ast_exists_extension(chan, fullmacro, "s", 1,
- S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
- if (!ast_context_find(fullmacro))
- ast_log(LOG_WARNING, "No such context '%s' for macro '%s'. Was called by %s@%s\n", fullmacro, macro, ast_channel_exten(chan), ast_channel_context(chan));
- else
- ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro);
+
+ /* first search for the macro */
+ if (!ast_context_find(fullmacro)) {
+ ast_log(LOG_WARNING, "No such context '%s' for macro '%s'. Was called by %s@%s\n",
+ fullmacro, macro, ast_channel_exten(chan), ast_channel_context(chan));
+ return 0;
+ }
+
+ /* now search for the right extension */
+ if (ast_exists_extension(chan, fullmacro, "s", 1,
+ S_COR(ast_channel_caller(chan)->id.number.valid,
+ ast_channel_caller(chan)->id.number.str, NULL))) {
+ /* We have a normal macro */
+ my_macro_exten = "s";
+ } else if (ast_exists_extension(chan, fullmacro, "~~s~~", 1,
+ S_COR(ast_channel_caller(chan)->id.number.valid,
+ ast_channel_caller(chan)->id.number.str, NULL))) {
+ /* We have an AEL generated macro */
+ my_macro_exten = "~~s~~";
+ }
+
+ /* do we have a valid exten? */
+ if (!my_macro_exten) {
+ ast_log(LOG_WARNING,
+ "Context '%s' for macro '%s' lacks 's' extension, priority 1\n",
+ fullmacro, macro);
return 0;
}
@@ -361,7 +381,7 @@ static int _macro_exec(struct ast_channel *chan, const char *data, int exclusive
ast_set_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
/* Setup environment for new run */
- ast_channel_exten_set(chan, "s");
+ ast_channel_exten_set(chan, my_macro_exten);
ast_channel_context_set(chan, fullmacro);
ast_channel_priority_set(chan, 1);
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 4cc210d5a..e42307dd9 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -2569,7 +2569,11 @@ static inline int ast_fdisset(struct pollfd *pfds, int fd, int maximum, int *sta
return 0;
}
-/*! \brief Retrieves the current T38 state of a channel */
+/*!
+ * \brief Retrieves the current T38 state of a channel
+ *
+ * \note Absolutely _NO_ channel locks should be held before calling this function.
+ */
static inline enum ast_t38_state ast_channel_get_t38_state(struct ast_channel *chan)
{
enum ast_t38_state state = T38_STATE_UNAVAILABLE;
diff --git a/include/asterisk/res_fax.h b/include/asterisk/res_fax.h
index 5119bfa6c..e88d8002f 100644
--- a/include/asterisk/res_fax.h
+++ b/include/asterisk/res_fax.h
@@ -20,16 +20,16 @@
#ifndef _ASTERISK_RES_FAX_H
#define _ASTERISK_RES_FAX_H
-#include <asterisk.h>
-#include <asterisk/lock.h>
-#include <asterisk/linkedlists.h>
-#include <asterisk/module.h>
-#include <asterisk/utils.h>
-#include <asterisk/options.h>
-#include <asterisk/frame.h>
-#include <asterisk/cli.h>
-#include <asterisk/stringfields.h>
-#include <asterisk/manager.h>
+#include "asterisk.h"
+#include "asterisk/lock.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/module.h"
+#include "asterisk/utils.h"
+#include "asterisk/options.h"
+#include "asterisk/frame.h"
+#include "asterisk/cli.h"
+#include "asterisk/stringfields.h"
+#include "asterisk/manager.h"
/*! \brief capabilities for res_fax to locate a fax technology module */
enum ast_fax_capabilities {
@@ -187,6 +187,8 @@ struct ast_fax_session_details {
int faxdetect_timeout;
/*! flags used for fax detection */
int faxdetect_flags;
+ /*! Non-zero if T.38 is negotiated */
+ int is_t38_negotiated;
};
struct ast_fax_tech;
diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index c4cf2a074..b24df0506 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -3090,7 +3090,9 @@ static int attach_framehook(struct attended_transfer_properties *props, struct a
ao2_ref(props, +1);
target_interface.data = props;
+ ast_channel_lock(channel);
props->target_framehook_id = ast_framehook_attach(channel, &target_interface);
+ ast_channel_unlock(channel);
if (props->target_framehook_id == -1) {
ao2_ref(props, -1);
return -1;
diff --git a/main/channel.c b/main/channel.c
index 853935da3..f3f79399f 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -6094,7 +6094,7 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
if (set_security_requirements(requestor, c)) {
ast_log(LOG_WARNING, "Setting security requirements failed\n");
- c = ast_channel_release(c);
+ ast_hangup(c);
*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
return NULL;
}
diff --git a/res/res_fax.c b/res/res_fax.c
index 86260d10e..e37091b31 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -641,6 +641,7 @@ static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_
struct ast_fax_session_details *new_details = find_or_create_details(new_chan);
ast_framehook_detach(old_chan, old_details->gateway_id);
+ new_details->is_t38_negotiated = old_details->is_t38_negotiated;
fax_gateway_attach(new_chan, new_details);
ao2_cleanup(new_details);
}
@@ -1439,6 +1440,7 @@ static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_de
static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
{
char buf[10];
+
pbx_builtin_setvar_helper(chan, "FAXSTATUS", S_OR(details->result, NULL));
pbx_builtin_setvar_helper(chan, "FAXERROR", S_OR(details->error, NULL));
pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", S_OR(details->resultstr, NULL));
@@ -1447,7 +1449,7 @@ static void set_channel_variables(struct ast_channel *chan, struct ast_fax_sessi
pbx_builtin_setvar_helper(chan, "FAXBITRATE", S_OR(details->transfer_rate, NULL));
pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", S_OR(details->resolution, NULL));
- if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
+ if (details->is_t38_negotiated) {
pbx_builtin_setvar_helper(chan, "FAXMODE", "T38");
} else {
pbx_builtin_setvar_helper(chan, "FAXMODE", "audio");
@@ -1656,6 +1658,7 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
ast_string_field_set(details, result, "");
ast_string_field_set(details, resultstr, "");
ast_string_field_set(details, error, "");
+ details->is_t38_negotiated = t38negotiated;
set_channel_variables(chan, details);
if (fax->tech->start_session(fax) < 0) {
@@ -1706,12 +1709,18 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
* do T.38 as well
*/
t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
- t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
+ if (details->caps & AST_FAX_TECH_T38) {
+ details->is_t38_negotiated = 1;
+ t38_parameters.request_response = AST_T38_NEGOTIATED;
+ } else {
+ t38_parameters.request_response = AST_T38_REFUSED;
+ }
ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
break;
case AST_T38_NEGOTIATED:
t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
t38negotiated = 1;
+ details->is_t38_negotiated = 1;
break;
default:
break;
@@ -2880,11 +2889,17 @@ static struct fax_gateway *fax_gateway_new(struct ast_channel *chan, struct ast_
return gateway;
}
-/*! \brief Create a fax session and start T.30<->T.38 gateway mode
+/*!
+ * \brief Create a fax session and start T.30<->T.38 gateway mode
+ *
* \param gateway a fax gateway object
* \param details fax session details
* \param chan active channel
- * \return 0 on error 1 on success*/
+ *
+ * \pre chan is locked on entry
+ *
+ * \return 0 on error 1 on success
+ */
static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
{
struct ast_fax_session *s;
@@ -2896,6 +2911,7 @@ static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session
ast_string_field_set(details, result, "FAILED");
ast_string_field_set(details, resultstr, "error starting gateway session");
ast_string_field_set(details, error, "INIT_ERROR");
+ details->is_t38_negotiated = 0;
set_channel_variables(chan, details);
report_fax_status(chan, details, "No Available Resource");
ast_log(LOG_ERROR, "Can't create a FAX session, gateway attempt failed.\n");
@@ -2916,6 +2932,7 @@ static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session
ast_string_field_set(details, result, "FAILED");
ast_string_field_set(details, resultstr, "error starting gateway session");
ast_string_field_set(details, error, "INIT_ERROR");
+ details->is_t38_negotiated = 0;
set_channel_variables(chan, details);
return -1;
}
@@ -2928,6 +2945,7 @@ static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session
return 0;
}
+/*! \pre chan is locked on entry */
static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_frame *f)
{
struct ast_frame *fp;
@@ -2960,12 +2978,14 @@ static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, st
gateway->t38_state = T38_STATE_NEGOTIATING;
gateway->timeout_start = ast_tvnow();
+ details->is_t38_negotiated = 0;
details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
ast_debug(1, "requesting T.38 for gateway session for %s\n", ast_channel_name(chan));
return fp;
}
+/*! \pre chan is locked on entry */
static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
{
struct ast_channel *other = (active == chan) ? peer : chan;
@@ -2981,8 +3001,14 @@ static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, str
}
if (gateway->detected_v21) {
+ enum ast_t38_state state_other;
+
destroy_v21_sessions(gateway);
- if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
+
+ ast_channel_unlock(chan);
+ state_other = ast_channel_get_t38_state(other);
+ ast_channel_lock(chan);
+ if (state_other == T38_STATE_UNKNOWN) {
ast_debug(1, "detected v21 preamble from %s\n", ast_channel_name(active));
return fax_gateway_request_t38(gateway, chan, f);
} else {
@@ -2993,21 +3019,29 @@ static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, str
return f;
}
-static int fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
+/*! \pre chan is locked on entry */
+static void fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
{
if (active == chan) {
- return ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
+ ast_channel_unlock(chan);
+ ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
+ ast_channel_lock(chan);
} else {
- return ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
+ ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
}
}
-/*! \brief T38 Gateway Negotiate t38 parameters
+/*!
+ * \brief T38 Gateway Negotiate t38 parameters
+ *
* \param gateway gateway object
* \param chan channel running the gateway
* \param peer channel im bridged too
* \param active channel the frame originated on
* \param f the control frame to process
+ *
+ * \pre chan is locked on entry
+ *
* \return processed control frame or null frame
*/
static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
@@ -3015,6 +3049,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
struct ast_control_t38_parameters *control_params = f->data.ptr;
struct ast_channel *other = (active == chan) ? peer : chan;
struct ast_fax_session_details *details;
+ enum ast_t38_state state_other;
if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
/* invalaid AST_CONTROL_T38_PARAMETERS frame, we can't
@@ -3037,9 +3072,11 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
}
if (control_params->request_response == AST_T38_REQUEST_NEGOTIATE) {
- enum ast_t38_state state = ast_channel_get_t38_state(other);
+ ast_channel_unlock(chan);
+ state_other = ast_channel_get_t38_state(other);
+ ast_channel_lock(chan);
- if (state == T38_STATE_UNKNOWN) {
+ if (state_other == T38_STATE_UNKNOWN) {
/* we detected a request to negotiate T.38 and the
* other channel appears to support T.38, we'll pass
* the request through and only step in if the other
@@ -3048,10 +3085,11 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
gateway->t38_state = T38_STATE_UNKNOWN;
gateway->timeout_start = ast_tvnow();
+ details->is_t38_negotiated = 0;
details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
ao2_ref(details, -1);
return f;
- } else if (state == T38_STATE_UNAVAILABLE || state == T38_STATE_REJECTED) {
+ } else if (state_other == T38_STATE_UNAVAILABLE || state_other == T38_STATE_REJECTED) {
/* the other channel does not support T.38, we need to
* step in here */
ast_debug(1, "%s is attempting to negotiate T.38 but %s does not support it\n", ast_channel_name(active), ast_channel_name(other));
@@ -3063,12 +3101,14 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
if (fax_gateway_start(gateway, details, chan)) {
ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
gateway->t38_state = T38_STATE_REJECTED;
+ details->is_t38_negotiated = 0;
control_params->request_response = AST_T38_REFUSED;
ast_framehook_detach(chan, details->gateway_id);
details->gateway_id = -1;
} else {
gateway->t38_state = T38_STATE_NEGOTIATED;
+ details->is_t38_negotiated = chan == active;
control_params->request_response = AST_T38_NEGOTIATED;
report_fax_status(chan, details, "T.38 Negotiated");
}
@@ -3086,6 +3126,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
gateway->t38_state = T38_STATE_UNKNOWN;
gateway->timeout_start = ast_tvnow();
+ details->is_t38_negotiated = 0;
details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
ast_debug(1, "%s is attempting to negotiate T.38 after we already sent a negotiation request based on v21 preamble detection\n", ast_channel_name(active));
@@ -3108,6 +3149,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
ast_string_field_set(details, result, "SUCCESS");
ast_string_field_set(details, resultstr, "no gateway necessary");
ast_string_field_set(details, error, "NATIVE_T38");
+ details->is_t38_negotiated = 1;
set_channel_variables(chan, details);
ast_debug(1, "%s is attempting to negotiate T.38 after we already negotiated T.38 with %s, disabling the gateway\n", ast_channel_name(active), ast_channel_name(other));
@@ -3122,11 +3164,15 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
&& control_params->request_response == AST_T38_REFUSED) {
ast_debug(1, "unable to negotiate T.38 on %s for fax gateway\n", ast_channel_name(active));
+ details->is_t38_negotiated = 0;
/* our request to negotiate T.38 was refused, if the other
* channel supports T.38, they might still reinvite and save
* the day. Otherwise disable the gateway. */
- if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
+ ast_channel_unlock(chan);
+ state_other = ast_channel_get_t38_state(other);
+ ast_channel_lock(chan);
+ if (state_other == T38_STATE_UNKNOWN) {
gateway->t38_state = T38_STATE_UNAVAILABLE;
} else {
ast_framehook_detach(chan, details->gateway_id);
@@ -3150,11 +3196,13 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
if (fax_gateway_start(gateway, details, chan)) {
ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
gateway->t38_state = T38_STATE_NEGOTIATING;
+ details->is_t38_negotiated = 0;
control_params->request_response = AST_T38_REQUEST_TERMINATE;
fax_gateway_indicate_t38(chan, active, control_params);
} else {
gateway->t38_state = T38_STATE_NEGOTIATED;
+ details->is_t38_negotiated = chan == active;
report_fax_status(chan, details, "T.38 Negotiated");
}
@@ -3170,14 +3218,16 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
if (fax_gateway_start(gateway, details, chan)) {
- ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
+ ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(other), ast_channel_name(active));
gateway->t38_state = T38_STATE_REJECTED;
+ details->is_t38_negotiated = 0;
control_params->request_response = AST_T38_REFUSED;
ast_framehook_detach(chan, details->gateway_id);
details->gateway_id = -1;
} else {
gateway->t38_state = T38_STATE_NEGOTIATED;
+ details->is_t38_negotiated = chan == other;
control_params->request_response = AST_T38_NEGOTIATED;
}
@@ -3193,6 +3243,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
details->gateway_id = -1;
gateway->t38_state = T38_STATE_REJECTED;
+ details->is_t38_negotiated = 0;
control_params->request_response = AST_T38_TERMINATED;
fax_gateway_indicate_t38(chan, active, control_params);
@@ -3208,6 +3259,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
ast_string_field_set(details, result, "SUCCESS");
ast_string_field_set(details, resultstr, "no gateway necessary");
ast_string_field_set(details, error, "NATIVE_T38");
+ details->is_t38_negotiated = 1;
set_channel_variables(chan, details);
ao2_ref(details, -1);
@@ -3250,7 +3302,8 @@ static void fax_gateway_framehook_destroy(void *data)
ao2_ref(gateway, -1);
}
-/*! \brief T.30<->T.38 gateway framehook.
+/*!
+ * \brief T.30<->T.38 gateway framehook.
*
* Intercept packets on bridged channels and determine if a T.38 gateway is
* required. If a gateway is required, start a gateway and handle T.38
@@ -3261,6 +3314,8 @@ static void fax_gateway_framehook_destroy(void *data)
* \param event framehook event
* \param data framehook data (struct fax_gateway *)
*
+ * \pre chan is locked on entry
+ *
* \return processed frame or NULL when f is NULL or a null frame
*/
static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
@@ -3323,8 +3378,16 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
}
if (!gateway->bridged) {
+ enum ast_t38_state state_chan;
+ enum ast_t38_state state_peer;
+
+ ast_channel_unlock(chan);
+ state_chan = ast_channel_get_t38_state(chan);
+ state_peer = ast_channel_get_t38_state(peer);
+ ast_channel_lock(chan);
+
/* don't start a gateway if neither channel can handle T.38 */
- if (ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE && ast_channel_get_t38_state(peer) == T38_STATE_UNAVAILABLE) {
+ if (state_chan == T38_STATE_UNAVAILABLE && state_peer == T38_STATE_UNAVAILABLE) {
ast_debug(1, "not starting gateway for %s and %s; neither channel supports T.38\n", ast_channel_name(chan), ast_channel_name(peer));
ast_framehook_detach(chan, gateway->framehook);
details->gateway_id = -1;
@@ -3332,6 +3395,7 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
ast_string_field_set(details, result, "FAILED");
ast_string_field_set(details, resultstr, "neither channel supports T.38");
ast_string_field_set(details, error, "T38_NEG_ERROR");
+ details->is_t38_negotiated = 0;
set_channel_variables(chan, details);
return f;
}
@@ -3376,6 +3440,7 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
ast_string_field_set(details, result, "FAILED");
ast_string_field_build(details, resultstr, "no fax activity after %d ms", details->gateway_timeout);
ast_string_field_set(details, error, "TIMEOUT");
+ details->is_t38_negotiated = 0;
set_channel_variables(chan, details);
return f;
}
@@ -3491,9 +3556,9 @@ static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_d
.disable_inheritance = 1, /* Masquerade inheritance is handled through the datastore fixup */
};
- if (global_fax_debug) {
- details->option.debug = AST_FAX_OPTFLAG_TRUE;
- }
+ if (global_fax_debug) {
+ details->option.debug = AST_FAX_OPTFLAG_TRUE;
+ }
ast_string_field_set(details, result, "SUCCESS");
ast_string_field_set(details, resultstr, "gateway operation started successfully");
@@ -3506,6 +3571,7 @@ static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_d
ast_string_field_set(details, result, "FAILED");
ast_string_field_set(details, resultstr, "error initializing gateway session");
ast_string_field_set(details, error, "INIT_ERROR");
+ details->is_t38_negotiated = 0;
set_channel_variables(chan, details);
report_fax_status(chan, details, "No Available Resource");
return -1;
@@ -3521,6 +3587,7 @@ static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_d
ast_string_field_set(details, result, "FAILED");
ast_string_field_set(details, resultstr, "error attaching gateway to channel");
ast_string_field_set(details, error, "INIT_ERROR");
+ details->is_t38_negotiated = 0;
set_channel_variables(chan, details);
return -1;
}
@@ -4509,7 +4576,9 @@ static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *dat
ast_log(LOG_WARNING, "Attempt to attach a T.38 gateway on channel (%s) with gateway already running.\n", ast_channel_name(chan));
}
} else if (ast_false(val)) {
+ ast_channel_lock(chan);
ast_framehook_detach(chan, details->gateway_id);
+ ast_channel_unlock(chan);
details->gateway_id = -1;
} else {
ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(%s).\n", value, data);
@@ -4561,7 +4630,9 @@ static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *dat
ast_log(LOG_WARNING, "Attempt to attach a FAX detect on channel (%s) with FAX detect already running.\n", ast_channel_name(chan));
}
} else if (ast_false(val)) {
+ ast_channel_lock(chan);
ast_framehook_detach(chan, details->faxdetect_id);
+ ast_channel_unlock(chan);
details->faxdetect_id = -1;
} else {
ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(%s).\n", value, data);
diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c
index 975c5eefe..1d0c11c35 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -48,6 +48,15 @@
#define DEFAULT_MWI_TPS_QUEUE_LOW -1
#define DEFAULT_MWI_DISABLE_INITIAL_UNSOLICITED 0
+/*!
+ * \brief Cached global config object
+ *
+ * \details
+ * Cached so we don't have to keep asking sorcery for the config.
+ * We could ask for it hundreds of times a second if not more.
+ */
+static AO2_GLOBAL_OBJ_STATIC(global_cfg);
+
static char default_useragent[256];
struct global_config {
@@ -135,23 +144,14 @@ static int global_apply(const struct ast_sorcery *sorcery, void *obj)
ast_sip_add_global_request_header("Max-Forwards", max_forwards, 1);
ast_sip_add_global_request_header("User-Agent", cfg->useragent, 1);
ast_sip_add_global_response_header("Server", cfg->useragent, 1);
+
+ ao2_t_global_obj_replace_unref(global_cfg, cfg, "Applying global settings");
return 0;
}
static struct global_config *get_global_cfg(void)
{
- struct global_config *cfg;
- struct ao2_container *globals;
-
- globals = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "global",
- AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
- if (!globals) {
- return NULL;
- }
-
- cfg = ao2_find(globals, NULL, 0);
- ao2_ref(globals, -1);
- return cfg;
+ return ao2_global_obj_ref(global_cfg);
}
char *ast_sip_global_default_outbound_endpoint(void)
@@ -462,6 +462,8 @@ int ast_sip_destroy_sorcery_global(void)
ast_sorcery_instance_observer_remove(sorcery, &observer_callbacks_global);
+ ao2_t_global_obj_release(global_cfg, "Module is unloading");
+
return 0;
}
diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c
index e5bb90e5c..8fe4e8477 100644
--- a/res/res_pjsip_refer.c
+++ b/res/res_pjsip_refer.c
@@ -607,7 +607,10 @@ static void refer_blind_callback(struct ast_channel *chan, struct transfer_chann
ao2_ref(refer->progress, +1);
/* If we can't attach a frame hook for whatever reason send a notification of success immediately */
- if ((refer->progress->framehook = ast_framehook_attach(chan, &hook)) < 0) {
+ ast_channel_lock(chan);
+ refer->progress->framehook = ast_framehook_attach(chan, &hook);
+ ast_channel_unlock(chan);
+ if (refer->progress->framehook < 0) {
struct refer_progress_notification *notification = refer_progress_notification_alloc(refer->progress, 200,
PJSIP_EVSUB_STATE_TERMINATED);
@@ -638,7 +641,9 @@ static void refer_blind_callback(struct ast_channel *chan, struct transfer_chann
refer_progress_notify(notification);
}
+ ast_channel_lock(chan);
ast_framehook_detach(chan, refer->progress->framehook);
+ ast_channel_unlock(chan);
ao2_cleanup(refer->progress);
}
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 992902af2..01bfefdd9 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -501,25 +501,27 @@ static void t38_attach_framehook(struct ast_sip_session *session)
return;
}
- /* Skip attaching the framehook if the T.38 datastore already exists for the channel */
ast_channel_lock(session->channel);
- if ((datastore = ast_channel_datastore_find(session->channel, &t38_framehook_datastore, NULL))) {
+
+ /* Skip attaching the framehook if the T.38 datastore already exists for the channel */
+ datastore = ast_channel_datastore_find(session->channel, &t38_framehook_datastore,
+ NULL);
+ if (datastore) {
ast_channel_unlock(session->channel);
return;
}
- ast_channel_unlock(session->channel);
framehook_id = ast_framehook_attach(session->channel, &hook);
if (framehook_id < 0) {
- ast_log(LOG_WARNING, "Could not attach T.38 Frame hook to channel, T.38 will be unavailable on '%s'\n",
+ ast_log(LOG_WARNING, "Could not attach T.38 Frame hook, T.38 will be unavailable on '%s'\n",
ast_channel_name(session->channel));
+ ast_channel_unlock(session->channel);
return;
}
- ast_channel_lock(session->channel);
datastore = ast_datastore_alloc(&t38_framehook_datastore, NULL);
if (!datastore) {
- ast_log(LOG_ERROR, "Could not attach T.38 Frame hook to channel, T.38 will be unavailable on '%s'\n",
+ ast_log(LOG_ERROR, "Could not alloc T.38 Frame hook datastore, T.38 will be unavailable on '%s'\n",
ast_channel_name(session->channel));
ast_framehook_detach(session->channel, framehook_id);
ast_channel_unlock(session->channel);