aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2010-11-19 16:47:11 +0000
committerrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2010-11-19 16:47:11 +0000
commit4801e8a95ba78f7a2a26c55ccc98c43dfa506714 (patch)
treeea3566c431d2f3a6eea68ec0f85aeb7162155ba0 /channels
parent0a3647435d88bec66ef63659379662a92614f0b3 (diff)
Bring sig_analog extraction more into alignment with orig-trunk/v1.6.2 chan_dahdi.
* Restore SMDI support. * Fixed initial value of struct analog_pvt.use_callerid. It may get forced on depending upon other config options. * Call analog_dnd() instead of manual inlined code. * Removed unused struct analog_pvt.usedistinctiveringdetection. * Removed the struct analog_pvt.unknown_alarm flag. It was really the struct analog_pvt.inalarm flag. * Use ast_debug() instead of ast_log(LOG_DEBUG). * Rename several function's index variable to idx. * Some formatting tweaks. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.8@295516 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_dahdi.c7
-rw-r--r--channels/sig_analog.c485
-rw-r--r--channels/sig_analog.h15
3 files changed, 271 insertions, 236 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index bf67c3298..34364a06a 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -955,7 +955,7 @@ struct dahdi_pvt {
*/
unsigned int use_smdi:1;
struct mwisend_info mwisend_data;
- /*! \brief The serial port to listen for SMDI data on */
+ /*! \brief The SMDI interface to get SMDI messages from. */
struct ast_smdi_interface *smdi_iface;
/*! \brief Distinctive Ring data */
@@ -12564,7 +12564,9 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
analog_p->threewaycalling = conf->chan.threewaycalling;
analog_p->transfer = conf->chan.transfer;
analog_p->transfertobusy = conf->chan.transfertobusy;
- analog_p->use_callerid = conf->chan.use_callerid;
+ analog_p->use_callerid = tmp->use_callerid;
+ analog_p->use_smdi = tmp->use_smdi;
+ analog_p->smdi_iface = tmp->smdi_iface;
analog_p->outsigmod = ANALOG_SIG_NONE;
analog_p->echotraining = conf->chan.echotraining;
analog_p->cid_signalling = conf->chan.cid_signalling;
@@ -12584,7 +12586,6 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
break;
}
analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid;
- analog_p->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
analog_p->ringt = conf->chan.ringt;
analog_p->ringt_base = ringt_base;
analog_p->chan_tech = &dahdi_tech;
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index ac1723ebc..6788b8309 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -766,7 +766,7 @@ struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const s
{
struct ast_channel *ast;
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
*callwait = (p->owner != NULL);
if (p->owner) {
@@ -789,7 +789,8 @@ int analog_available(struct analog_pvt *p)
{
int offhook;
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
+
/* If do not disturb, definitely not */
if (p->dnd) {
return 0;
@@ -814,6 +815,7 @@ int analog_available(struct analog_pvt *p)
/* TDM FXS card, "offhook" means someone took the hook off so it's unavailable! */
} else if (offhook) {
ast_debug(1, "Channel %d off hook, can't use\n", p->channel);
+ /* Not available when the other end is off hook */
return 0;
}
return 1;
@@ -979,11 +981,11 @@ static void analog_set_inthreeway(struct analog_pvt *p, enum analog_sub sub, int
int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout)
{
- int res, index,mysig;
+ int res, idx, mysig;
char *c, *n, *l;
char dest[256]; /* must be same length as p->dialdest */
- ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n",
+ ast_debug(1, "CALLING CID_NAME: %s CID_NUM:: %s\n",
S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
@@ -1042,6 +1044,7 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int
}
analog_set_dialing(p, 1);
} else {
+ /* Call waiting call */
if (ast->connected.id.number.valid && ast->connected.id.number.str) {
ast_copy_string(p->callwait_num, ast->connected.id.number.str, sizeof(p->callwait_num));
} else {
@@ -1082,14 +1085,14 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int
}
ast_setstate(ast, AST_STATE_RINGING);
- index = analog_get_index(ast, p, 0);
- if (index > -1) {
+ idx = analog_get_index(ast, p, 0);
+ if (idx > -1) {
struct ast_cc_config_params *cc_params;
/* This is where the initial ringing frame is queued for an analog call.
* As such, this is a great time to offer CCNR to the caller if it's available.
*/
- cc_params = ast_channel_get_cc_config_params(p->subs[index].owner);
+ cc_params = ast_channel_get_cc_config_params(p->subs[idx].owner);
if (cc_params) {
switch (ast_get_cc_monitor_policy(cc_params)) {
case AST_CC_MONITOR_NEVER:
@@ -1097,12 +1100,12 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int
case AST_CC_MONITOR_NATIVE:
case AST_CC_MONITOR_ALWAYS:
case AST_CC_MONITOR_GENERIC:
- ast_queue_cc_frame(p->subs[index].owner, AST_CC_GENERIC_MONITOR_TYPE,
+ ast_queue_cc_frame(p->subs[idx].owner, AST_CC_GENERIC_MONITOR_TYPE,
analog_get_orig_dialstring(p), AST_CC_CCNR, NULL);
break;
}
}
- ast_queue_control(p->subs[index].owner, AST_CONTROL_RINGING);
+ ast_queue_control(p->subs[idx].owner, AST_CONTROL_RINGING);
}
break;
case ANALOG_SIG_FXSLS:
@@ -1144,7 +1147,7 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int
return -1;
}
}
- ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
+ ast_debug(1, "Dialing '%s'\n", c);
p->dop.op = ANALOG_DIAL_OP_REPLACE;
c += p->stripmsd;
@@ -1246,38 +1249,38 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int
int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
{
int res;
- int index, x;
+ int idx, x;
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
if (!ast->tech_pvt) {
ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
return 0;
}
- index = analog_get_index(ast, p, 1);
+ idx = analog_get_index(ast, p, 1);
x = 0;
if (p->origcid_num) {
ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
- free(p->origcid_num);
+ ast_free(p->origcid_num);
p->origcid_num = NULL;
}
if (p->origcid_name) {
ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
- free(p->origcid_name);
+ ast_free(p->origcid_name);
p->origcid_name = NULL;
}
analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
- p->channel, index, p->subs[ANALOG_SUB_REAL].allocd, p->subs[ANALOG_SUB_CALLWAIT].allocd, p->subs[ANALOG_SUB_THREEWAY].allocd);
- if (index > -1) {
+ p->channel, idx, p->subs[ANALOG_SUB_REAL].allocd, p->subs[ANALOG_SUB_CALLWAIT].allocd, p->subs[ANALOG_SUB_THREEWAY].allocd);
+ if (idx > -1) {
/* Real channel, do some fixup */
- p->subs[index].owner = NULL;
+ p->subs[idx].owner = NULL;
p->polarity = POLARITY_IDLE;
- analog_set_linear_mode(p, index, 0);
- switch (index) {
+ analog_set_linear_mode(p, idx, 0);
+ switch (idx) {
case ANALOG_SUB_REAL:
if (p->subs[ANALOG_SUB_CALLWAIT].allocd && p->subs[ANALOG_SUB_THREEWAY].allocd) {
ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
@@ -1436,6 +1439,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
break;
default:
analog_play_tone(p, ANALOG_SUB_REAL, -1);
+ break;
}
analog_set_echocanceller(p, 0);
@@ -1462,13 +1466,14 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
{
int res = 0;
- int index;
+ int idx;
int oldstate = ast->_state;
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
+
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
ast_setstate(ast, AST_STATE_UP);
- index = analog_get_index(ast, p, 1);
- if (index < 0) {
- index = ANALOG_SUB_REAL;
+ idx = analog_get_index(ast, p, 1);
+ if (idx < 0) {
+ idx = ANALOG_SUB_REAL;
}
switch (p->sig) {
case ANALOG_SIG_FXSLS:
@@ -1500,9 +1505,9 @@ int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
gettimeofday(&p->polaritydelaytv, NULL);
}
res = analog_off_hook(p);
- analog_play_tone(p, index, -1);
+ analog_play_tone(p, idx, -1);
analog_set_dialing(p, 0);
- if ((index == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
+ if ((idx == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
if (oldstate == AST_STATE_RINGING) {
ast_debug(1, "Finally swapping real and threeway\n");
analog_play_tone(p, ANALOG_SUB_THREEWAY, -1);
@@ -1530,6 +1535,7 @@ int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
default:
ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
res = -1;
+ break;
}
ast_setstate(ast, AST_STATE_UP);
return res;
@@ -1560,21 +1566,22 @@ static int analog_handles_digit(struct ast_frame *f)
}
}
-void analog_handle_dtmfup(struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, struct ast_frame **dest)
+void analog_handle_dtmfup(struct analog_pvt *p, struct ast_channel *ast, enum analog_sub idx, struct ast_frame **dest)
{
struct ast_frame *f = *dest;
+ ast_debug(1, "DTMF digit: %c on %s\n", f->subclass.integer, ast->name);
+
if (analog_check_confirmanswer(p)) {
ast_debug(1, "Confirm answer on %s!\n", ast->name);
/* Upon receiving a DTMF digit, consider this an answer confirmation instead
of a DTMF digit */
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_ANSWER;
- *dest = &p->subs[index].f;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
+ *dest = &p->subs[idx].f;
/* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
analog_set_confirmanswer(p, 0);
- }
- if (p->callwaitcas) {
+ } else if (p->callwaitcas) {
if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
ast_debug(1, "Got some DTMF, but it's for the CAS\n");
p->caller.id.name.str = p->callwait_name;
@@ -1583,11 +1590,11 @@ void analog_handle_dtmfup(struct analog_pvt *p, struct ast_channel *ast, enum an
}
if (analog_handles_digit(f))
p->callwaitcas = 0;
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass.integer = 0;
- *dest = &p->subs[index].f;
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.subclass.integer = 0;
+ *dest = &p->subs[idx].f;
} else {
- analog_cb_handle_dtmfup(p, ast, index, dest);
+ analog_cb_handle_dtmfup(p, ast, idx, dest);
}
}
@@ -1685,16 +1692,17 @@ static void *__analog_ss_thread(void *data)
struct callerid_state *cs = NULL;
char *name = NULL, *number = NULL;
int flags = 0;
+ struct ast_smdi_md_message *smdi_msg = NULL;
int timeout;
int getforward = 0;
char *s1, *s2;
int len = 0;
int res;
- int index;
+ int idx;
analog_increase_ss_count(p);
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
if (!chan) {
/* What happened to the channel? */
@@ -1710,8 +1718,8 @@ static void *__analog_ss_thread(void *data)
}
ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
- index = analog_get_index(chan, p, 0);
- if (index < 0) {
+ idx = analog_get_index(chan, p, 0);
+ if (idx < 0) {
ast_hangup(chan);
goto quit;
}
@@ -1728,17 +1736,18 @@ static void *__analog_ss_thread(void *data)
case ANALOG_SIG_SF_FEATDMF:
case ANALOG_SIG_SF_FEATB:
case ANALOG_SIG_SFWINK:
- if (analog_wink(p, index))
+ if (analog_wink(p, idx))
goto quit;
/* Fall through */
case ANALOG_SIG_EM:
case ANALOG_SIG_EM_E1:
case ANALOG_SIG_SF:
case ANALOG_SIG_FGC_CAMA:
- res = analog_play_tone(p, index, -1);
+ res = analog_play_tone(p, idx, -1);
analog_dsp_reset_and_flush_digits(p);
+ /* set digit mode appropriately */
if (ANALOG_NEED_MFDETECT(p)) {
analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);
} else {
@@ -1772,7 +1781,7 @@ static void *__analog_ss_thread(void *data)
if (res < 1) {
analog_dsp_reset_and_flush_digits(p);
}
- if (analog_wink(p, index)) {
+ if (analog_wink(p, idx)) {
goto quit;
}
dtmfbuf[0] = 0;
@@ -1791,7 +1800,7 @@ static void *__analog_ss_thread(void *data)
/* if international caca, do it again to get real ANO */
if ((p->sig == ANALOG_SIG_FEATDMF) && (dtmfbuf[1] != '0')
&& (strlen(dtmfbuf) != 14)) {
- if (analog_wink(p, index)) {
+ if (analog_wink(p, idx)) {
goto quit;
}
dtmfbuf[0] = 0;
@@ -1875,13 +1884,13 @@ static void *__analog_ss_thread(void *data)
char anibuf[100];
if (ast_safe_sleep(chan,1000) == -1) {
- ast_hangup(chan);
- goto quit;
+ ast_hangup(chan);
+ goto quit;
}
analog_off_hook(p);
analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);
- res = analog_my_getsigstr(chan, anibuf, "#", 10000);
- if ((res > 0) && (strlen(anibuf) > 2)) {
+ res = analog_my_getsigstr(chan, anibuf, "#", 10000);
+ if ((res > 0) && (strlen(anibuf) > 2)) {
if (anibuf[strlen(anibuf) - 1] == '#') {
anibuf[strlen(anibuf) - 1] = 0;
}
@@ -1976,7 +1985,7 @@ static void *__analog_ss_thread(void *data)
}
}
if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {
- analog_wink(p, index);
+ analog_wink(p, idx);
/* some switches require a minimum guard time between
the last FGD wink and something that answers
immediately. This ensures it */
@@ -1995,13 +2004,13 @@ static void *__analog_ss_thread(void *data)
res = ast_pbx_run(chan);
if (res) {
ast_log(LOG_WARNING, "PBX exited non-zero\n");
- res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
}
goto quit;
} else {
ast_verb(3, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
sleep(2);
- res = analog_play_tone(p, index, ANALOG_TONE_INFO);
+ res = analog_play_tone(p, idx, ANALOG_TONE_INFO);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
} else {
@@ -2011,7 +2020,7 @@ static void *__analog_ss_thread(void *data)
if (res >= 0) {
ast_waitstream(chan, "");
}
- res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
ast_hangup(chan);
goto quit;
}
@@ -2037,17 +2046,18 @@ static void *__analog_ss_thread(void *data)
timeout = 0;
if (res < 0) {
ast_debug(1, "waitfordigit returned < 0...\n");
- res = analog_play_tone(p, index, -1);
+ res = analog_play_tone(p, idx, -1);
ast_hangup(chan);
goto quit;
} else if (res) {
+ ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
exten[len++]=res;
exten[len] = '\0';
}
if (!ast_ignore_pattern(chan->context, exten)) {
- analog_play_tone(p, index, -1);
+ analog_play_tone(p, idx, -1);
} else {
- analog_play_tone(p, index, ANALOG_TONE_DIALTONE);
+ analog_play_tone(p, idx, ANALOG_TONE_DIALTONE);
}
if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, chan->context)) {
if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
@@ -2055,19 +2065,19 @@ static void *__analog_ss_thread(void *data)
/* Record this as the forwarding extension */
ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
if (res) {
break;
}
usleep(500000);
- res = analog_play_tone(p, index, -1);
+ res = analog_play_tone(p, idx, -1);
sleep(1);
memset(exten, 0, sizeof(exten));
- res = analog_play_tone(p, index, ANALOG_TONE_DIALTONE);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALTONE);
len = 0;
getforward = 0;
} else {
- res = analog_play_tone(p, index, -1);
+ res = analog_play_tone(p, idx, -1);
ast_copy_string(chan->exten, exten, sizeof(chan->exten));
if (!ast_strlen_zero(p->cid_num)) {
if (!p->hidecallerid) {
@@ -2086,7 +2096,7 @@ static void *__analog_ss_thread(void *data)
res = ast_pbx_run(chan);
if (res) {
ast_log(LOG_WARNING, "PBX exited non-zero\n");
- res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
}
goto quit;
}
@@ -2097,7 +2107,7 @@ static void *__analog_ss_thread(void *data)
}
} else if (res == 0) {
ast_debug(1, "not enough digits (and no ambiguous match)...\n");
- res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
analog_wait_event(p);
ast_hangup(chan);
goto quit;
@@ -2105,7 +2115,7 @@ static void *__analog_ss_thread(void *data)
ast_verb(3, "Disabling call waiting on %s\n", chan->name);
/* Disable call waiting if enabled */
p->callwaiting = 0;
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
if (res) {
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
chan->name, strerror(errno));
@@ -2119,7 +2129,7 @@ static void *__analog_ss_thread(void *data)
* ringing channels that have call groups
* that equal this channels pickup group
*/
- if (index == ANALOG_SUB_REAL) {
+ if (idx == ANALOG_SUB_REAL) {
/* Switch us from Third call to Call Wait */
if (p->subs[ANALOG_SUB_THREEWAY].owner) {
/* If you make a threeway call and the *8# a call, it should actually
@@ -2131,7 +2141,7 @@ static void *__analog_ss_thread(void *data)
analog_set_echocanceller(p, 1);
if (ast_pickup_call(chan)) {
ast_debug(1, "No call pickup possible...\n");
- res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
analog_wait_event(p);
}
ast_hangup(chan);
@@ -2141,6 +2151,7 @@ static void *__analog_ss_thread(void *data)
ast_hangup(chan);
goto quit;
}
+
} else if (!p->hidecallerid && !strcmp(exten, "*67")) {
ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
/* Disable Caller*ID if enabled */
@@ -2149,7 +2160,7 @@ static void *__analog_ss_thread(void *data)
ast_party_number_init(&chan->caller.id.number);
ast_party_name_free(&chan->caller.id.name);
ast_party_name_init(&chan->caller.id.name);
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
if (res) {
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
chan->name, strerror(errno));
@@ -2163,39 +2174,31 @@ static void *__analog_ss_thread(void *data)
res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
}
if (!res) {
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
}
break;
} else if (!strcmp(exten, "*78")) {
- /* Do not disturb */
- ast_verb(3, "Enabled DND on channel %d\n", p->channel);
- manager_event(EVENT_FLAG_SYSTEM, "DNDState",
- "Channel: DAHDI/%d\r\n"
- "Status: enabled\r\n", p->channel);
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
- p->dnd = 1;
+ /* Do not disturb enabled */
+ analog_dnd(p, 1);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
getforward = 0;
memset(exten, 0, sizeof(exten));
len = 0;
} else if (!strcmp(exten, "*79")) {
- /* Do not disturb */
- ast_verb(3, "Disabled DND on channel %d\n", p->channel);
- manager_event(EVENT_FLAG_SYSTEM, "DNDState",
- "Channel: DAHDI/%d\r\n"
- "Status: disabled\r\n", p->channel);
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
- p->dnd = 0;
+ /* Do not disturb disabled */
+ analog_dnd(p, 0);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
getforward = 0;
memset(exten, 0, sizeof(exten));
len = 0;
} else if (p->cancallforward && !strcmp(exten, "*72")) {
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
getforward = 1;
memset(exten, 0, sizeof(exten));
len = 0;
} else if (p->cancallforward && !strcmp(exten, "*73")) {
ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
memset(p->call_forward, 0, sizeof(p->call_forward));
getforward = 0;
memset(exten, 0, sizeof(exten));
@@ -2212,7 +2215,7 @@ static void *__analog_ss_thread(void *data)
ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);
res = ast_db_put("blacklist", p->lastcid_num, "1");
if (!res) {
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
memset(exten, 0, sizeof(exten));
len = 0;
}
@@ -2221,7 +2224,7 @@ static void *__analog_ss_thread(void *data)
/* Enable Caller*ID if enabled */
p->hidecallerid = 0;
ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
- res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
+ res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
if (res) {
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
chan->name, strerror(errno));
@@ -2232,7 +2235,7 @@ static void *__analog_ss_thread(void *data)
} else if (!strcmp(exten, "*0")) {
struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;
struct analog_pvt *pbridge = NULL;
- /* set up the private struct of the bridged one, if any */
+ /* set up the private struct of the bridged one, if any */
if (nbridge && ast_bridged_channel(nbridge)) {
pbridge = analog_get_bridged_channel(p, nbridge);
}
@@ -2256,9 +2259,9 @@ static void *__analog_ss_thread(void *data)
ast_hangup(chan);
goto quit;
} else {
- analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
analog_wait_event(p);
- analog_play_tone(p, index, -1);
+ analog_play_tone(p, idx, -1);
analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
p->owner = p->subs[ANALOG_SUB_REAL].owner;
@@ -2278,27 +2281,48 @@ static void *__analog_ss_thread(void *data)
timeout = analog_gendigittimeout;
}
if (len && !ast_ignore_pattern(chan->context, exten)) {
- analog_play_tone(p, index, -1);
+ analog_play_tone(p, idx, -1);
}
}
break;
case ANALOG_SIG_FXSLS:
case ANALOG_SIG_FXSGS:
case ANALOG_SIG_FXSKS:
+ /* check for SMDI messages */
+ if (p->use_smdi && p->smdi_iface) {
+ smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, ANALOG_SMDI_MD_WAIT_TIMEOUT);
+ if (smdi_msg != NULL) {
+ ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
+
+ if (smdi_msg->type == 'B')
+ pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
+ else if (smdi_msg->type == 'N')
+ pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
+
+ ast_debug(1, "Received SMDI message on %s\n", chan->name);
+ } else {
+ ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
+ }
+ }
+
+ if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
+ number = smdi_msg->calling_st;
/* If we want caller id, we're in a prering state due to a polarity reversal
* and we're set to use a polarity reversal to trigger the start of caller id,
* grab the caller id and wait for ringing to start... */
- if (p->use_callerid && (chan->_state == AST_STATE_PRERING &&
- (p->cid_start == ANALOG_CID_START_POLARITY || p->cid_start == ANALOG_CID_START_POLARITY_IN || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) {
+ } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING
+ && (p->cid_start == ANALOG_CID_START_POLARITY
+ || p->cid_start == ANALOG_CID_START_POLARITY_IN
+ || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) {
/* If set to use DTMF CID signalling, listen for DTMF */
if (p->cid_signalling == CID_SIG_DTMF) {
- int i = 0;
+ int k = 0;
int oldlinearity;
cs = NULL;
ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name);
- oldlinearity = analog_set_linear_mode(p, index, 0);
+ oldlinearity = analog_set_linear_mode(p, idx, 0);
/*
* We are the only party interested in the Rx stream since
@@ -2322,25 +2346,27 @@ static void *__analog_ss_thread(void *data)
ast_hangup(chan);
goto quit;
}
- if (!(f = ast_read(chan))) {
+ f = ast_read(chan);
+ if (!f) {
break;
}
if (f->frametype == AST_FRAME_DTMF) {
- if (i < ARRAY_LEN(dtmfbuf) - 1) {
- dtmfbuf[i++] = f->subclass.integer;
+ if (k < ARRAY_LEN(dtmfbuf) - 1) {
+ dtmfbuf[k++] = f->subclass.integer;
}
ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
res = 4000;/* This is a typical OFF time between rings. */
}
ast_frfree(f);
- if (chan->_state == AST_STATE_RING || chan->_state == AST_STATE_RINGING) {
+ if (chan->_state == AST_STATE_RING ||
+ chan->_state == AST_STATE_RINGING) {
break; /* Got ring */
}
}
ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
- dtmfbuf[i] = '\0';
+ dtmfbuf[k] = '\0';
- analog_set_linear_mode(p, index, oldlinearity);
+ analog_set_linear_mode(p, idx, oldlinearity);
/* Got cid and ring. */
ast_debug(1, "CID got string '%s'\n", dtmfbuf);
@@ -2421,7 +2447,7 @@ static void *__analog_ss_thread(void *data)
break; /* Got ring */
}
- if (analog_distinctive_ring(chan, p, index, NULL)) {
+ if (analog_distinctive_ring(chan, p, idx, NULL)) {
goto quit;
}
@@ -2431,7 +2457,6 @@ static void *__analog_ss_thread(void *data)
} else {
ast_log(LOG_WARNING, "Unable to get caller ID space\n");
}
-
} else {
ast_log(LOG_WARNING, "Channel %s in prering "
"state, but I have nothing to do. "
@@ -2495,7 +2520,7 @@ static void *__analog_ss_thread(void *data)
analog_stop_cid_detect(p);
- if (analog_distinctive_ring(chan, p, index, curRingData)) {
+ if (analog_distinctive_ring(chan, p, idx, curRingData)) {
goto quit;
}
@@ -2533,12 +2558,15 @@ static void *__analog_ss_thread(void *data)
ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", analog_sigtype_to_str(p->sig), p->channel);
break;
}
- res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
+ res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
}
ast_hangup(chan);
quit:
+ if (smdi_msg) {
+ ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
+ }
analog_decrease_ss_count(p);
return NULL;
}
@@ -2554,19 +2582,19 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
{
int res, x;
int mysig;
- enum analog_sub index;
+ enum analog_sub idx;
char *c;
pthread_t threadid;
- pthread_attr_t attr;
struct ast_channel *chan;
struct ast_frame *f;
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
- index = analog_get_index(ast, p, 0);
- if (index < 0) {
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
+
+ idx = analog_get_index(ast, p, 0);
+ if (idx < 0) {
return &ast_null_frame;
}
- if (index != ANALOG_SUB_REAL) {
+ if (idx != ANALOG_SUB_REAL) {
ast_log(LOG_ERROR, "We got an event on a non real sub. Fix it!\n");
}
@@ -2575,27 +2603,27 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
mysig = p->outsigmod;
}
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass.integer = 0;
- p->subs[index].f.datalen = 0;
- p->subs[index].f.samples = 0;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = 0;
- p->subs[index].f.src = "dahdi_handle_event";
- p->subs[index].f.data.ptr = NULL;
- f = &p->subs[index].f;
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.subclass.integer = 0;
+ p->subs[idx].f.datalen = 0;
+ p->subs[idx].f.samples = 0;
+ p->subs[idx].f.mallocd = 0;
+ p->subs[idx].f.offset = 0;
+ p->subs[idx].f.src = "dahdi_handle_event";
+ p->subs[idx].f.data.ptr = NULL;
+ f = &p->subs[idx].f;
res = analog_get_event(p);
- ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, index);
+ ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, idx);
if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) {
analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0);
ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
analog_confmute(p, 0);
- p->subs[index].f.frametype = AST_FRAME_DTMF_END;
- p->subs[index].f.subclass.integer = res & 0xff;
- analog_handle_dtmfup(p, ast, index, &f);
+ p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
+ p->subs[idx].f.subclass.integer = res & 0xff;
+ analog_handle_dtmfup(p, ast, idx, &f);
return f;
}
@@ -2603,8 +2631,8 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
/* Mute conference */
analog_confmute(p, 1);
- p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
- p->subs[index].f.subclass.integer = res & 0xff;
+ p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN;
+ p->subs[idx].f.subclass.integer = res & 0xff;
return f;
}
@@ -2636,7 +2664,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
if (p->inalarm) {
break;
}
- x = analog_is_dialing(p, index);
+ x = analog_is_dialing(p, idx);
if (!x) { /* if not still dialing in driver */
analog_set_echocanceller(p, 1);
if (p->echobreak) {
@@ -2651,8 +2679,8 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
/* if thru with dialing after offhook */
if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
ast_setstate(ast, AST_STATE_UP);
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_ANSWER;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
break;
} else { /* if to state wait for offhook to dial rest */
/* we now wait for off hook */
@@ -2660,12 +2688,20 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
}
}
if (ast->_state == AST_STATE_DIALING) {
- if (analog_check_confirmanswer(p) || (!p->dialednone && ((mysig == ANALOG_SIG_EM) || (mysig == ANALOG_SIG_EM_E1) || (mysig == ANALOG_SIG_EMWINK) || (mysig == ANALOG_SIG_FEATD) || (mysig == ANALOG_SIG_FEATDMF_TA) || (mysig == ANALOG_SIG_FEATDMF) || (mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF) || (mysig == ANALOG_SIG_FEATB) || (mysig == ANALOG_SIG_SF) || (mysig == ANALOG_SIG_SFWINK) || (mysig == ANALOG_SIG_SF_FEATD) || (mysig == ANALOG_SIG_SF_FEATDMF) || (mysig == ANALOG_SIG_SF_FEATB)))) {
+ if (analog_check_confirmanswer(p) || (!p->dialednone
+ && ((mysig == ANALOG_SIG_EM) || (mysig == ANALOG_SIG_EM_E1)
+ || (mysig == ANALOG_SIG_EMWINK) || (mysig == ANALOG_SIG_FEATD)
+ || (mysig == ANALOG_SIG_FEATDMF_TA) || (mysig == ANALOG_SIG_FEATDMF)
+ || (mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA)
+ || (mysig == ANALOG_SIG_FGC_CAMAMF) || (mysig == ANALOG_SIG_FEATB)
+ || (mysig == ANALOG_SIG_SF) || (mysig == ANALOG_SIG_SFWINK)
+ || (mysig == ANALOG_SIG_SF_FEATD) || (mysig == ANALOG_SIG_SF_FEATDMF)
+ || (mysig == ANALOG_SIG_SF_FEATB)))) {
ast_setstate(ast, AST_STATE_RINGING);
} else if (!p->answeronpolarityswitch) {
ast_setstate(ast, AST_STATE_UP);
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_ANSWER;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
/* If aops=0 and hops=1, this is necessary */
p->polarity = POLARITY_REV;
} else {
@@ -2679,7 +2715,6 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
case ANALOG_EVENT_ALARM:
analog_set_alarm(p, 1);
analog_get_and_handle_alarms(p);
-
case ANALOG_EVENT_ONHOOK:
switch (p->sig) {
case ANALOG_SIG_FXOLS:
@@ -2690,7 +2725,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
p->onhooktime = time(NULL);
p->msgstate = -1;
/* Check for some special conditions regarding call waiting */
- if (index == ANALOG_SUB_REAL) {
+ if (idx == ANALOG_SUB_REAL) {
/* The normal line was hung up */
if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
/* Need to hold the lock for real-call, private, and call-waiting call */
@@ -2788,7 +2823,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
}
}
} else {
- ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
+ ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx);
}
/* Fall through */
default:
@@ -2830,7 +2865,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
return NULL;
}
analog_set_dialing(p, 1);
- return &p->subs[index].f;
+ return &p->subs[idx].f;
}
switch (p->sig) {
case ANALOG_SIG_FXOLS:
@@ -2841,8 +2876,8 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
case AST_STATE_RINGING:
analog_set_echocanceller(p, 1);
analog_train_echocanceller(p);
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_ANSWER;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
/* Make sure it stops ringing */
analog_set_needringing(p, 0);
analog_off_hook(p);
@@ -2852,8 +2887,8 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
p->callwaitcas = 0;
if (analog_check_confirmanswer(p)) {
/* Ignore answer if "confirm answer" is enabled */
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass.integer = 0;
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.subclass.integer = 0;
} else if (!ast_strlen_zero(p->dop.dialstr)) {
/* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
@@ -2863,8 +2898,8 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
return NULL;
} else {
ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass.integer = 0;
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.subclass.integer = 0;
analog_set_dialing(p, 1);
}
p->dop.dialstr[0] = '\0';
@@ -2873,14 +2908,14 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
ast_setstate(ast, AST_STATE_UP);
analog_answer_polarityswitch(p);
}
- return &p->subs[index].f;
+ return &p->subs[idx].f;
case AST_STATE_DOWN:
ast_setstate(ast, AST_STATE_RING);
ast->rings = 1;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_OFFHOOK;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK;
ast_debug(1, "channel %d picked up\n", p->channel);
- return &p->subs[index].f;
+ return &p->subs[idx].f;
case AST_STATE_UP:
/* Make sure it stops ringing */
analog_off_hook(p);
@@ -2931,19 +2966,19 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
case AST_STATE_DOWN:
case AST_STATE_RING:
ast_debug(1, "Ring detected\n");
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_RING;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_RING;
break;
case AST_STATE_RINGING:
case AST_STATE_DIALING:
if (p->outgoing) {
ast_debug(1, "Line answered\n");
if (analog_check_confirmanswer(p)) {
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass.integer = 0;
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.subclass.integer = 0;
} else {
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_ANSWER;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
ast_setstate(ast, AST_STATE_UP);
}
break;
@@ -2983,20 +3018,16 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
analog_cancel_cidspill(p);
p->callwaitcas = 0;
}
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass.integer = AST_CONTROL_RINGING;
+ p->subs[idx].f.frametype = AST_FRAME_CONTROL;
+ p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING;
break;
case ANALOG_EVENT_RINGERON:
break;
case ANALOG_EVENT_NOALARM:
analog_set_alarm(p, 0);
- if (!p->unknown_alarm) {
- ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
- manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
- "Channel: %d\r\n", p->channel);
- } else {
- p->unknown_alarm = 0;
- }
+ ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
+ manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
+ "Channel: %d\r\n", p->channel);
break;
case ANALOG_EVENT_WINKFLASH:
if (p->inalarm) {
@@ -3009,12 +3040,12 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
case ANALOG_SIG_FXOGS:
case ANALOG_SIG_FXOKS:
ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
- index, analog_get_sub_fd(p, ANALOG_SUB_REAL), analog_get_sub_fd(p, ANALOG_SUB_CALLWAIT), analog_get_sub_fd(p, ANALOG_SUB_THREEWAY));
+ idx, analog_get_sub_fd(p, ANALOG_SUB_REAL), analog_get_sub_fd(p, ANALOG_SUB_CALLWAIT), analog_get_sub_fd(p, ANALOG_SUB_THREEWAY));
p->callwaitcas = 0;
- if (index != ANALOG_SUB_REAL) {
- ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
+ if (idx != ANALOG_SUB_REAL) {
+ ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel);
goto winkflashdone;
}
@@ -3119,9 +3150,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
}
p->ss_astchan = p->owner = chan;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create(&threadid, &attr, __analog_ss_thread, p)) {
+ if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p)) {
ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
analog_set_echocanceller(p, 1);
@@ -3136,7 +3165,6 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
}
}
- pthread_attr_destroy(&attr);
}
} else {
/* Already have a 3 way call */
@@ -3261,12 +3289,14 @@ winkflashdone:
p->dop.dialstr[0] = '\0';
break;
default:
- ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
+ ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
}
break;
case ANALOG_EVENT_HOOKCOMPLETE:
if (p->inalarm) break;
- if (analog_check_waitingfordt(p)) break;
+ if (analog_check_waitingfordt(p)) {
+ break;
+ }
switch (mysig) {
case ANALOG_SIG_FXSLS: /* only interesting for FXS */
case ANALOG_SIG_FXSGS:
@@ -3307,17 +3337,16 @@ winkflashdone:
break;
case ANALOG_EVENT_POLARITY:
/*
- * If we get a Polarity Switch event, this could be
- * due to line seizure, remote end connect or remote end disconnect.
- *
- * Check to see if we should change the polarity state and
+ * If we get a Polarity Switch event, this could be
+ * due to line seizure, remote end connect or remote end disconnect.
+ *
+ * Check to see if we should change the polarity state and
* mark the channel as UP or if this is an indication
* of remote end disconnect.
*/
if (p->polarityonanswerdelay > 0) {
/* check if event is not too soon after OffHook or Answer */
-
if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
switch (ast->_state) {
case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */
@@ -3333,6 +3362,7 @@ winkflashdone:
ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel);
}
break;
+
case AST_STATE_UP: /*!< Line is up */
case AST_STATE_RING: /*!< Line is ringing */
if (p->hanguponpolarityswitch) {
@@ -3354,6 +3384,7 @@ winkflashdone:
if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
ast_debug(1, "Ignoring Polarity switch on channel %d, state %d\n", p->channel, ast->_state);
}
+ break;
}
} else {
@@ -3377,6 +3408,7 @@ winkflashdone:
if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %d\n", p->channel, ast->_state);
}
+ break;
}
}
}
@@ -3387,31 +3419,31 @@ winkflashdone:
default:
ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
}
- return &p->subs[index].f;
+ return &p->subs[idx].f;
}
struct ast_frame *analog_exception(struct analog_pvt *p, struct ast_channel *ast)
{
int res;
- int index;
+ int idx;
struct ast_frame *f;
- ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
+ ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
- index = analog_get_index(ast, p, 1);
- if (index < 0) {
- index = ANALOG_SUB_REAL;
+ idx = analog_get_index(ast, p, 1);
+ if (idx < 0) {
+ idx = ANALOG_SUB_REAL;
}
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.datalen = 0;
- p->subs[index].f.samples = 0;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = 0;
- p->subs[index].f.subclass.integer = 0;
- p->subs[index].f.delivery = ast_tv(0,0);
- p->subs[index].f.src = "dahdi_exception";
- p->subs[index].f.data.ptr = NULL;
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.datalen = 0;
+ p->subs[idx].f.samples = 0;
+ p->subs[idx].f.mallocd = 0;
+ p->subs[idx].f.offset = 0;
+ p->subs[idx].f.subclass.integer = 0;
+ p->subs[idx].f.delivery = ast_tv(0,0);
+ p->subs[idx].f.src = "dahdi_exception";
+ p->subs[idx].f.data.ptr = NULL;
if (!p->owner) {
/* If nobody owns us, absorb the event appropriately, otherwise
@@ -3487,14 +3519,14 @@ struct ast_frame *analog_exception(struct analog_pvt *p, struct ast_channel *ast
ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res));
break;
}
- f = &p->subs[index].f;
+ f = &p->subs[idx].f;
return f;
}
ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
/* If it's not us, return NULL immediately */
if (ast != p->owner) {
ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
- f = &p->subs[index].f;
+ f = &p->subs[idx].f;
return f;
}
f = __analog_handle_event(p, ast);
@@ -3592,15 +3624,15 @@ void *analog_handle_init_event(struct analog_pvt *i, int event)
chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL);
}
i->ss_astchan = chan;
- if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
+ if (!chan) {
+ ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
+ } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
}
ast_hangup(chan);
- } else if (!chan) {
- ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
}
break;
default:
@@ -3614,18 +3646,13 @@ void *analog_handle_init_event(struct analog_pvt *i, int event)
break;
case ANALOG_EVENT_NOALARM:
analog_set_alarm(i, 0);
- if (!i->unknown_alarm) {
- ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
- manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
- "Channel: %d\r\n", i->channel);
- } else {
- i->unknown_alarm = 0;
- }
+ ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
+ manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
+ "Channel: %d\r\n", i->channel);
break;
case ANALOG_EVENT_ALARM:
analog_set_alarm(i, 1);
analog_get_and_handle_alarms(i);
-
/* fall thru intentionally */
case ANALOG_EVENT_ONHOOK:
/* Back on hook. Hang up. */
@@ -3634,6 +3661,7 @@ void *analog_handle_init_event(struct analog_pvt *i, int event)
case ANALOG_SIG_FXOGS:
i->fxsoffhookstate = 0;
analog_start_polarityswitch(i);
+ /* Fall through */
case ANALOG_SIG_FEATD:
case ANALOG_SIG_FEATDMF:
case ANALOG_SIG_FEATDMF_TA:
@@ -3686,15 +3714,16 @@ void *analog_handle_init_event(struct analog_pvt *i, int event)
if (i->hanguponpolarityswitch) {
i->polarity = POLARITY_REV;
}
-
if (i->cid_start == ANALOG_CID_START_POLARITY || i->cid_start == ANALOG_CID_START_POLARITY_IN) {
i->polarity = POLARITY_REV;
- ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
- "CID detection on channel %d\n",
- i->channel);
+ ast_verb(2, "Starting post polarity "
+ "CID detection on channel %d\n",
+ i->channel);
chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
i->ss_astchan = chan;
- if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
+ if (!chan) {
+ ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
+ } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
}
}
@@ -3703,31 +3732,35 @@ void *analog_handle_init_event(struct analog_pvt *i, int event)
ast_log(LOG_WARNING, "handle_init_event detected "
"polarity reversal on non-FXO (ANALOG_SIG_FXS) "
"interface %d\n", i->channel);
+ break;
}
break;
case ANALOG_EVENT_DTMFCID:
switch (i->sig) {
- case ANALOG_SIG_FXSLS:
- case ANALOG_SIG_FXSKS:
- case ANALOG_SIG_FXSGS:
- if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
- ast_verbose(VERBOSE_PREFIX_2 "Starting DTMF CID detection on channel %d\n",
- i->channel);
- chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
- i->ss_astchan = chan;
- if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
- ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
- }
+ case ANALOG_SIG_FXSLS:
+ case ANALOG_SIG_FXSKS:
+ case ANALOG_SIG_FXSGS:
+ if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
+ ast_verb(2, "Starting DTMF CID detection on channel %d\n",
+ i->channel);
+ chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
+ i->ss_astchan = chan;
+ if (!chan) {
+ ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
+ } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
+ ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
}
- break;
- default:
- ast_log(LOG_WARNING, "handle_init_event detected "
- "dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) "
- "interface %d\n", i->channel);
+ }
+ break;
+ default:
+ ast_log(LOG_WARNING, "handle_init_event detected "
+ "dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) "
+ "interface %d\n", i->channel);
+ break;
}
break;
case ANALOG_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
- ast_log(LOG_NOTICE, "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
+ ast_log(LOG_NOTICE, "Got ANALOG_EVENT_REMOVED. Destroying channel %d\n",
i->channel);
return i->chan_pvt;
case ANALOG_EVENT_NEONMWI_ACTIVE:
@@ -3791,7 +3824,7 @@ int analog_config_complete(struct analog_pvt *p)
void analog_free(struct analog_pvt *p)
{
- free(p);
+ ast_free(p);
}
/* called while dahdi_pvt is locked in dahdi_fixup */
@@ -3822,12 +3855,12 @@ int analog_dnd(struct analog_pvt *p, int flag)
p->dnd = flag;
ast_verb(3, "%s DND on channel %d\n",
- flag? "Enabled" : "Disabled",
+ flag ? "Enabled" : "Disabled",
p->channel);
manager_event(EVENT_FLAG_SYSTEM, "DNDState",
"Channel: DAHDI/%d\r\n"
"Status: %s\r\n", p->channel,
- flag? "enabled" : "disabled");
+ flag ? "enabled" : "disabled");
return 0;
}
diff --git a/channels/sig_analog.h b/channels/sig_analog.h
index b58b0985a..3c33aebf0 100644
--- a/channels/sig_analog.h
+++ b/channels/sig_analog.h
@@ -27,7 +27,9 @@
#include "asterisk/channel.h"
#include "asterisk/frame.h"
+#include "asterisk/smdi.h"
+#define ANALOG_SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
#define ANALOG_MAX_CID 300
#define READ_SIZE 160
#define RING_PATTERNS 3
@@ -276,13 +278,13 @@ struct analog_pvt {
unsigned int transfertobusy:1; /*!< allow flash-transfers to busy channels */
unsigned int use_callerid:1; /*!< Whether or not to use caller id on this channel */
unsigned int callwaitingcallerid:1;
- const struct ast_channel_tech *chan_tech;
/*!
- * \brief TRUE if distinctive rings are to be detected.
- * \note For FXO lines
- * \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
- */
- unsigned int usedistinctiveringdetection:1;
+ * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
+ */
+ unsigned int use_smdi:1;
+ /*! \brief The SMDI interface to get SMDI messages from. */
+ struct ast_smdi_interface *smdi_iface;
+ const struct ast_channel_tech *chan_tech;
/* Not used for anything but log messages. Could be just the TCID */
int channel; /*!< Channel Number */
@@ -329,7 +331,6 @@ struct analog_pvt {
/* All variables after this are definitely going to be audited */
unsigned int inalarm:1;
- unsigned int unknown_alarm:1;
int callwaitcas;