62 #define POLARITY_IDLE 0
63 #define POLARITY_REV 1
64 #define MIN_MS_SINCE_FLASH ( (2000) )
107 #define ISTRUNK(p) ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \
108 (p->sig == ANALOG_SIG_FXSGS))
219 #define gen_analog_field_callback(type, callback_name, def_value) \
220 static type analog_get_##callback_name(struct analog_pvt *p) \
222 if (!analog_callbacks.get_##callback_name) { \
225 return analog_callbacks.get_##callback_name(p->chan_pvt); \
232 #undef gen_analog_field_callback
236 if (!strcasecmp(
value,
"ring")) {
238 }
else if (!strcasecmp(
value,
"polarity")) {
240 }
else if (!strcasecmp(
value,
"polarity_in")) {
242 }
else if (!strcasecmp(
value,
"dtmf")) {
257 return "Polarity_In";
270 res =
"ANALOG_EVENT_ONHOOK";
273 res =
"ANALOG_EVENT_RINGOFFHOOK";
276 res =
"ANALOG_EVENT_WINKFLASH";
279 res =
"ANALOG_EVENT_ALARM";
282 res =
"ANALOG_EVENT_NOALARM";
285 res =
"ANALOG_EVENT_DIALCOMPLETE";
288 res =
"ANALOG_EVENT_HOOKCOMPLETE";
291 res =
"ANALOG_EVENT_PULSE_START";
294 res =
"ANALOG_EVENT_POLARITY";
297 res =
"ANALOG_EVENT_RINGBEGIN";
300 res =
"ANALOG_EVENT_EC_DISABLED";
303 res =
"ANALOG_EVENT_RINGERON";
306 res =
"ANALOG_EVENT_RINGEROFF";
309 res =
"ANALOG_EVENT_REMOVED";
312 res =
"ANALOG_EVENT_NEONMWI_ACTIVE";
315 res =
"ANALOG_EVENT_NEONMWI_INACTIVE";
317 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
319 res =
"ANALOG_EVENT_TX_CED_DETECTED";
322 res =
"ANALOG_EVENT_RX_CED_DETECTED";
325 res =
"ANALOG_EVENT_EC_NLP_DISABLED";
328 res =
"ANALOG_EVENT_EC_NLP_ENABLED";
332 res =
"ANALOG_EVENT_PULSEDIGIT";
335 res =
"ANALOG_EVENT_DTMFDOWN";
338 res =
"ANALOG_EVENT_DTMFUP";
341 res =
"UNKNOWN/OTHER";
393 ast_debug(1,
"Sending callerid. CID_NAME: '%s' CID_NUM: '%s'\n",
407 #define analog_get_index(ast, p, nullok) _analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
421 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
448 p->
owner = new_owner;
720 ast_verb(3,
"TRANSFERRING %s to %s\n",
749 for (
x = 0;
x < 3;
x++) {
762 ast_debug(1,
"Updated conferencing on %d, with %d conference users\n", p->
channel, needconf);
814 #ifdef DAHDI_CHECK_HOOKSTATE
821 }
else if (offhook) {
991 ast_debug(1,
"CALLING CID_NAME: %s CID_NUM:: %s\n",
1020 if (p->
owner == ast) {
1028 c = strchr(dest,
'/');
1043 ast_debug(1,
"FXO: setup deferred dialstring: %s\n",
c);
1122 ast_debug(1,
"Ignore possible polarity reversal on line seizure\n");
1141 c = strchr(dest,
'/');
1153 if (
errno != EINPROGRESS) {
1181 const char *cic =
"", *ozz =
"";
1195 ast_log(
LOG_WARNING,
"Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
1280 ast_debug(1,
"Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
1290 ast_debug(1,
"Normal call hung up with both three way call and a call waiting call in place?\n");
1293 ast_debug(1,
"We were flipped over to the callwait, moving back and not owning.\n");
1300 ast_debug(1,
"We were in the threeway and have a callwait still. Ditching the threeway.\n");
1306 ast_debug(1,
"Call was complete, setting owner to former third call\n");
1311 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
1340 ast_debug(1,
"Call was complete, setting owner to former third call\n");
1345 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
1509 ast_debug(1,
"Finally swapping real and threeway\n");
1570 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
1587 *dest = &p->
subs[idx].
f;
1591 ast_debug(1,
"Got some DTMF, but it's for the CAS\n");
1602 *dest = &p->
subs[idx].
f;
1622 if (strchr(term,
c)) {
1686 #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))
1690 int extlen = strlen(
exten);
1694 if (extlen < strlen(pickupexten) && !strncmp(pickupexten,
exten, extlen)) {
1698 if (
exten[0] ==
'*' && extlen < 3) {
1734 const char *pickupexten;
1768 ast_log(
LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
1771 pickupexten =
ast_strdupa(pickup_cfg->pickupexten);
1806 memset(dtmfbuf, 0,
sizeof(dtmfbuf));
1851 && (strlen(dtmfbuf) != 14)) {
1899 dtmfbuf[
len] =
'\0';
1902 timeout = analog_get_matchdigit_timeout(p);
1904 timeout = analog_get_interdigit_timeout(p);
1908 ast_debug(1,
"waitfordigit returned < 0...\n");
1912 dtmfbuf[
len++] = res;
1913 dtmfbuf[
len] =
'\0';
1925 }
else if (res < 0) {
1926 ast_debug(1,
"Got hung up before digits finished\n");
1949 ast_debug(1,
"cnoffset: %d\n", cnoffset);
1958 ast_debug(1,
"Sent wink to signal ANI start\n");
1970 if ((res > 0) || (strlen(anibuf) >= 2)) {
1971 char anistart[2] =
"X";
1973 if (strchr(
"#ABC", anibuf[strlen(anibuf) - 1])) {
1974 anistart[0] = anibuf[strlen(anibuf) - 1];
1975 anibuf[strlen(anibuf) - 1] = 0;
1981 caller->
ani2 = atoi(f);
1983 anibuf[cnoffset] = 0;
1999 if (
exten[0] ==
'*') {
2004 s1 =
strsep(&stringp,
"*");
2005 s2 =
strsep(&stringp,
"*");
2021 if (
exten[0] ==
'*') {
2028 s1 =
strsep(&stringp,
"#");
2029 s2 =
strsep(&stringp,
"#");
2046 caller->
ani2 = atoi(s1);
2052 if (
exten[0] ==
'*') {
2057 s1 =
strsep(&stringp,
"#");
2058 s2 =
strsep(&stringp,
"#");
2059 if (s2 && (*(s2 + 1) ==
'0')) {
2070 ast_log(
LOG_WARNING,
"A KP was expected to start signaling for Feature Group C CAMA-MF, but we got something else. Received: %s on channel %d\n",
exten, p->
channel);
2074 if (
exten[0] ==
'*') {
2079 s1 =
strsep(&stringp,
"#");
2082 ast_log(
LOG_WARNING,
"A KP was expected to start signaling for Feature Group B, but we got something else. Received: %s on channel %d\n",
exten, p->
channel);
2133 timeout = analog_get_firstdigit_timeout(p);
2140 int is_exten_parking = 0;
2151 ast_debug(1,
"waitfordigit returned < 0...\n");
2156 ast_debug(1,
"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
2214 timeout = analog_get_matchdigit_timeout(p);
2216 }
else if (res == 0) {
2217 ast_debug(1,
"not enough digits (and no ambiguous match)...\n");
2233 timeout = analog_get_firstdigit_timeout(p);
2235 }
else if (!strcmp(
exten, pickupexten)) {
2251 ast_debug(1,
"No call pickup possible...\n");
2278 timeout = analog_get_firstdigit_timeout(p);
2288 }
else if (!strcmp(
exten,
"*78")) {
2295 }
else if (!strcmp(
exten,
"*79")) {
2308 ast_verb(3,
"Cancelling call forwarding on channel %d\n", p->
channel);
2325 if (bridge_channel) {
2364 timeout = analog_get_firstdigit_timeout(p);
2365 }
else if (!strcmp(
exten,
"*0")) {
2372 if (pbridge &&
ISTRUNK(pbridge)) {
2378 "Unable to flash-hook bridged trunk from channel %s: %s\n",
2407 timeout = analog_get_interdigit_timeout(p);
2420 if (smdi_msg !=
NULL) {
2423 if (smdi_msg->
type ==
'B')
2425 else if (smdi_msg->
type ==
'N')
2477 "DTMFCID timed out waiting for ring. Exiting simple switch\n");
2506 ast_debug(1,
"CID got string '%s'\n", dtmfbuf);
2522 int timeout = 10000;
2527 struct timeval off_start;
2537 "CallerID returned with error on channel '%s'\n",
2577 "CID timed out waiting for ring. Exiting simple switch\n");
2604 "Channel %s in prering state, but I have nothing to do. Terminating simple switch, should be restarted by the actual ring.\n",
2614 int timeout = 10000;
2618 int ring_data_idx = 0;
2629 "CallerID returned with error on channel '%s'\n",
2645 "Hanging up due to polarity reversal on channel %d while detecting callerid\n",
2658 ring_data[ring_data_idx] = p->
ringt;
2739 int data_size =
sizeof(*cause_code);
2740 char *subclass =
NULL;
2763 p->
subs[idx].
f.
src =
"dahdi_handle_event";
2765 f = &p->
subs[idx].
f;
2782 ast_debug(1,
"DTMF Down '%c'\n", res & 0xff);
2798 data_size += strlen(subclass);
2800 memset(cause_code, 0, data_size);
2803 snprintf(cause_code->
code, data_size -
sizeof(*cause_code) + 1,
"ANALOG %s", subclass);
2811 ast_verb(3,
"Channel %d echo canceler disabled due to CED detection\n", p->
channel);
2814 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2816 ast_verb(3,
"Channel %d detected a CED tone towards the network.\n", p->
channel);
2819 ast_verb(3,
"Channel %d detected a CED tone from the network.\n", p->
channel);
2822 ast_verb(3,
"Channel %d echo canceler disabled its NLP.\n", p->
channel);
2825 ast_verb(3,
"Channel %d echo canceler enabled its NLP.\n", p->
channel);
2862 ast_debug(1,
"Done dialing, but waiting for progress detection before doing more...\n");
2919 ast_verb(3,
"Channel %d still has (callwait) call, ringing phone\n", p->
channel);
2931 unsigned int mssinceflash;
2940 if (p->
owner != ast) {
2948 ast_debug(1,
"Last flash was %u ms ago\n", mssinceflash);
2952 ast_debug(1,
"Looks like a bounced flash, hanging up both calls on %d\n", p->
channel);
3039 return &p->
subs[idx].
f;
3084 return &p->
subs[idx].
f;
3091 return &p->
subs[idx].
f;
3211 ast_debug(1,
"Winkflash, index: %u, normal: %d, callwait: %d, thirdcall: %d\n",
3285 ast_debug(1,
"Flash when call not up or ringing\n");
3308 "Cannot allocate new call structure on channel %d\n",
3365 ast_debug(1,
"Got flash with three way call up, dropping last call on %d\n", p->
channel);
3383 ast_verb(3,
"Building conference call with %s and %s\n",
3439 ast_log(
LOG_WARNING,
"Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA\n");
3504 ast_debug(1,
"Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->
channel);
3534 ast_debug(1,
"Ignore Answer on polarity switch, channel %d\n", p->
channel);
3547 ast_debug(1,
"Ignore Hangup on polarity switch, channel %d\n", p->
channel);
3591 ast_debug(1,
"Polarity Reversal event occured - DEBUG 2: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64
"\n", p->
channel,
ast_channel_state(ast), p->
polarity, p->
answeronpolarityswitch, p->
hanguponpolarityswitch, p->
polarityonanswerdelay,
ast_tvdiff_ms(
ast_tvnow(), p->
polaritydelaytv) );
3594 ast_debug(1,
"Dunno what to do with event %d on channel %d\n", res, p->
channel);
3596 return &p->
subs[idx].
f;
3619 p->
subs[idx].
f.
src =
"dahdi_exception";
3633 ast_debug(1,
"Restoring owner of channel %d on event %d\n", p->
channel, res);
3694 f = &p->
subs[idx].
f;
3699 if (ast != p->
owner) {
3701 f = &p->
subs[idx].
f;
3727 ast_debug(1,
"channel (%d) - signaling (%d) - event (%s)\n",
3744 if (res && (
errno == EBUSY)) {
3775 ast_log(
LOG_WARNING,
"Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->
channel);
3910 ast_verb(2,
"Starting post polarity CID detection on channel %d\n",
3925 "handle_init_event detected polarity reversal on non-FXO (ANALOG_SIG_FXS) interface %d\n",
3937 ast_verb(2,
"Starting DTMF CID detection on channel %d\n",
3952 "handle_init_event detected dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) interface %d\n",
3982 p->
sig = signallingtype;
4028 if (new_pvt->
owner == oldchan) {
4031 for (x = 0; x < 3; x++) {
4032 if (new_pvt->
subs[x].
owner == oldchan) {
4069 ast_verb(3,
"%s DND on channel %d\n",
4070 flag ?
"Enabled" :
"Disabled",
Persistent data storage (akin to *doze registry)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
@ AST_BRIDGE_TRANSFER_SUCCESS
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
void callerid_get_dtmf(char *cidstring, char *number, int *flags)
Get and parse DTMF-based callerid.
Internal Asterisk hangup causes.
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
#define AST_CAUSE_NO_ANSWER
#define AST_CAUSE_NORMAL_CLEARING
#define AST_CC_GENERIC_MONITOR_TYPE
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
static char exten[AST_MAX_EXTENSION]
struct analog_callback analog_callbacks
static char cid_num[AST_MAX_EXTENSION]
static char cid_name[AST_MAX_EXTENSION]
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_party_name_init(struct ast_party_name *init)
Initialize the given name structure.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
int ast_channel_rings(const struct ast_channel *chan)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
@ AST_SOFTHANGUP_EXPLICIT
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define ast_channel_lock(chan)
const char * ast_channel_context(const struct ast_channel *chan)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
#define ast_channel_ref(c)
Increase channel reference count.
ast_callid ast_channel_callid(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_trylock(chan)
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
void ast_party_name_free(struct ast_party_name *doomed)
Destroy the party name contents.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
int ast_channel_fd(const struct ast_channel *chan, int which)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)