summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2013-06-06 21:40:35 +0000
committerMark Michelson <mmichelson@digium.com>2013-06-06 21:40:35 +0000
commit2dc8a060064f359a17f5ebcd515d85fe5203c019 (patch)
treefca012b9378a2a005fea30278f7d2a6129251b1f /channels
parent5f740572d081330fb43462eba5b0f495d8e56df1 (diff)
Refactor the features configuration scheme.
Features configuration is handled in its own API in features_config.h and features_config.c. This way, features configuration is accessible to anything that needs it. In addition, features configuration has been altered to be more channel-oriented. Most callers of features API code will be supplying a channel so that the individual channel's settings will be acquired rather than the global setting. Missing from this commit is XML documentation for the features configuration. That will be handled in a separate commit. Review: https://reviewboard.asterisk.org/r/2578/ (issue ASTERISK-21542) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@390751 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_dahdi.c26
-rw-r--r--channels/chan_mgcp.c15
-rw-r--r--channels/chan_misdn.c30
-rw-r--r--channels/chan_sip.c42
-rw-r--r--channels/chan_unistim.c28
-rw-r--r--channels/sig_analog.c24
-rw-r--r--channels/sip/include/sip.h5
7 files changed, 139 insertions, 31 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 00c25b9c1..92de02391 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -130,6 +130,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/paths.h"
#include "asterisk/ccss.h"
#include "asterisk/data.h"
+#include "asterisk/features_config.h"
/*** DOCUMENTATION
<application name="DAHDISendKeypadFacility" language="en_US">
@@ -10137,15 +10138,15 @@ static int dahdi_dnd(struct dahdi_pvt *dahdichan, int flag)
return 0;
}
-static int canmatch_featurecode(const char *exten)
+static int canmatch_featurecode(const char *pickupexten, const char *exten)
{
int extlen = strlen(exten);
- const char *pickup_ext;
+
if (!extlen) {
return 1;
}
- pickup_ext = ast_pickup_ext();
- if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) {
+
+ if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
return 1;
}
/* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
@@ -10191,6 +10192,8 @@ static void *analog_ss_thread(void *data)
int res;
int idx;
struct ast_format tmpfmt;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
ast_mutex_lock(&ss_thread_lock);
ss_thread_count++;
@@ -10210,6 +10213,17 @@ static void *analog_ss_thread(void *data)
ast_hangup(chan);
goto quit;
}
+
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ 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);
+ }
+ ast_channel_unlock(chan);
+
if (p->dsp)
ast_dsp_digitreset(p->dsp);
switch (p->sig) {
@@ -10576,7 +10590,7 @@ static void *analog_ss_thread(void *data)
memset(exten, 0, sizeof(exten));
timeout = firstdigittimeout;
- } else if (!strcmp(exten,ast_pickup_ext())) {
+ } else if (!strcmp(exten, pickupexten)) {
/* Scan all channels and see if there are any
* ringing channels that have call groups
* that equal this channels pickup group
@@ -10708,7 +10722,7 @@ static void *analog_ss_thread(void *data)
}
} else if (!ast_canmatch_extension(chan, ast_channel_context(chan), exten, 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
- && !canmatch_featurecode(exten)) {
+ && !canmatch_featurecode(pickupexten, exten)) {
ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
ast_channel_context(chan));
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index df82061b8..9080dbaf0 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -84,6 +84,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/pktccops.h"
#include "asterisk/stasis.h"
#include "asterisk/bridging.h"
+#include "asterisk/features_config.h"
/*
* Define to work around buggy dlink MGCP phone firmware which
@@ -2971,9 +2972,21 @@ static void *mgcp_ss(void *data)
int res= 0;
int getforward = 0;
int loop_pause = 100;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
len = strlen(p->dtmf_buf);
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ 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);
+ }
+ ast_channel_unlock(chan);
+
while (len < AST_MAX_EXTENSION - 1) {
ast_debug(1, "Dtmf buffer '%s' for '%s@%s'\n", p->dtmf_buf, p->name, p->parent->name);
res = 1; /* Assume that we will get a digit */
@@ -3065,7 +3078,7 @@ static void *mgcp_ss(void *data)
len = 0;
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
timeout = firstdigittimeout;
- } else if (!strcmp(p->dtmf_buf,ast_pickup_ext())) {
+ } else if (!strcmp(p->dtmf_buf, pickupexten)) {
/* Scan all channels and see if any there
* ringing channqels with that have call groups
* that equal this channels pickup group
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index c68538e66..1a8f0d980 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -102,6 +102,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/causes.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
+#include "asterisk/features_config.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
@@ -10071,6 +10072,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
if (ch->state == MISDN_WAITING4DIGS) {
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
+
/* Ok, incomplete Setup, waiting till extension exists */
if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
chan_misdn_log(1, bc->port, " --> using keypad as info\n");
@@ -10080,8 +10084,18 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
ast_channel_exten_set(ch->ast, bc->dialed.number);
+ ast_channel_lock(ch->ast);
+ pickup_cfg = ast_get_chan_features_pickup_config(ch->ast);
+ 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);
+ }
+ ast_channel_unlock(ch->ast);
+
/* Check for Pickup Request first */
- if (!strcmp(ast_channel_exten(ch->ast), ast_pickup_ext())) {
+ if (!strcmp(ast_channel_exten(ch->ast), pickupexten)) {
if (ast_pickup_call(ch->ast)) {
hangup_chan(ch, bc);
} else {
@@ -10169,6 +10183,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
int ai;
int im;
int append_msn = 0;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
if (ch) {
switch (ch->state) {
@@ -10224,6 +10240,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
return RESPONSE_RELEASE_SETUP;
}
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ 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);
+ }
+ ast_channel_unlock(chan);
+
if ((exceed = add_in_calls(bc->port))) {
char tmp[16];
snprintf(tmp, sizeof(tmp), "%d", exceed);
@@ -10315,7 +10341,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
/* Check for Pickup Request first */
- if (!strcmp(ast_channel_exten(chan), ast_pickup_ext())) {
+ if (!strcmp(ast_channel_exten(chan), pickupexten)) {
if (!ch->noautorespond_on_setup) {
/* Sending SETUP_ACK */
misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index fe67d28c7..eb79d237e 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -296,6 +296,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/app.h"
#include "asterisk/bridging.h"
#include "asterisk/stasis_endpoints.h"
+#include "asterisk/features_config.h"
/*** DOCUMENTATION
<application name="SIPDtmfMode" language="en_US">
@@ -17662,6 +17663,16 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
char tmpf[256] = "", *from = NULL;
struct sip_request *req;
char *decoded_uri;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, ast_get_chan_features_pickup_config(p->owner), ao2_cleanup);
+ const char *pickupexten;
+
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ /* Don't need to duplicate since channel is locked for the duration of this function */
+ pickupexten = pickup_cfg->pickupexten;
+ }
req = oreq;
if (!req) {
@@ -17772,7 +17783,7 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
return SIP_GET_DEST_EXTEN_FOUND;
}
if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
- || !strcmp(decoded_uri, ast_pickup_ext())) {
+ || !strcmp(decoded_uri, pickupexten)) {
if (!oreq) {
ast_string_field_set(p, exten, decoded_uri);
}
@@ -17800,7 +17811,7 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)
&& (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))
|| ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
- || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) {
+ || !strncmp(decoded_uri, pickupexten, strlen(decoded_uri)))) {
/* Overlap dialing is enabled and we need more digits to match an extension. */
return SIP_GET_DEST_EXTEN_MATCHMORE;
}
@@ -21699,7 +21710,8 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
* on phone calls.
*/
- struct ast_call_feature *feat = NULL;
+ char feat[AST_FEATURE_MAX_LEN];
+ int feat_res = -1;
int j;
struct ast_frame f = { AST_FRAME_DTMF, };
int suppress_warning = 0; /* Supress warning if the feature is blank */
@@ -21711,43 +21723,40 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
}
/* first, get the feature string, if it exists */
- ast_rdlock_call_features();
if (p->relatedpeer) {
if (!strcasecmp(c, "on")) {
if (ast_strlen_zero(p->relatedpeer->record_on_feature)) {
suppress_warning = 1;
} else {
- feat = ast_find_call_feature(p->relatedpeer->record_on_feature);
+ feat_res = ast_get_feature(p->owner, p->relatedpeer->record_on_feature, feat, sizeof(feat));
}
} else if (!strcasecmp(c, "off")) {
if (ast_strlen_zero(p->relatedpeer->record_off_feature)) {
suppress_warning = 1;
} else {
- feat = ast_find_call_feature(p->relatedpeer->record_off_feature);
+ feat_res = ast_get_feature(p->owner, p->relatedpeer->record_off_feature, feat, sizeof(feat));
}
} else {
ast_log(LOG_ERROR, "Received INFO requesting to record with invalid value: %s\n", c);
}
}
- if (!feat || ast_strlen_zero(feat->exten)) {
+ if (feat_res || ast_strlen_zero(feat)) {
if (!suppress_warning) {
ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
}
/* 403 means that we don't support this feature, so don't request it again */
transmit_response(p, "403 Forbidden", req);
- ast_unlock_call_features();
return;
}
/* Send the feature code to the PBX as DTMF, just like the handset had sent it */
f.len = 100;
- for (j = 0; j < strlen(feat->exten); j++) {
- f.subclass.integer = feat->exten[j];
+ for (j = 0; j < strlen(feat); j++) {
+ f.subclass.integer = feat[j];
ast_queue_frame(p->owner, &f);
if (sipdebug) {
ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer);
}
}
- ast_unlock_call_features();
ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
transmit_response(p, "200 OK", req);
@@ -25650,6 +25659,15 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */
enum ast_channel_state c_state = ast_channel_state(c);
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, ast_get_chan_features_pickup_config(c), ao2_cleanup);
+ const char *pickupexten;
+
+ 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);
+ }
if (c_state != AST_STATE_UP && reinvite &&
(p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
@@ -25671,7 +25689,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
transmit_provisional_response(p, "100 Trying", req, 0);
p->invitestate = INV_PROCEEDING;
ast_setstate(c, AST_STATE_RING);
- if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
+ if (strcmp(p->exten, pickupexten)) { /* Call to extension -start pbx on this call */
enum ast_pbx_result result;
result = ast_pbx_start(c);
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 426e6ab10..28d332f62 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/features.h"
#include "asterisk/astobj2.h"
#include "asterisk/astdb.h"
+#include "asterisk/features_config.h"
#define DEFAULTCONTEXT "default"
@@ -3086,11 +3087,25 @@ static void handle_call_outgoing(struct unistimsession *s)
send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s);
s->device->selected = -1;
if (!sub->owner) { /* A call is already in progress ? */
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
+
c = unistim_new(sub, AST_STATE_DOWN, NULL); /* No, starting a new one */
if (!sub->rtp) { /* Need to start RTP before calling ast_pbx_run */
start_rtp(sub);
}
- if (c && !strcmp(s->device->phone_number, ast_pickup_ext())) {
+ if (c) {
+ ast_channel_lock(c);
+ pickup_cfg = ast_get_chan_features_pickup_config(c);
+ 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);
+ }
+ ast_channel_unlock(c);
+ }
+ if (c && !strcmp(s->device->phone_number, pickupexten)) {
if (unistimdebug) {
ast_verb(0, "Try to pickup in unistim_new\n");
}
@@ -4099,8 +4114,17 @@ static void key_main_page(struct unistimsession *pte, char keycode)
ast_mutex_unlock(&devicelock);
show_extension_page(pte);
} else { /* Pickup function */
+ /* XXX Is there a way to get a specific channel here? */
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg,
+ ast_get_chan_features_pickup_config(NULL), ao2_cleanup);
+
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ break;
+ }
+
pte->device->selected = -1;
- ast_copy_string(pte->device->phone_number, ast_pickup_ext(),
+ ast_copy_string(pte->device->phone_number, pickup_cfg->pickupexten,
sizeof(pte->device->phone_number));
handle_call_outgoing(pte);
}
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index e3bd1d0c8..956c4a654 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -43,6 +43,7 @@
#include "asterisk/features.h"
#include "asterisk/cel.h"
#include "asterisk/causes.h"
+#include "asterisk/features_config.h"
#include "sig_analog.h"
@@ -1708,15 +1709,13 @@ static int analog_get_sub_fd(struct analog_pvt *p, enum analog_sub sub)
#define ANALOG_NEED_MFDETECT(p) (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB))
-static int analog_canmatch_featurecode(const char *exten)
+static int analog_canmatch_featurecode(const char *pickupexten, const char *exten)
{
int extlen = strlen(exten);
- const char *pickup_ext;
if (!extlen) {
return 1;
}
- pickup_ext = ast_pickup_ext();
- if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) {
+ if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
return 1;
}
/* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
@@ -1756,6 +1755,8 @@ static void *__analog_ss_thread(void *data)
int res;
int idx;
struct ast_callid *callid;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
analog_increase_ss_count();
@@ -1786,6 +1787,17 @@ static void *__analog_ss_thread(void *data)
ast_hangup(chan);
goto quit;
}
+
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ 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);
+ }
+ ast_channel_unlock(chan);
+
analog_dsp_reset_and_flush_digits(p);
switch (p->sig) {
case ANALOG_SIG_FEATD:
@@ -2190,7 +2202,7 @@ static void *__analog_ss_thread(void *data)
memset(exten, 0, sizeof(exten));
timeout = analog_firstdigittimeout;
- } else if (!strcmp(exten,ast_pickup_ext())) {
+ } else if (!strcmp(exten, pickupexten)) {
/* Scan all channels and see if there are any
* ringing channels that have call groups
* that equal this channels pickup group
@@ -2334,7 +2346,7 @@ static void *__analog_ss_thread(void *data)
}
} else if (!ast_canmatch_extension(chan, ast_channel_context(chan), exten, 1,
ast_channel_caller(chan)->id.number.valid ? ast_channel_caller(chan)->id.number.str : NULL)
- && !analog_canmatch_featurecode(exten)) {
+ && !analog_canmatch_featurecode(pickupexten, exten)) {
ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
ast_channel_caller(chan)->id.number.valid && ast_channel_caller(chan)->id.number.str
? ast_channel_caller(chan)->id.number.str : "<Unknown Caller>",
diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h
index 185f3935d..0adde37f2 100644
--- a/channels/sip/include/sip.h
+++ b/channels/sip/include/sip.h
@@ -38,6 +38,7 @@
#include "asterisk/http_websocket.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/netsock2.h"
+#include "asterisk/features_config.h"
#ifndef FALSE
#define FALSE 0
@@ -762,8 +763,8 @@ struct sip_settings {
struct sip_proxy outboundproxy; /*!< Outbound proxy */
char default_context[AST_MAX_CONTEXT];
char default_subscribecontext[AST_MAX_CONTEXT];
- char default_record_on_feature[FEATURE_MAX_LEN];
- char default_record_off_feature[FEATURE_MAX_LEN];
+ char default_record_on_feature[AST_FEATURE_MAX_LEN];
+ char default_record_off_feature[AST_FEATURE_MAX_LEN];
struct ast_acl_list *contact_acl; /*! \brief Global list of addresses dynamic peers are not allowed to use */
struct ast_format_cap *caps; /*!< Supported codecs */
int tcp_enabled;