#include "asterisk.h"
#include <errno.h>
#include <ctype.h>
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/say.h"
#include "asterisk/manager.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/cel.h"
#include "asterisk/causes.h"
#include "sig_analog.h"

Go to the source code of this file.
Defines | |
| #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)) |
| #define | ISTRUNK(p) |
| #define | MIN_MS_SINCE_FLASH ( (2000) ) |
| #define | POLARITY_IDLE 0 |
| #define | POLARITY_REV 1 |
Functions | |
| static struct ast_frame * | __analog_handle_event (struct analog_pvt *p, struct ast_channel *ast) |
| static void * | __analog_ss_thread (void *data) |
| static void | analog_all_subchannels_hungup (struct analog_pvt *p) |
| static int | analog_alloc_sub (struct analog_pvt *p, enum analog_sub x) |
| int | analog_answer (struct analog_pvt *p, struct ast_channel *ast) |
| static int | analog_attempt_transfer (struct analog_pvt *p) |
| int | analog_available (struct analog_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched) |
| int | analog_call (struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout) |
| static int | analog_callwait (struct analog_pvt *p) |
| static void | analog_cancel_cidspill (struct analog_pvt *p) |
| static void | analog_cb_handle_dtmfup (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest) |
| static int | analog_check_confirmanswer (struct analog_pvt *p) |
| static int | analog_check_for_conference (struct analog_pvt *p) |
| static int | analog_check_waitingfordt (struct analog_pvt *p) |
| const char * | analog_cidstart_to_str (enum analog_cid_start cid_start) |
| const char * | analog_cidtype_to_str (unsigned int cid_type) |
| int | analog_config_complete (struct analog_pvt *p) |
| static int | analog_confmute (struct analog_pvt *p, int mute) |
| static int | analog_decrease_ss_count (struct analog_pvt *p) |
| void | analog_delete (struct analog_pvt *doomed) |
| Delete the analog private structure. | |
| static int | analog_dial_digits (struct analog_pvt *p, enum analog_sub sub, struct analog_dialoperation *dop) |
| static int | analog_distinctive_ring (struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata) |
| int | analog_dnd (struct analog_pvt *p, int flag) |
| static int | analog_dsp_reset_and_flush_digits (struct analog_pvt *p) |
| static int | analog_dsp_set_digitmode (struct analog_pvt *p, enum analog_dsp_digitmode mode) |
| static char * | analog_event2str (enum analog_event event) |
| struct ast_frame * | analog_exception (struct analog_pvt *p, struct ast_channel *ast) |
| int | analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp) |
| static int | analog_flash (struct analog_pvt *p) |
| void | analog_free (struct analog_pvt *p) |
| static void | analog_get_and_handle_alarms (struct analog_pvt *p) |
| static void * | analog_get_bridged_channel (struct analog_pvt *p, struct ast_channel *chan) |
| static int | analog_get_callerid (struct analog_pvt *p, char *name, char *number, enum analog_event *ev, size_t timeout) |
| static int | analog_get_event (struct analog_pvt *p) |
| static int | analog_get_index (struct ast_channel *ast, struct analog_pvt *p, int nullok) |
| static int | analog_get_sub_fd (struct analog_pvt *p, enum analog_sub sub) |
| void | analog_handle_dtmfup (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, struct ast_frame **dest) |
| void * | analog_handle_init_event (struct analog_pvt *i, int event) |
| static int | analog_handle_notify_message (struct ast_channel *chan, struct analog_pvt *p, int cid_flags, int neon_mwievent) |
| static int | analog_handles_digit (struct ast_frame *f) |
| int | analog_hangup (struct analog_pvt *p, struct ast_channel *ast) |
| static int | analog_has_voicemail (struct analog_pvt *p) |
| static int | analog_increase_ss_count (struct analog_pvt *p) |
| static int | analog_is_dialing (struct analog_pvt *p, enum analog_sub index) |
| static int | analog_is_off_hook (struct analog_pvt *p) |
| static void | analog_lock_private (struct analog_pvt *p) |
| static int | analog_my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
| struct analog_pvt * | analog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data) |
| static struct ast_channel * | analog_new_ast_channel (struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor) |
| static int | analog_off_hook (struct analog_pvt *p) |
| static int | analog_on_hook (struct analog_pvt *p) |
| static int | analog_play_tone (struct analog_pvt *p, enum analog_sub sub, enum analog_tone tone) |
| struct ast_channel * | analog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor) |
| static int | analog_ring (struct analog_pvt *p) |
| static int | analog_send_callerid (struct analog_pvt *p, int cwcid, struct ast_callerid *cid) |
| static void | analog_set_cadence (struct analog_pvt *p, struct ast_channel *chan) |
| static void | analog_set_confirmanswer (struct analog_pvt *p, int flag) |
| static void | analog_set_dialing (struct analog_pvt *p, int flag) |
| static int | analog_set_echocanceller (struct analog_pvt *p, int enable) |
| static int | analog_set_linear_mode (struct analog_pvt *p, int index, int linear_mode) |
| static void | analog_set_pulsedial (struct analog_pvt *p, int flag) |
| static void | analog_set_ringtimeout (struct analog_pvt *p, int ringt) |
| static void | analog_set_waitingfordt (struct analog_pvt *p, struct ast_channel *ast) |
| const char * | analog_sigtype_to_str (enum analog_sigtype sigtype) |
| int | analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *chan) |
| static int | analog_start (struct analog_pvt *p) |
| static int | analog_start_cid_detect (struct analog_pvt *p, int cid_signalling) |
| static int | analog_stop_callwait (struct analog_pvt *p) |
| static int | analog_stop_cid_detect (struct analog_pvt *p) |
| enum analog_cid_start | analog_str_to_cidstart (const char *value) |
| unsigned int | analog_str_to_cidtype (const char *name) |
| enum analog_sigtype | analog_str_to_sigtype (const char *name) |
| static void | analog_swap_subs (struct analog_pvt *p, enum analog_sub a, enum analog_sub b) |
| static int | analog_train_echocanceller (struct analog_pvt *p) |
| static int | analog_unalloc_sub (struct analog_pvt *p, enum analog_sub x) |
| static void | analog_unlock_private (struct analog_pvt *p) |
| static int | analog_update_conf (struct analog_pvt *p) |
| static int | analog_wait_event (struct analog_pvt *p) |
| static int | analog_wink (struct analog_pvt *p, enum analog_sub index) |
Variables | |
| static char | analog_defaultcic [64] = "" |
| static char | analog_defaultozz [64] = "" |
| static int | analog_firstdigittimeout = 16000 |
| static int | analog_gendigittimeout = 8000 |
| static int | analog_matchdigittimeout = 3000 |
| struct { | |
| unsigned int cid_type | |
| const char const * name | |
| } | cidtypes [] |
| struct { | |
| const char const * name | |
| enum analog_sigtype sigtype | |
| } | sigtypes [] |
Definition in file sig_analog.c.
| #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)) |
| #define ISTRUNK | ( | p | ) |
Value:
((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \ (p->sig == ANALOG_SIG_FXSGS))
Definition at line 93 of file sig_analog.c.
| #define MIN_MS_SINCE_FLASH ( (2000) ) |
2000 ms
Definition at line 47 of file sig_analog.c.
| #define POLARITY_IDLE 0 |
Definition at line 45 of file sig_analog.c.
| #define POLARITY_REV 1 |
Definition at line 46 of file sig_analog.c.
| static struct ast_frame* __analog_handle_event | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) | [static, read] |
< Digits (or equivalent) have been dialed
< Remote end is ringing
< Line is up
< Line is ringing
< Channel is down and available
< Channel is down, but reserved
< Channel is off hook
< Line is busy
< Digits (or equivalent) have been dialed while offhook
< Channel has detected an incoming call and is waiting for ring
< Digits (or equivalent) have been dialed
< Remote end is ringing
< Line is up
< Line is ringing
Definition at line 2339 of file sig_analog.c.
References __analog_ss_thread(), ast_channel::_state, analog_alloc_sub(), analog_attempt_transfer(), analog_cancel_cidspill(), analog_check_confirmanswer(), analog_check_for_conference(), analog_check_waitingfordt(), analog_confmute(), analog_dial_digits(), ANALOG_DIAL_OP_REPLACE, analog_event2str(), ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, ANALOG_EVENT_WINKFLASH, analog_get_and_handle_alarms(), analog_get_event(), analog_get_index(), analog_get_sub_fd(), analog_handle_dtmfup(), analog_has_voicemail(), analog_is_dialing(), analog_lock_private(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_dialing(), analog_set_echocanceller(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_RINGTONE, ANALOG_TONE_STUTTER, analog_train_echocanceller(), analog_unalloc_sub(), analog_unlock_private(), analog_update_conf(), analog_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CAUSE_NO_ANSWER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup_with_cause(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, analog_pvt::callwaitcas, ast_channel::cdr, chan, analog_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::cid, analog_pvt::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, analog_pvt::cid_name, ast_callerid::cid_name, cid_name, analog_pvt::cid_num, ast_callerid::cid_num, cid_num, analog_pvt::cidrings, analog_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, analog_pvt::dialdest, analog_pvt::dialednone, analog_pvt::dialing, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, EVENT_FLAG_SYSTEM, analog_subchannel::f, f, analog_pvt::finaldial, analog_pvt::flashtime, ast_frame::frametype, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, analog_pvt::inalarm, analog_subchannel::inthreeway, ast_channel::linkedid, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event, MIN_MS_SINCE_FLASH, analog_pvt::mohsuggest, analog_pvt::msgstate, ast_channel::name, ast_frame::offset, analog_pvt::onhooktime, analog_dialoperation::op, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::outgoing, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, ast_channel::pbx, analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, analog_pvt::polaritydelaytv, analog_pvt::polarityonanswerdelay, ast_frame::ptr, ast_channel::rings, analog_pvt::ringt_base, S_OR, ast_frame::samples, analog_pvt::sig, ast_frame::src, analog_pvt::ss_astchan, ast_frame::subclass, analog_pvt::subs, analog_pvt::threewaycalling, analog_pvt::transfer, analog_pvt::transfertobusy, analog_pvt::unknown_alarm, and analog_pvt::whichwink.
Referenced by analog_exception().
02340 { 02341 int res, x; 02342 int mysig; 02343 enum analog_sub index; 02344 char *c; 02345 pthread_t threadid; 02346 pthread_attr_t attr; 02347 struct ast_channel *chan; 02348 struct ast_frame *f; 02349 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 02350 02351 index = analog_get_index(ast, p, 0); 02352 mysig = p->sig; 02353 if (p->outsigmod > -1) { 02354 mysig = p->outsigmod; 02355 } 02356 p->subs[index].f.frametype = AST_FRAME_NULL; 02357 p->subs[index].f.subclass = 0; 02358 p->subs[index].f.datalen = 0; 02359 p->subs[index].f.samples = 0; 02360 p->subs[index].f.mallocd = 0; 02361 p->subs[index].f.offset = 0; 02362 p->subs[index].f.src = "dahdi_handle_event"; 02363 p->subs[index].f.data.ptr = NULL; 02364 f = &p->subs[index].f; 02365 02366 if (index < 0) { 02367 return &p->subs[index].f; 02368 } 02369 02370 if (index != ANALOG_SUB_REAL) { 02371 ast_log(LOG_ERROR, "We got an event on a non real sub. Fix it!\n"); 02372 } 02373 02374 res = analog_get_event(p); 02375 02376 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, index); 02377 02378 if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) { 02379 analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT)); 02380 ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff); 02381 analog_confmute(p, 0); 02382 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 02383 p->subs[index].f.subclass = res & 0xff; 02384 analog_handle_dtmfup(p, ast, index, &f); 02385 return f; 02386 } 02387 02388 if (res & ANALOG_EVENT_DTMFDOWN) { 02389 ast_debug(1, "DTMF Down '%c'\n", res & 0xff); 02390 /* Mute conference */ 02391 analog_confmute(p, 1); 02392 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 02393 p->subs[index].f.subclass = res & 0xff; 02394 return f; 02395 } 02396 02397 switch (res) { 02398 case ANALOG_EVENT_EC_DISABLED: 02399 ast_verb(3, "Channel %d echo canceler disabled due to CED detection\n", p->channel); 02400 analog_set_echocanceller(p, 0); 02401 break; 02402 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 02403 case ANALOG_EVENT_TX_CED_DETECTED: 02404 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel); 02405 break; 02406 case ANALOG_EVENT_RX_CED_DETECTED: 02407 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel); 02408 break; 02409 case ANALOG_EVENT_EC_NLP_DISABLED: 02410 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel); 02411 break; 02412 case ANALOG_EVENT_EC_NLP_ENABLED: 02413 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel); 02414 break; 02415 #endif 02416 case ANALOG_EVENT_PULSE_START: 02417 /* Stop tone if there's a pulse start and the PBX isn't started */ 02418 if (!ast->pbx) 02419 analog_play_tone(p, ANALOG_SUB_REAL, -1); 02420 break; 02421 case ANALOG_EVENT_DIALCOMPLETE: 02422 if (p->inalarm) { 02423 break; 02424 } 02425 x = analog_is_dialing(p, index); 02426 if (!x) { /* if not still dialing in driver */ 02427 analog_set_echocanceller(p, 1); 02428 if (p->echobreak) { 02429 analog_train_echocanceller(p); 02430 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 02431 p->dop.op = ANALOG_DIAL_OP_REPLACE; 02432 analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 02433 p->echobreak = 0; 02434 } else { 02435 analog_set_dialing(p, 0); 02436 if ((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) { 02437 /* if thru with dialing after offhook */ 02438 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 02439 ast_setstate(ast, AST_STATE_UP); 02440 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02441 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 02442 break; 02443 } else { /* if to state wait for offhook to dial rest */ 02444 /* we now wait for off hook */ 02445 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 02446 } 02447 } 02448 if (ast->_state == AST_STATE_DIALING) { 02449 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)))) { 02450 ast_setstate(ast, AST_STATE_RINGING); 02451 } else if (!p->answeronpolarityswitch) { 02452 ast_setstate(ast, AST_STATE_UP); 02453 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02454 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 02455 /* If aops=0 and hops=1, this is necessary */ 02456 p->polarity = POLARITY_REV; 02457 } else { 02458 /* Start clean, so we can catch the change to REV polarity when party answers */ 02459 p->polarity = POLARITY_IDLE; 02460 } 02461 } 02462 } 02463 } 02464 break; 02465 case ANALOG_EVENT_ALARM: 02466 p->inalarm = 1; 02467 analog_get_and_handle_alarms(p); 02468 02469 case ANALOG_EVENT_ONHOOK: 02470 switch (p->sig) { 02471 case ANALOG_SIG_FXOLS: 02472 case ANALOG_SIG_FXOGS: 02473 case ANALOG_SIG_FXOKS: 02474 p->fxsoffhookstate = 0; 02475 p->onhooktime = time(NULL); 02476 p->msgstate = -1; 02477 /* Check for some special conditions regarding call waiting */ 02478 if (index == ANALOG_SUB_REAL) { 02479 /* The normal line was hung up */ 02480 if (p->subs[ANALOG_SUB_CALLWAIT].owner) { 02481 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 02482 analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL); 02483 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel); 02484 analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT); 02485 analog_stop_callwait(p); 02486 p->owner = NULL; 02487 /* Don't start streaming audio yet if the incoming call isn't up yet */ 02488 if (p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) { 02489 analog_set_dialing(p, 1); 02490 } 02491 analog_ring(p); 02492 } else if (p->subs[ANALOG_SUB_THREEWAY].owner) { 02493 unsigned int mssinceflash; 02494 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 02495 the private structure -- not especially easy or clean */ 02496 while (p->subs[ANALOG_SUB_THREEWAY].owner && ast_channel_trylock(p->subs[ANALOG_SUB_THREEWAY].owner)) { 02497 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 02498 analog_unlock_private(p); 02499 CHANNEL_DEADLOCK_AVOIDANCE(ast); 02500 /* We can grab ast and p in that order, without worry. We should make sure 02501 nothing seriously bad has happened though like some sort of bizarre double 02502 masquerade! */ 02503 analog_lock_private(p); 02504 if (p->owner != ast) { 02505 ast_log(LOG_WARNING, "This isn't good...\n"); 02506 return NULL; 02507 } 02508 } 02509 if (!p->subs[ANALOG_SUB_THREEWAY].owner) { 02510 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 02511 return NULL; 02512 } 02513 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 02514 ast_debug(1, "Last flash was %d ms ago\n", mssinceflash); 02515 if (mssinceflash < MIN_MS_SINCE_FLASH) { 02516 /* It hasn't been long enough since the last flashook. This is probably a bounce on 02517 hanging up. Hangup both channels now */ 02518 if (p->subs[ANALOG_SUB_THREEWAY].owner) { 02519 ast_queue_hangup_with_cause(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER); 02520 } 02521 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02522 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 02523 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02524 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 02525 if (p->transfer) { 02526 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 02527 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 02528 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02529 /* Swap subs and dis-own channel */ 02530 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02531 p->owner = NULL; 02532 /* Ring the phone */ 02533 analog_ring(p); 02534 } else { 02535 if ((res = analog_attempt_transfer(p)) < 0) { 02536 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02537 if (p->subs[ANALOG_SUB_THREEWAY].owner) { 02538 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02539 } 02540 } else if (res) { 02541 /* this isn't a threeway call anymore */ 02542 p->subs[ANALOG_SUB_REAL].inthreeway = 0; 02543 p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0; 02544 02545 /* Don't actually hang up at this point */ 02546 if (p->subs[ANALOG_SUB_THREEWAY].owner) { 02547 ast_channel_unlock(&p->subs[ANALOG_SUB_THREEWAY].owner); 02548 } 02549 break; 02550 } 02551 } 02552 /* this isn't a threeway call anymore */ 02553 p->subs[ANALOG_SUB_REAL].inthreeway = 0; 02554 p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0; 02555 } else { 02556 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02557 if (p->subs[ANALOG_SUB_THREEWAY].owner) { 02558 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02559 } 02560 } 02561 } else { 02562 ast_cel_report_event(ast, AST_CEL_BLINDTRANSFER, NULL, ast->linkedid, NULL); 02563 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02564 /* Swap subs and dis-own channel */ 02565 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02566 p->owner = NULL; 02567 /* Ring the phone */ 02568 analog_ring(p); 02569 } 02570 } 02571 } else { 02572 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 02573 } 02574 /* Fall through */ 02575 default: 02576 analog_set_echocanceller(p, 0); 02577 return NULL; 02578 } 02579 break; 02580 case ANALOG_EVENT_RINGOFFHOOK: 02581 if (p->inalarm) { 02582 break; 02583 } 02584 /* for E911, its supposed to wait for offhook then dial 02585 the second half of the dial string */ 02586 if (((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 02587 c = strchr(p->dialdest, '/'); 02588 if (c) { 02589 c++; 02590 } else { 02591 c = p->dialdest; 02592 } 02593 if (*c) { 02594 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 02595 } else { 02596 ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 02597 } 02598 if (strlen(p->dop.dialstr) > 4) { 02599 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02600 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02601 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02602 p->echobreak = 1; 02603 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02604 } else { 02605 p->echobreak = 0; 02606 } 02607 if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { 02608 int saveerr = errno; 02609 analog_on_hook(p); 02610 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 02611 return NULL; 02612 } 02613 analog_set_dialing(p, 1); 02614 return &p->subs[index].f; 02615 } 02616 switch (p->sig) { 02617 case ANALOG_SIG_FXOLS: 02618 case ANALOG_SIG_FXOGS: 02619 case ANALOG_SIG_FXOKS: 02620 p->fxsoffhookstate = 1; 02621 switch (ast->_state) { 02622 case AST_STATE_RINGING: 02623 analog_set_echocanceller(p, 1); 02624 analog_train_echocanceller(p); 02625 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02626 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 02627 /* Make sure it stops ringing */ 02628 analog_off_hook(p); 02629 ast_debug(1, "channel %d answered\n", p->channel); 02630 analog_cancel_cidspill(p); 02631 analog_set_dialing(p, 0); 02632 p->callwaitcas = 0; 02633 if (analog_check_confirmanswer(p)) { 02634 /* Ignore answer if "confirm answer" is enabled */ 02635 p->subs[index].f.frametype = AST_FRAME_NULL; 02636 p->subs[index].f.subclass = 0; 02637 } else if (!ast_strlen_zero(p->dop.dialstr)) { 02638 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 02639 res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 02640 if (res < 0) { 02641 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 02642 p->dop.dialstr[0] = '\0'; 02643 return NULL; 02644 } else { 02645 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 02646 p->subs[index].f.frametype = AST_FRAME_NULL; 02647 p->subs[index].f.subclass = 0; 02648 analog_set_dialing(p, 1); 02649 } 02650 p->dop.dialstr[0] = '\0'; 02651 ast_setstate(ast, AST_STATE_DIALING); 02652 } else { 02653 ast_setstate(ast, AST_STATE_UP); 02654 } 02655 return &p->subs[index].f; 02656 case AST_STATE_DOWN: 02657 ast_setstate(ast, AST_STATE_RING); 02658 ast->rings = 1; 02659 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02660 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 02661 ast_debug(1, "channel %d picked up\n", p->channel); 02662 return &p->subs[index].f; 02663 case AST_STATE_UP: 02664 /* Make sure it stops ringing */ 02665 analog_off_hook(p); 02666 /* Okay -- probably call waiting*/ 02667 if (ast_bridged_channel(p->owner)) { 02668 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 02669 } 02670 break; 02671 case AST_STATE_RESERVED: 02672 /* Start up dialtone */ 02673 if (analog_has_voicemail(p)) { 02674 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER); 02675 } else { 02676 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE); 02677 } 02678 break; 02679 default: 02680 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 02681 } 02682 break; 02683 case ANALOG_SIG_FXSLS: 02684 case ANALOG_SIG_FXSGS: 02685 case ANALOG_SIG_FXSKS: 02686 if (ast->_state == AST_STATE_RING) { 02687 analog_set_ringtimeout(p, p->ringt_base); 02688 } 02689 02690 /* Fall through */ 02691 case ANALOG_SIG_EM: 02692 case ANALOG_SIG_EM_E1: 02693 case ANALOG_SIG_EMWINK: 02694 case ANALOG_SIG_FEATD: 02695 case ANALOG_SIG_FEATDMF: 02696 case ANALOG_SIG_FEATDMF_TA: 02697 case ANALOG_SIG_E911: 02698 case ANALOG_SIG_FGC_CAMA: 02699 case ANALOG_SIG_FGC_CAMAMF: 02700 case ANALOG_SIG_FEATB: 02701 case ANALOG_SIG_SF: 02702 case ANALOG_SIG_SFWINK: 02703 case ANALOG_SIG_SF_FEATD: 02704 case ANALOG_SIG_SF_FEATDMF: 02705 case ANALOG_SIG_SF_FEATB: 02706 if (ast->_state == AST_STATE_PRERING) { 02707 ast_setstate(ast, AST_STATE_RING); 02708 } 02709 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 02710 ast_debug(1, "Ring detected\n"); 02711 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02712 p->subs[index].f.subclass = AST_CONTROL_RING; 02713 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 02714 ast_debug(1, "Line answered\n"); 02715 if (analog_check_confirmanswer(p)) { 02716 p->subs[index].f.frametype = AST_FRAME_NULL; 02717 p->subs[index].f.subclass = 0; 02718 } else { 02719 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02720 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 02721 ast_setstate(ast, AST_STATE_UP); 02722 } 02723 } else if (ast->_state != AST_STATE_RING) { 02724 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 02725 } 02726 break; 02727 default: 02728 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 02729 } 02730 break; 02731 #ifdef ANALOG_EVENT_RINGBEGIN 02732 case ANALOG_EVENT_RINGBEGIN: 02733 switch (p->sig) { 02734 case ANALOG_SIG_FXSLS: 02735 case ANALOG_SIG_FXSGS: 02736 case ANALOG_SIG_FXSKS: 02737 if (ast->_state == AST_STATE_RING) { 02738 analog_set_ringtimeout(p, p->ringt_base); 02739 } 02740 break; 02741 } 02742 break; 02743 #endif 02744 case ANALOG_EVENT_RINGEROFF: 02745 if (p->inalarm) break; 02746 ast->rings++; 02747 if (ast->rings == p->cidrings) { 02748 analog_send_callerid(p, 0, &p->cid); 02749 } 02750 02751 if (ast->rings > p->cidrings) { 02752 analog_cancel_cidspill(p); 02753 p->callwaitcas = 0; 02754 } 02755 p->subs[index].f.frametype = AST_FRAME_CONTROL; 02756 p->subs[index].f.subclass = AST_CONTROL_RINGING; 02757 break; 02758 case ANALOG_EVENT_RINGERON: 02759 break; 02760 case ANALOG_EVENT_NOALARM: 02761 p->inalarm = 0; 02762 if (!p->unknown_alarm) { 02763 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 02764 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 02765 "Channel: %d\r\n", p->channel); 02766 } else { 02767 p->unknown_alarm = 0; 02768 } 02769 break; 02770 case ANALOG_EVENT_WINKFLASH: 02771 if (p->inalarm) { 02772 break; 02773 } 02774 /* Remember last time we got a flash-hook */ 02775 gettimeofday(&p->flashtime, NULL); 02776 switch (mysig) { 02777 case ANALOG_SIG_FXOLS: 02778 case ANALOG_SIG_FXOGS: 02779 case ANALOG_SIG_FXOKS: 02780 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 02781 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)); 02782 02783 p->callwaitcas = 0; 02784 02785 if (index != ANALOG_SUB_REAL) { 02786 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 02787 goto winkflashdone; 02788 } 02789 02790 if (p->subs[ANALOG_SUB_CALLWAIT].owner) { 02791 /* Swap to call-wait */ 02792 int previous_state = p->subs[ANALOG_SUB_CALLWAIT].owner->_state; 02793 if (p->subs[ANALOG_SUB_CALLWAIT].owner->_state == AST_STATE_RINGING) { 02794 ast_setstate(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_STATE_UP); 02795 } 02796 analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT); 02797 analog_play_tone(p, ANALOG_SUB_REAL, -1); 02798 p->owner = p->subs[ANALOG_SUB_REAL].owner; 02799 ast_debug(1, "Making %s the new owner\n", p->owner->name); 02800 if (previous_state == AST_STATE_RINGING) { 02801 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER); 02802 } 02803 analog_stop_callwait(p); 02804 /* Start music on hold if appropriate */ 02805 if (!p->subs[ANALOG_SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) { 02806 ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02807 S_OR(p->mohsuggest, NULL), 02808 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02809 } 02810 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER); 02811 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 02812 ast_queue_control_data(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_HOLD, 02813 S_OR(p->mohsuggest, NULL), 02814 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02815 } 02816 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 02817 } else if (!p->subs[ANALOG_SUB_THREEWAY].owner) { 02818 char cid_num[256]; 02819 char cid_name[256]; 02820 02821 if (!p->threewaycalling) { 02822 /* Just send a flash if no 3-way calling */ 02823 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_FLASH); 02824 goto winkflashdone; 02825 } else if (!analog_check_for_conference(p)) { 02826 if (p->dahditrcallerid && p->owner) { 02827 if (p->owner->cid.cid_num) { 02828 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 02829 } 02830 if (p->owner->cid.cid_name) { 02831 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 02832 } 02833 } 02834 /* XXX This section needs much more error checking!!! XXX */ 02835 /* Start a 3-way call if feasible */ 02836 if (!((ast->pbx) || 02837 (ast->_state == AST_STATE_UP) || 02838 (ast->_state == AST_STATE_RING))) { 02839 ast_debug(1, "Flash when call not up or ringing\n"); 02840 goto winkflashdone; 02841 } 02842 if (analog_alloc_sub(p, ANALOG_SUB_THREEWAY)) { 02843 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 02844 goto winkflashdone; 02845 } 02846 /* Make new channel */ 02847 chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY, NULL); 02848 if (p->dahditrcallerid) { 02849 if (!p->origcid_num) { 02850 p->origcid_num = ast_strdup(p->cid_num); 02851 } 02852 if (!p->origcid_name) { 02853 p->origcid_name = ast_strdup(p->cid_name); 02854 } 02855 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 02856 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 02857 } 02858 /* Swap things around between the three-way and real call */ 02859 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02860 /* Disable echo canceller for better dialing */ 02861 analog_set_echocanceller(p, 0); 02862 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALRECALL); 02863 if (res) { 02864 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 02865 } 02866 p->ss_astchan = p->owner = chan; 02867 pthread_attr_init(&attr); 02868 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02869 if (!chan) { 02870 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 02871 } else if (ast_pthread_create(&threadid, &attr, __analog_ss_thread, p)) { 02872 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 02873 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 02874 analog_set_echocanceller(p, 1); 02875 ast_hangup(chan); 02876 } else { 02877 struct ast_channel *other = ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner); 02878 int way3bridge = 0, cdr3way = 0; 02879 02880 if (!other) { 02881 other = ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner); 02882 } else { 02883 way3bridge = 1; 02884 } 02885 02886 if (p->subs[ANALOG_SUB_THREEWAY].owner->cdr) { 02887 cdr3way = 1; 02888 } 02889 02890 ast_verb(3, "Started three way call on channel %d\n", p->channel); 02891 /* Start music on hold if appropriate */ 02892 if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) { 02893 ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02894 S_OR(p->mohsuggest, NULL), 02895 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02896 } 02897 } 02898 pthread_attr_destroy(&attr); 02899 } 02900 } else { 02901 /* Already have a 3 way call */ 02902 if (p->subs[ANALOG_SUB_THREEWAY].inthreeway) { 02903 /* Call is already up, drop the last person */ 02904 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel); 02905 /* If the primary call isn't answered yet, use it */ 02906 if ((p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) && 02907 (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 02908 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 02909 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02910 p->owner = p->subs[ANALOG_SUB_REAL].owner; 02911 } 02912 /* Drop the last call and stop the conference */ 02913 ast_verb(3, "Dropping three-way call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name); 02914 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02915 p->subs[ANALOG_SUB_REAL].inthreeway = 0; 02916 p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0; 02917 } else { 02918 /* Lets see what we're up to */ 02919 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 02920 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 02921 int otherindex = ANALOG_SUB_THREEWAY; 02922 struct ast_channel *other = ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner); 02923 int way3bridge = 0, cdr3way = 0; 02924 02925 if (!other) { 02926 other = ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner); 02927 } else { 02928 way3bridge = 1; 02929 } 02930 02931 if (p->subs[ANALOG_SUB_THREEWAY].owner->cdr) { 02932 cdr3way = 1; 02933 } 02934 02935 ast_verb(3, "Building conference on call on %s and %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name, p->subs[ANALOG_SUB_REAL].owner->name); 02936 /* Put them in the threeway, and flip */ 02937 p->subs[ANALOG_SUB_THREEWAY].inthreeway = 1; 02938 p->subs[ANALOG_SUB_REAL].inthreeway = 1; 02939 if (ast->_state == AST_STATE_UP) { 02940 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02941 otherindex = ANALOG_SUB_REAL; 02942 } 02943 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) { 02944 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 02945 } 02946 p->owner = p->subs[ANALOG_SUB_REAL].owner; 02947 if (ast->_state == AST_STATE_RINGING) { 02948 ast_debug(1, "Enabling ringtone on real and threeway\n"); 02949 analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE); 02950 analog_play_tone(p, ANALOG_SUB_THREEWAY, ANALOG_TONE_RINGTONE); 02951 } 02952 } else { 02953 ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name); 02954 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02955 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02956 p->owner = p->subs[ANALOG_SUB_REAL].owner; 02957 if (p->subs[ANALOG_SUB_REAL].owner && ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 02958 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 02959 } 02960 analog_set_echocanceller(p, 1); 02961 } 02962 } 02963 } 02964 winkflashdone: 02965 analog_update_conf(p); 02966 break; 02967 case ANALOG_SIG_EM: 02968 case ANALOG_SIG_EM_E1: 02969 case ANALOG_SIG_FEATD: 02970 case ANALOG_SIG_SF: 02971 case ANALOG_SIG_SFWINK: 02972 case ANALOG_SIG_SF_FEATD: 02973 case ANALOG_SIG_FXSLS: 02974 case ANALOG_SIG_FXSGS: 02975 if (p->dialing) { 02976 ast_debug(1, "Ignoring wink on channel %d\n", p->channel); 02977 } else { 02978 ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 02979 } 02980 break; 02981 case ANALOG_SIG_FEATDMF_TA: 02982 switch (p->whichwink) { 02983 case 0: 02984 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 02985 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 02986 break; 02987 case 1: 02988 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 02989 break; 02990 case 2: 02991 ast_log(LOG_WARNING, "Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA\n"); 02992 return NULL; 02993 } 02994 p->whichwink++; 02995 /* Fall through */ 02996 case ANALOG_SIG_FEATDMF: 02997 case ANALOG_SIG_E911: 02998 case ANALOG_SIG_FGC_CAMAMF: 02999 case ANALOG_SIG_FGC_CAMA: 03000 case ANALOG_SIG_FEATB: 03001 case ANALOG_SIG_SF_FEATDMF: 03002 case ANALOG_SIG_SF_FEATB: 03003 case ANALOG_SIG_EMWINK: 03004 /* FGD MF and EMWINK *Must* wait for wink */ 03005 if (!ast_strlen_zero(p->dop.dialstr)) { 03006 res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 03007 if (res < 0) { 03008 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 03009 p->dop.dialstr[0] = '\0'; 03010 return NULL; 03011 } else { 03012 ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr); 03013 } 03014 } 03015 p->dop.dialstr[0] = '\0'; 03016 break; 03017 default: 03018 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 03019 } 03020 break; 03021 case ANALOG_EVENT_HOOKCOMPLETE: 03022 if (p->inalarm) break; 03023 if (analog_check_waitingfordt(p)) break; 03024 switch (mysig) { 03025 case ANALOG_SIG_FXSLS: /* only interesting for FXS */ 03026 case ANALOG_SIG_FXSGS: 03027 case ANALOG_SIG_FXSKS: 03028 case ANALOG_SIG_EM: 03029 case ANALOG_SIG_EM_E1: 03030 case ANALOG_SIG_EMWINK: 03031 case ANALOG_SIG_FEATD: 03032 case ANALOG_SIG_SF: 03033 case ANALOG_SIG_SFWINK: 03034 case ANALOG_SIG_SF_FEATD: 03035 if (!ast_strlen_zero(p->dop.dialstr)) { 03036 res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 03037 if (res < 0) { 03038 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 03039 p->dop.dialstr[0] = '\0'; 03040 return NULL; 03041 } else { 03042 ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr); 03043 } 03044 } 03045 p->dop.dialstr[0] = '\0'; 03046 p->dop.op = ANALOG_DIAL_OP_REPLACE; 03047 break; 03048 case ANALOG_SIG_FEATDMF: 03049 case ANALOG_SIG_FEATDMF_TA: 03050 case ANALOG_SIG_E911: 03051 case ANALOG_SIG_FGC_CAMA: 03052 case ANALOG_SIG_FGC_CAMAMF: 03053 case ANALOG_SIG_FEATB: 03054 case ANALOG_SIG_SF_FEATDMF: 03055 case ANALOG_SIG_SF_FEATB: 03056 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 03057 break; 03058 default: 03059 break; 03060 } 03061 break; 03062 case ANALOG_EVENT_POLARITY: 03063 /* 03064 * If we get a Polarity Switch event, this could be 03065 * due to line seizure, remote end connect or remote end disconnect. 03066 * 03067 * Check to see if we should change the polarity state and 03068 * mark the channel as UP or if this is an indication 03069 * of remote end disconnect. 03070 */ 03071 03072 if (p->polarityonanswerdelay > 0) { 03073 /* check if event is not too soon after OffHook or Answer */ 03074 03075 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 03076 switch (ast->_state) { 03077 case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */ 03078 case AST_STATE_RINGING: /*!< Remote end is ringing */ 03079 if (p->answeronpolarityswitch) { 03080 ast_debug(1, "Answering on polarity switch! channel %d\n", p->channel); 03081 ast_setstate(p->owner, AST_STATE_UP); 03082 p->polarity = POLARITY_REV; 03083 if (p->hanguponpolarityswitch) { 03084 p->polaritydelaytv = ast_tvnow(); 03085 } 03086 } else { 03087 ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel); 03088 } 03089 break; 03090 case AST_STATE_UP: /*!< Line is up */ 03091 case AST_STATE_RING: /*!< Line is ringing */ 03092 if (p->hanguponpolarityswitch) { 03093 ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel); 03094 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 03095 p->polarity = POLARITY_IDLE; 03096 } else { 03097 ast_debug(1, "Ignore Hangup on polarity switch, channel %d\n", p->channel); 03098 } 03099 break; 03100 03101 case AST_STATE_DOWN: /*!< Channel is down and available */ 03102 case AST_STATE_RESERVED: /*!< Channel is down, but reserved */ 03103 case AST_STATE_OFFHOOK: /*!< Channel is off hook */ 03104 case AST_STATE_BUSY: /*!< Line is busy */ 03105 case AST_STATE_DIALING_OFFHOOK: /*!< Digits (or equivalent) have been dialed while offhook */ 03106 case AST_STATE_PRERING: /*!< Channel has detected an incoming call and is waiting for ring */ 03107 default: 03108 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 03109 ast_debug(1, "Ignoring Polarity switch on channel %d, state %d\n", p->channel, ast->_state); 03110 } 03111 } 03112 03113 } else { 03114 /* event is too soon after OffHook or Answer */ 03115 switch (ast->_state) { 03116 case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */ 03117 case AST_STATE_RINGING: /*!< Remote end is ringing */ 03118 if (p->answeronpolarityswitch) { 03119 ast_debug(1, "Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %d\n", p->channel, ast->_state); 03120 } 03121 break; 03122 03123 case AST_STATE_UP: /*!< Line is up */ 03124 case AST_STATE_RING: /*!< Line is ringing */ 03125 if (p->hanguponpolarityswitch) { 03126 ast_debug(1, "Polarity switch detected but NOT hanging up (too close to Answer event) on channel %d, state %d\n", p->channel, ast->_state); 03127 } 03128 break; 03129 03130 default: 03131 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 03132 ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %d\n", p->channel, ast->_state); 03133 } 03134 } 03135 } 03136 } 03137 03138 /* Added more log_debug information below to provide a better indication of what is going on */ 03139 ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 03140 break; 03141 default: 03142 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel); 03143 } 03144 return &p->subs[index].f; 03145 }
| static void* __analog_ss_thread | ( | void * | data | ) | [static] |
Definition at line 1469 of file sig_analog.c.
References ast_channel::_state, analog_alloc_sub(), ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, ANALOG_CID_START_RING, analog_decrease_ss_count(), ANALOG_DIGITMODE_DTMF, ANALOG_DIGITMODE_MF, analog_distinctive_ring(), analog_dsp_reset_and_flush_digits(), analog_dsp_set_digitmode(), ANALOG_EVENT_NONE, ANALOG_EVENT_POLARITY, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGOFFHOOK, analog_firstdigittimeout, analog_flash(), analog_gendigittimeout, analog_get_bridged_channel(), analog_get_callerid(), analog_get_index(), analog_handle_notify_message(), analog_increase_ss_count(), analog_matchdigittimeout, ANALOG_MAX_CID, analog_my_getsigstr(), ANALOG_NEED_MFDETECT, analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_echocanceller(), analog_set_linear_mode(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_sigtype_to_str(), analog_start_cid_detect(), analog_stop_cid_detect(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_INFO, analog_unalloc_sub(), analog_wait_event(), analog_wink(), ARRAY_LEN, ast_bridged_channel(), ast_canmatch_extension(), AST_CONTROL_UNHOLD, ast_copy_string(), ast_db_put(), ast_debug, ast_exists_extension(), AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_shrink_phone_number(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), analog_pvt::call_forward, callerid_free(), callerid_get_dtmf(), analog_pvt::callreturn, analog_pvt::callwaiting, analog_pvt::cancallforward, analog_pvt::canpark, chan, analog_pvt::chan_tech, analog_pvt::channel, ast_channel::cid, ast_callerid::cid_name, analog_pvt::cid_name, ast_callerid::cid_num, analog_pvt::cid_num, CID_SIG_DTMF, CID_SIG_V23, CID_SIG_V23_JP, analog_pvt::cid_signalling, analog_pvt::cid_start, ast_channel::context, analog_dialoperation::dialstr, analog_pvt::dnd, analog_pvt::dop, errno, EVENT_FLAG_SYSTEM, ast_channel::exten, exten, f, callerid_state::flags, ast_frame::frametype, free, analog_pvt::hanguponpolarityswitch, analog_pvt::hidecallerid, analog_pvt::immediate, ISTRUNK, ast_channel::language, analog_pvt::lastcid_num, len(), LOG_DEBUG, LOG_WARNING, manager_event, ast_channel::name, name, analog_pvt::owner, analog_subchannel::owner, analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, quit, ast_channel::rings, analog_pvt::ringt, analog_pvt::ringt_base, analog_pvt::sig, analog_pvt::ss_astchan, strsep(), ast_frame::subclass, analog_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, analog_pvt::transfer, and analog_pvt::use_callerid.
Referenced by __analog_handle_event(), analog_handle_init_event(), and analog_ss_thread_start().
01470 { 01471 struct analog_pvt *p = data; 01472 struct ast_channel *chan = p->ss_astchan; 01473 char exten[AST_MAX_EXTENSION] = ""; 01474 char exten2[AST_MAX_EXTENSION] = ""; 01475 char dtmfcid[300]; 01476 char dtmfbuf[300]; 01477 char namebuf[ANALOG_MAX_CID]; 01478 char numbuf[ANALOG_MAX_CID]; 01479 struct callerid_state *cs = NULL; 01480 char *name = NULL, *number = NULL; 01481 int flags = 0; 01482 int timeout; 01483 int getforward = 0; 01484 char *s1, *s2; 01485 int len = 0; 01486 int res; 01487 int index; 01488 01489 analog_increase_ss_count(p); 01490 01491 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 01492 01493 if (!chan) { 01494 /* What happened to the channel? */ 01495 goto quit; 01496 } 01497 /* in the bizarre case where the channel has become a zombie before we 01498 even get started here, abort safely 01499 */ 01500 if (!chan->tech_pvt) { 01501 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 01502 ast_hangup(chan); 01503 goto quit; 01504 } 01505 01506 ast_verb(3, "Starting simple switch on '%s'\n", chan->name); 01507 index = analog_get_index(chan, p, 1); 01508 if (index < 0) { 01509 ast_log(LOG_WARNING, "Huh?\n"); 01510 ast_hangup(chan); 01511 goto quit; 01512 } 01513 analog_dsp_reset_and_flush_digits(p); 01514 switch (p->sig) { 01515 case ANALOG_SIG_FEATD: 01516 case ANALOG_SIG_FEATDMF: 01517 case ANALOG_SIG_FEATDMF_TA: 01518 case ANALOG_SIG_E911: 01519 case ANALOG_SIG_FGC_CAMAMF: 01520 case ANALOG_SIG_FEATB: 01521 case ANALOG_SIG_EMWINK: 01522 case ANALOG_SIG_SF_FEATD: 01523 case ANALOG_SIG_SF_FEATDMF: 01524 case ANALOG_SIG_SF_FEATB: 01525 case ANALOG_SIG_SFWINK: 01526 if (analog_wink(p, index)) 01527 goto quit; 01528 /* Fall through */ 01529 case ANALOG_SIG_EM: 01530 case ANALOG_SIG_EM_E1: 01531 case ANALOG_SIG_SF: 01532 case ANALOG_SIG_FGC_CAMA: 01533 res = analog_play_tone(p, index, -1); 01534 01535 analog_dsp_reset_and_flush_digits(p); 01536 01537 if (ANALOG_NEED_MFDETECT(p)) { 01538 analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF); 01539 } else { 01540 analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF); 01541 } 01542 01543 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 01544 /* Wait for the first digit only if immediate=no */ 01545 if (!p->immediate) { 01546 /* Wait for the first digit (up to 5 seconds). */ 01547 res = ast_waitfordigit(chan, 5000); 01548 } else { 01549 res = 0; 01550 } 01551 if (res > 0) { 01552 /* save first char */ 01553 dtmfbuf[0] = res; 01554 switch (p->sig) { 01555 case ANALOG_SIG_FEATD: 01556 case ANALOG_SIG_SF_FEATD: 01557 res = analog_my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 01558 if (res > 0) { 01559 res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 01560 } 01561 if (res < 1) { 01562 analog_dsp_reset_and_flush_digits(p); 01563 } 01564 break; 01565 case ANALOG_SIG_FEATDMF_TA: 01566 res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 01567 if (res < 1) { 01568 analog_dsp_reset_and_flush_digits(p); 01569 } 01570 if (analog_wink(p, index)) { 01571 goto quit; 01572 } 01573 dtmfbuf[0] = 0; 01574 /* Wait for the first digit (up to 5 seconds). */ 01575 res = ast_waitfordigit(chan, 5000); 01576 if (res <= 0) { 01577 break; 01578 } 01579 dtmfbuf[0] = res; 01580 /* fall through intentionally */ 01581 case ANALOG_SIG_FEATDMF: 01582 case ANALOG_SIG_E911: 01583 case ANALOG_SIG_FGC_CAMAMF: 01584 case ANALOG_SIG_SF_FEATDMF: 01585 res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 01586 /* if international caca, do it again to get real ANO */ 01587 if ((p->sig == ANALOG_SIG_FEATDMF) && (dtmfbuf[1] != '0') 01588 && (strlen(dtmfbuf) != 14)) { 01589 if (analog_wink(p, index)) { 01590 goto quit; 01591 } 01592 dtmfbuf[0] = 0; 01593 /* Wait for the first digit (up to 5 seconds). */ 01594 res = ast_waitfordigit(chan, 5000); 01595 if (res <= 0) { 01596 break; 01597 } 01598 dtmfbuf[0] = res; 01599 res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 01600 } 01601 if (res > 0) { 01602 /* if E911, take off hook */ 01603 if (p->sig == ANALOG_SIG_E911) { 01604 analog_off_hook(p); 01605 } 01606 res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 01607 } 01608 if (res < 1) { 01609 analog_dsp_reset_and_flush_digits(p); 01610 } 01611 break; 01612 case ANALOG_SIG_FEATB: 01613 case ANALOG_SIG_SF_FEATB: 01614 res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 01615 if (res < 1) { 01616 analog_dsp_reset_and_flush_digits(p); 01617 } 01618 break; 01619 case ANALOG_SIG_EMWINK: 01620 /* if we received a '*', we are actually receiving Feature Group D 01621 dial syntax, so use that mode; otherwise, fall through to normal 01622 mode 01623 */ 01624 if (res == '*') { 01625 res = analog_my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 01626 if (res > 0) { 01627 res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 01628 } 01629 if (res < 1) { 01630 analog_dsp_reset_and_flush_digits(p); 01631 } 01632 break; 01633 } 01634 default: 01635 /* If we got the first digit, get the rest */ 01636 len = 1; 01637 dtmfbuf[len] = '\0'; 01638 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 01639 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 01640 timeout = analog_matchdigittimeout; 01641 } else { 01642 timeout = analog_gendigittimeout; 01643 } 01644 res = ast_waitfordigit(chan, timeout); 01645 if (res < 0) { 01646 ast_debug(1, "waitfordigit returned < 0...\n"); 01647 ast_hangup(chan); 01648 goto quit; 01649 } else if (res) { 01650 dtmfbuf[len++] = res; 01651 dtmfbuf[len] = '\0'; 01652 } else { 01653 break; 01654 } 01655 } 01656 break; 01657 } 01658 } 01659 if (res == -1) { 01660 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 01661 ast_hangup(chan); 01662 goto quit; 01663 } else if (res < 0) { 01664 ast_debug(1, "Got hung up before digits finished\n"); 01665 ast_hangup(chan); 01666 goto quit; 01667 } 01668 01669 if (p->sig == ANALOG_SIG_FGC_CAMA) { 01670 char anibuf[100]; 01671 01672 if (ast_safe_sleep(chan,1000) == -1) { 01673 ast_hangup(chan); 01674 goto quit; 01675 } 01676 analog_off_hook(p); 01677 analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF); 01678 res = analog_my_getsigstr(chan, anibuf, "#", 10000); 01679 if ((res > 0) && (strlen(anibuf) > 2)) { 01680 if (anibuf[strlen(anibuf) - 1] == '#') { 01681 anibuf[strlen(anibuf) - 1] = 0; 01682 } 01683 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 01684 } 01685 analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF); 01686 } 01687 01688 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 01689 if (ast_strlen_zero(exten)) { 01690 ast_copy_string(exten, "s", sizeof(exten)); 01691 } 01692 if (p->sig == ANALOG_SIG_FEATD || p->sig == ANALOG_SIG_EMWINK) { 01693 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 01694 if (exten[0] == '*') { 01695 char *stringp=NULL; 01696 ast_copy_string(exten2, exten, sizeof(exten2)); 01697 /* Parse out extension and callerid */ 01698 stringp=exten2 +1; 01699 s1 = strsep(&stringp, "*"); 01700 s2 = strsep(&stringp, "*"); 01701 if (s2) { 01702 if (!ast_strlen_zero(p->cid_num)) { 01703 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 01704 } else { 01705 ast_set_callerid(chan, s1, NULL, s1); 01706 } 01707 ast_copy_string(exten, s2, sizeof(exten)); 01708 } else { 01709 ast_copy_string(exten, s1, sizeof(exten)); 01710 } 01711 } else if (p->sig == ANALOG_SIG_FEATD) { 01712 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 01713 } 01714 } 01715 if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) { 01716 if (exten[0] == '*') { 01717 char *stringp=NULL; 01718 ast_copy_string(exten2, exten, sizeof(exten2)); 01719 /* Parse out extension and callerid */ 01720 stringp=exten2 +1; 01721 s1 = strsep(&stringp, "#"); 01722 s2 = strsep(&stringp, "#"); 01723 if (s2) { 01724 if (!ast_strlen_zero(p->cid_num)) { 01725 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 01726 } else { 01727 if (*(s1 + 2)) { 01728 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 01729 } 01730 } 01731 ast_copy_string(exten, s2 + 1, sizeof(exten)); 01732 } else { 01733 ast_copy_string(exten, s1 + 2, sizeof(exten)); 01734 } 01735 } else { 01736 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 01737 } 01738 } 01739 if ((p->sig == ANALOG_SIG_E911) || (p->sig == ANALOG_SIG_FGC_CAMAMF)) { 01740 if (exten[0] == '*') { 01741 char *stringp=NULL; 01742 ast_copy_string(exten2, exten, sizeof(exten2)); 01743 /* Parse out extension and callerid */ 01744 stringp=exten2 +1; 01745 s1 = strsep(&stringp, "#"); 01746 s2 = strsep(&stringp, "#"); 01747 if (s2 && (*(s2 + 1) == '0')) { 01748 if (*(s2 + 2)) { 01749 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 01750 } 01751 } 01752 if (s1) { 01753 ast_copy_string(exten, s1, sizeof(exten)); 01754 } else { 01755 ast_copy_string(exten, "911", sizeof(exten)); 01756 } 01757 } else { 01758 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 01759 } 01760 } 01761 if (p->sig == ANALOG_SIG_FEATB) { 01762 if (exten[0] == '*') { 01763 char *stringp=NULL; 01764 ast_copy_string(exten2, exten, sizeof(exten2)); 01765 /* Parse out extension and callerid */ 01766 stringp=exten2 +1; 01767 s1 = strsep(&stringp, "#"); 01768 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 01769 } else { 01770 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 01771 } 01772 } 01773 if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) { 01774 analog_wink(p, index); 01775 /* some switches require a minimum guard time between 01776 the last FGD wink and something that answers 01777 immediately. This ensures it */ 01778 if (ast_safe_sleep(chan,100)) { 01779 goto quit; 01780 } 01781 } 01782 analog_set_echocanceller(p, 1); 01783 01784 analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF); 01785 01786 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 01787 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 01788 analog_dsp_reset_and_flush_digits(p); 01789 res = ast_pbx_run(chan); 01790 if (res) { 01791 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 01792 res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 01793 } 01794 goto quit; 01795 } else { 01796 ast_verb(3, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 01797 sleep(2); 01798 res = analog_play_tone(p, index, ANALOG_TONE_INFO); 01799 if (res < 0) { 01800 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 01801 } else { 01802 sleep(1); 01803 } 01804 res = ast_streamfile(chan, "ss-noservice", chan->language); 01805 if (res >= 0) { 01806 ast_waitstream(chan, ""); 01807 } 01808 res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 01809 ast_hangup(chan); 01810 goto quit; 01811 } 01812 break; 01813 case ANALOG_SIG_FXOLS: 01814 case ANALOG_SIG_FXOGS: 01815 case ANALOG_SIG_FXOKS: 01816 /* Read the first digit */ 01817 timeout = analog_firstdigittimeout; 01818 /* If starting a threeway call, never timeout on the first digit so someone 01819 can use flash-hook as a "hold" feature */ 01820 if (p->subs[ANALOG_SUB_THREEWAY].owner) { 01821 timeout = 999999; 01822 } 01823 while (len < AST_MAX_EXTENSION-1) { 01824 /* Read digit unless it's supposed to be immediate, in which case the 01825 only answer is 's' */ 01826 if (p->immediate) { 01827 res = 's'; 01828 } else { 01829 res = ast_waitfordigit(chan, timeout); 01830 } 01831 timeout = 0; 01832 if (res < 0) { 01833 ast_debug(1, "waitfordigit returned < 0...\n"); 01834 res = analog_play_tone(p, index, -1); 01835 ast_hangup(chan); 01836 goto quit; 01837 } else if (res) { 01838 exten[len++]=res; 01839 exten[len] = '\0'; 01840 } 01841 if (!ast_ignore_pattern(chan->context, exten)) { 01842 analog_play_tone(p, index, -1); 01843 } else { 01844 analog_play_tone(p, index, ANALOG_TONE_DIALTONE); 01845 } 01846 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 01847 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 01848 if (getforward) { 01849 /* Record this as the forwarding extension */ 01850 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 01851 ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 01852 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01853 if (res) { 01854 break; 01855 } 01856 usleep(500000); 01857 res = analog_play_tone(p, index, -1); 01858 sleep(1); 01859 memset(exten, 0, sizeof(exten)); 01860 res = analog_play_tone(p, index, ANALOG_TONE_DIALTONE); 01861 len = 0; 01862 getforward = 0; 01863 } else { 01864 res = analog_play_tone(p, index, -1); 01865 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 01866 if (!ast_strlen_zero(p->cid_num)) { 01867 if (!p->hidecallerid) { 01868 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 01869 } else { 01870 ast_set_callerid(chan, NULL, NULL, p->cid_num); 01871 } 01872 } 01873 if (!ast_strlen_zero(p->cid_name)) { 01874 if (!p->hidecallerid) { 01875 ast_set_callerid(chan, NULL, p->cid_name, NULL); 01876 } 01877 } 01878 ast_setstate(chan, AST_STATE_RING); 01879 analog_set_echocanceller(p, 1); 01880 res = ast_pbx_run(chan); 01881 if (res) { 01882 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 01883 res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 01884 } 01885 goto quit; 01886 } 01887 } else { 01888 /* It's a match, but they just typed a digit, and there is an ambiguous match, 01889 so just set the timeout to analog_matchdigittimeout and wait some more */ 01890 timeout = analog_matchdigittimeout; 01891 } 01892 } else if (res == 0) { 01893 ast_debug(1, "not enough digits (and no ambiguous match)...\n"); 01894 res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 01895 analog_wait_event(p); 01896 ast_hangup(chan); 01897 goto quit; 01898 } else if (p->callwaiting && !strcmp(exten, "*70")) { 01899 ast_verb(3, "Disabling call waiting on %s\n", chan->name); 01900 /* Disable call waiting if enabled */ 01901 p->callwaiting = 0; 01902 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01903 if (res) { 01904 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 01905 chan->name, strerror(errno)); 01906 } 01907 len = 0; 01908 memset(exten, 0, sizeof(exten)); 01909 timeout = analog_firstdigittimeout; 01910 01911 } else if (!strcmp(exten,ast_pickup_ext())) { 01912 /* Scan all channels and see if there are any 01913 * ringing channels that have call groups 01914 * that equal this channels pickup group 01915 */ 01916 if (index == ANALOG_SUB_REAL) { 01917 /* Switch us from Third call to Call Wait */ 01918 if (p->subs[ANALOG_SUB_THREEWAY].owner) { 01919 /* If you make a threeway call and the *8# a call, it should actually 01920 look like a callwait */ 01921 analog_alloc_sub(p, ANALOG_SUB_CALLWAIT); 01922 analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY); 01923 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 01924 } 01925 analog_set_echocanceller(p, 1); 01926 if (ast_pickup_call(chan)) { 01927 ast_debug(1, "No call pickup possible...\n"); 01928 res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 01929 analog_wait_event(p); 01930 } 01931 ast_hangup(chan); 01932 goto quit; 01933 } else { 01934 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 01935 ast_hangup(chan); 01936 goto quit; 01937 } 01938 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 01939 ast_verb(3, "Disabling Caller*ID on %s\n", chan->name); 01940 /* Disable Caller*ID if enabled */ 01941 p->hidecallerid = 1; 01942 if (chan->cid.cid_num) { 01943 free(chan->cid.cid_num); 01944 } 01945 chan->cid.cid_num = NULL; 01946 if (chan->cid.cid_name) { 01947 free(chan->cid.cid_name); 01948 } 01949 chan->cid.cid_name = NULL; 01950 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01951 if (res) { 01952 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 01953 chan->name, strerror(errno)); 01954 } 01955 len = 0; 01956 memset(exten, 0, sizeof(exten)); 01957 timeout = analog_firstdigittimeout; 01958 } else if (p->callreturn && !strcmp(exten, "*69")) { 01959 res = 0; 01960 if (!ast_strlen_zero(p->lastcid_num)) { 01961 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 01962 } 01963 if (!res) { 01964 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01965 } 01966 break; 01967 } else if (!strcmp(exten, "*78")) { 01968 /* Do not disturb */ 01969 ast_verb(3, "Enabled DND on channel %d\n", p->channel); 01970 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 01971 "Channel: DAHDI/%d\r\n" 01972 "Status: enabled\r\n", p->channel); 01973 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01974 p->dnd = 1; 01975 getforward = 0; 01976 memset(exten, 0, sizeof(exten)); 01977 len = 0; 01978 } else if (!strcmp(exten, "*79")) { 01979 /* Do not disturb */ 01980 ast_verb(3, "Disabled DND on channel %d\n", p->channel); 01981 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 01982 "Channel: DAHDI/%d\r\n" 01983 "Status: disabled\r\n", p->channel); 01984 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01985 p->dnd = 0; 01986 getforward = 0; 01987 memset(exten, 0, sizeof(exten)); 01988 len = 0; 01989 } else if (p->cancallforward && !strcmp(exten, "*72")) { 01990 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01991 getforward = 1; 01992 memset(exten, 0, sizeof(exten)); 01993 len = 0; 01994 } else if (p->cancallforward && !strcmp(exten, "*73")) { 01995 ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel); 01996 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 01997 memset(p->call_forward, 0, sizeof(p->call_forward)); 01998 getforward = 0; 01999 memset(exten, 0, sizeof(exten)); 02000 len = 0; 02001 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 02002 p->subs[ANALOG_SUB_THREEWAY].owner && 02003 ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) { 02004 /* This is a three way call, the main call being a real channel, 02005 and we're parking the first call. */ 02006 ast_masq_park_call(ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner), chan, 0, NULL); 02007 ast_verb(3, "Parking call to '%s'\n", chan->name); 02008 break; 02009 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 02010 ast_verb(3, "Blacklisting number %s\n", p->lastcid_num); 02011 res = ast_db_put("blacklist", p->lastcid_num, "1"); 02012 if (!res) { 02013 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 02014 memset(exten, 0, sizeof(exten)); 02015 len = 0; 02016 } 02017 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 02018 ast_verb(3, "Enabling Caller*ID on %s\n", chan->name); 02019 /* Enable Caller*ID if enabled */ 02020 p->hidecallerid = 0; 02021 if (chan->cid.cid_num) { 02022 free(chan->cid.cid_num); 02023 } 02024 chan->cid.cid_num = NULL; 02025 if (chan->cid.cid_name) { 02026 free(chan->cid.cid_name); 02027 } 02028 chan->cid.cid_name = NULL; 02029 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 02030 res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL); 02031 if (res) { 02032 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 02033 chan->name, strerror(errno)); 02034 } 02035 len = 0; 02036 memset(exten, 0, sizeof(exten)); 02037 timeout = analog_firstdigittimeout; 02038 } else if (!strcmp(exten, "*0")) { 02039 struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner; 02040 struct analog_pvt *pbridge = NULL; 02041 /* set up the private struct of the bridged one, if any */ 02042 if (nbridge && ast_bridged_channel(nbridge)) { 02043 pbridge = analog_get_bridged_channel(p, nbridge); 02044 } 02045 if (nbridge && pbridge && 02046 (nbridge->tech == p->chan_tech) && 02047 (ast_bridged_channel(nbridge)->tech == p->chan_tech) && 02048 ISTRUNK(pbridge)) { 02049 /* Clear out the dial buffer */ 02050 p->dop.dialstr[0] = '\0'; 02051 /* flash hookswitch */ 02052 if ((analog_flash(p) == -1) && (errno != EINPROGRESS)) { 02053 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 02054 nbridge->name, strerror(errno)); 02055 } 02056 analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY); 02057 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 02058 p->owner = p->subs[ANALOG_SUB_REAL].owner; 02059 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 02060 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 02061 } 02062 ast_hangup(chan); 02063 goto quit; 02064 } else { 02065 analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 02066 analog_wait_event(p); 02067 analog_play_tone(p, index, -1); 02068 analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY); 02069 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 02070 p->owner = p->subs[ANALOG_SUB_REAL].owner; 02071 ast_hangup(chan); 02072 goto quit; 02073 } 02074 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 02075 ((exten[0] != '*') || (strlen(exten) > 2))) { 02076 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context); 02077 break; 02078 } 02079 if (!timeout) { 02080 timeout = analog_gendigittimeout; 02081 } 02082 if (len && !ast_ignore_pattern(chan->context, exten)) { 02083 analog_play_tone(p, index, -1); 02084 } 02085 } 02086 break; 02087 case ANALOG_SIG_FXSLS: 02088 case ANALOG_SIG_FXSGS: 02089 case ANALOG_SIG_FXSKS: 02090 02091 /* If we want caller id, we're in a prering state due to a polarity reversal 02092 * and we're set to use a polarity reversal to trigger the start of caller id, 02093 * grab the caller id and wait for ringing to start... */ 02094 if (p->use_callerid && (chan->_state == AST_STATE_PRERING && 02095 (p->cid_start == ANALOG_CID_START_POLARITY || p->cid_start == ANALOG_CID_START_POLARITY_IN || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) { 02096 /* If set to use DTMF CID signalling, listen for DTMF */ 02097 if (p->cid_signalling == CID_SIG_DTMF) { 02098 int i = 0; 02099 int oldlinearity; 02100 cs = NULL; 02101 ast_debug(1, "Receiving DTMF cid on " 02102 "channel %s\n", chan->name); 02103 02104 oldlinearity = analog_set_linear_mode(p, index, 0); 02105 02106 res = 2000; 02107 for (;;) { 02108 struct ast_frame *f; 02109 res = ast_waitfor(chan, res); 02110 if (res <= 0) { 02111 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 02112 "Exiting simple switch\n"); 02113 ast_hangup(chan); 02114 goto quit; 02115 } 02116 if (!(f = ast_read(chan))) { 02117 break; 02118 } 02119 if (f->frametype == AST_FRAME_DTMF) { 02120 dtmfbuf[i++] = f->subclass; 02121 ast_debug(1, "CID got digit '%c'\n", f->subclass); 02122 res = 2000; 02123 } 02124 ast_frfree(f); 02125 if (chan->_state == AST_STATE_RING || chan->_state == AST_STATE_RINGING) { 02126 break; /* Got ring */ 02127 } 02128 } 02129 dtmfbuf[i] = '\0'; 02130 02131 analog_set_linear_mode(p, index, oldlinearity); 02132 02133 /* Got cid and ring. */ 02134 ast_debug(1, "CID got string '%s'\n", dtmfbuf); 02135 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 02136 ast_debug(1, "CID is '%s', flags %d\n", 02137 dtmfcid, flags); 02138 /* If first byte is NULL, we have no cid */ 02139 if (!ast_strlen_zero(dtmfcid)) { 02140 number = dtmfcid; 02141 } else { 02142 number = NULL; 02143 } 02144 02145 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 02146 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 02147 int timeout = 10000; /* Ten seconds */ 02148 struct timeval start = ast_tvnow(); 02149 enum analog_event ev; 02150 02151 namebuf[0] = 0; 02152 numbuf[0] = 0; 02153 02154 if (!analog_start_cid_detect(p, p->cid_signalling)) { 02155 while (1) { 02156 res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start)); 02157 02158 if (res == 0) { 02159 break; 02160 } 02161 02162 if (res == 1) { 02163 if (p->cid_signalling == CID_SIG_V23_JP) { 02164 if (ev == ANALOG_EVENT_RINGBEGIN) { 02165 analog_off_hook(p); 02166 usleep(1); 02167 } 02168 } else { 02169 ev = ANALOG_EVENT_NONE; 02170 break; 02171 } 02172 } 02173 02174 if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) 02175 break; 02176 02177 } 02178 name = namebuf; 02179 number = numbuf; 02180 02181 analog_stop_cid_detect(p); 02182 02183 if (p->cid_signalling == CID_SIG_V23_JP) { 02184 res = analog_on_hook(p); 02185 usleep(1); 02186 res = 4000; 02187 } else { 02188 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 02189 res = 2000; 02190 } 02191 02192 for (;;) { 02193 struct ast_frame *f; 02194 res = ast_waitfor(chan, res); 02195 if (res <= 0) { 02196 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 02197 "Exiting simple switch\n"); 02198 ast_hangup(chan); 02199 goto quit; 02200 } 02201 if (!(f = ast_read(chan))) { 02202 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n"); 02203 ast_hangup(chan); 02204 goto quit; 02205 } 02206 ast_frfree(f); 02207 if (chan->_state == AST_STATE_RING || 02208 chan->_state == AST_STATE_RINGING) 02209 break; /* Got ring */ 02210 } 02211 02212 if (analog_distinctive_ring(chan, p, index, NULL)) { 02213 goto quit; 02214 } 02215 02216 if (res < 0) { 02217 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 02218 } 02219 } else { 02220 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 02221 } 02222 02223 } else { 02224 ast_log(LOG_WARNING, "Channel %s in prering " 02225 "state, but I have nothing to do. " 02226 "Terminating simple switch, should be " 02227 "restarted by the actual ring.\n", 02228 chan->name); 02229 ast_hangup(chan); 02230 goto quit; 02231 } 02232 } else if (p->use_callerid && p->cid_start == ANALOG_CID_START_RING) { 02233 int timeout = 10000; /* Ten seconds */ 02234 struct timeval start = ast_tvnow(); 02235 enum analog_event ev; 02236 int curRingData[3] = { 0 }; 02237 int receivedRingT = 0; 02238 02239 namebuf[0] = 0; 02240 numbuf[0] = 0; 02241 02242 if (!analog_start_cid_detect(p, p->cid_signalling)) { 02243 while (1) { 02244 res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start)); 02245 02246 if (res == 0) { 02247 break; 02248 } 02249 02250 if (res == 1 || res == 2) { 02251 if (ev == ANALOG_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 02252 ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 02253 p->polarity = POLARITY_IDLE; 02254 ast_hangup(chan); 02255 goto quit; 02256 } else if (ev != ANALOG_EVENT_NONE && ev != ANALOG_EVENT_RINGBEGIN && ev != ANALOG_EVENT_RINGOFFHOOK) { 02257 break; 02258 } 02259 if (res != 2) { 02260 /* Let us detect callerid when the telco uses distinctive ring */ 02261 curRingData[receivedRingT] = p->ringt; 02262 02263 if (p->ringt < p->ringt_base/2) { 02264 break; 02265 } 02266 /* Increment the ringT counter so we can match it against 02267 values in chan_dahdi.conf for distinctive ring */ 02268 if (++receivedRingT == ARRAY_LEN(curRingData)) { 02269 break; 02270 } 02271 } 02272 } 02273 02274 if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) { 02275 break; 02276 } 02277 02278 } 02279 name = namebuf; 02280 number = numbuf; 02281 02282 analog_stop_cid_detect(p); 02283 02284 if (analog_distinctive_ring(chan, p, index, curRingData)) { 02285 goto quit; 02286 } 02287 02288 if (res < 0) { 02289 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 02290 } 02291 } else { 02292 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 02293 } 02294 } else { 02295 cs = NULL; 02296 } 02297 02298 if (number) { 02299 ast_shrink_phone_number(number); 02300 } 02301 ast_set_callerid(chan, number, name, number); 02302 02303 if (cs) { 02304 callerid_free(cs); 02305 } 02306 02307 analog_handle_notify_message(chan, p, flags, -1); 02308 02309 ast_setstate(chan, AST_STATE_RING); 02310 chan->rings = 1; 02311 analog_set_ringtimeout(p, p->ringt_base); 02312 res = ast_pbx_run(chan); 02313 if (res) { 02314 ast_hangup(chan); 02315 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 02316 } 02317 goto quit; 02318 default: 02319 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); 02320 break; 02321 } 02322 res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION); 02323 if (res < 0) { 02324 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 02325 } 02326 ast_hangup(chan); 02327 quit: 02328 analog_decrease_ss_count(p); 02329 return NULL; 02330 }
| static void analog_all_subchannels_hungup | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 484 of file sig_analog.c.
References analog_callback::all_subchannels_hungup, analog_pvt::calls, and analog_pvt::chan_pvt.
Referenced by analog_hangup().
00485 { 00486 if (p->calls->all_subchannels_hungup) { 00487 p->calls->all_subchannels_hungup(p->chan_pvt); 00488 } 00489 }
| static int analog_alloc_sub | ( | struct analog_pvt * | p, | |
| enum analog_sub | x | |||
| ) | [static] |
Definition at line 323 of file sig_analog.c.
References analog_callback::allocate_sub, analog_subchannel::allocd, analog_pvt::calls, analog_pvt::chan_pvt, and analog_pvt::subs.
Referenced by __analog_handle_event(), __analog_ss_thread(), and analog_request().
00324 { 00325 if (p->calls->allocate_sub) { 00326 int res; 00327 res = p->calls->allocate_sub(p->chan_pvt, x); 00328 if (!res) { 00329 p->subs[x].allocd = 1; 00330 } 00331 return res; 00332 } 00333 return 0; 00334 }
| int analog_answer | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) |
Definition at line 1268 of file sig_analog.c.
References ast_channel::_state, analog_get_index(), analog_off_hook(), analog_play_tone(), analog_set_dialing(), analog_set_echocanceller(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), analog_train_echocanceller(), ast_debug, ast_log(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, analog_pvt::channel, analog_pvt::hanguponpolarityswitch, analog_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, ast_channel::name, analog_subchannel::owner, analog_pvt::owner, analog_pvt::polaritydelaytv, analog_pvt::sig, and analog_pvt::subs.
Referenced by dahdi_answer().
01269 { 01270 int res = 0; 01271 int index; 01272 int oldstate = ast->_state; 01273 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 01274 ast_setstate(ast, AST_STATE_UP); 01275 index = analog_get_index(ast, p, 1); 01276 if (index < 0) { 01277 index = ANALOG_SUB_REAL; 01278 } 01279 switch (p->sig) { 01280 case ANALOG_SIG_FXSLS: 01281 case ANALOG_SIG_FXSGS: 01282 case ANALOG_SIG_FXSKS: 01283 analog_set_ringtimeout(p, 0); 01284 /* Fall through */ 01285 case ANALOG_SIG_EM: 01286 case ANALOG_SIG_EM_E1: 01287 case ANALOG_SIG_EMWINK: 01288 case ANALOG_SIG_FEATD: 01289 case ANALOG_SIG_FEATDMF: 01290 case ANALOG_SIG_FEATDMF_TA: 01291 case ANALOG_SIG_E911: 01292 case ANALOG_SIG_FGC_CAMA: 01293 case ANALOG_SIG_FGC_CAMAMF: 01294 case ANALOG_SIG_FEATB: 01295 case ANALOG_SIG_SF: 01296 case ANALOG_SIG_SFWINK: 01297 case ANALOG_SIG_SF_FEATD: 01298 case ANALOG_SIG_SF_FEATDMF: 01299 case ANALOG_SIG_SF_FEATB: 01300 case ANALOG_SIG_FXOLS: 01301 case ANALOG_SIG_FXOGS: 01302 case ANALOG_SIG_FXOKS: 01303 /* Pick up the line */ 01304 ast_debug(1, "Took %s off hook\n", ast->name); 01305 if (p->hanguponpolarityswitch) { 01306 gettimeofday(&p->polaritydelaytv, NULL); 01307 } 01308 res = analog_off_hook(p); 01309 analog_play_tone(p, index, -1); 01310 analog_set_dialing(p, 0); 01311 if ((index == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) { 01312 if (oldstate == AST_STATE_RINGING) { 01313 ast_debug(1, "Finally swapping real and threeway\n"); 01314 analog_play_tone(p, ANALOG_SUB_THREEWAY, -1); 01315 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 01316 p->owner = p->subs[ANALOG_SUB_REAL].owner; 01317 } 01318 } 01319 if ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || (p->sig == ANALOG_SIG_FXSGS)) { 01320 analog_set_echocanceller(p, 1); 01321 analog_train_echocanceller(p); 01322 } 01323 break; 01324 default: 01325 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 01326 res = -1; 01327 } 01328 ast_setstate(ast, AST_STATE_UP); 01329 return res; 01330 }
| static int analog_attempt_transfer | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 552 of file sig_analog.c.
References ast_channel::_state, analog_play_tone(), ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_RINGTONE, analog_unalloc_sub(), ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_masquerade(), ast_channel_unlock, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), ast_log(), ast_queue_control(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, analog_subchannel::inthreeway, ast_channel::linkedid, LOG_WARNING, ast_channel::name, analog_subchannel::owner, and analog_pvt::subs.
Referenced by __analog_handle_event().
00553 { 00554 /* In order to transfer, we need at least one of the channels to 00555 actually be in a call bridge. We can't conference two applications 00556 together (but then, why would we want to?) */ 00557 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 00558 /* The three-way person we're about to transfer to could still be in MOH, so 00559 stop if now if appropriate */ 00560 if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) { 00561 ast_queue_control(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 00562 } 00563 if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RINGING) { 00564 ast_indicate(ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner), AST_CONTROL_RINGING); 00565 } 00566 if (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_RING) { 00567 analog_play_tone(p, ANALOG_SUB_THREEWAY, ANALOG_TONE_RINGTONE); 00568 } 00569 if (!p->subs[ANALOG_SUB_THREEWAY].inthreeway) { 00570 ast_cel_report_event(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CEL_ATTENDEDTRANSFER, NULL, p->subs[ANALOG_SUB_THREEWAY].owner->linkedid, NULL); 00571 } 00572 if (ast_channel_masquerade(p->subs[ANALOG_SUB_THREEWAY].owner, ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner))) { 00573 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 00574 ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)->name, p->subs[ANALOG_SUB_THREEWAY].owner->name); 00575 return -1; 00576 } 00577 /* Orphan the channel after releasing the lock */ 00578 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 00579 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 00580 } else if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) { 00581 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 00582 if (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 00583 ast_indicate(ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner), AST_CONTROL_RINGING); 00584 } 00585 if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RING) { 00586 analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE); 00587 } 00588 ast_cel_report_event(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CEL_BLINDTRANSFER, NULL, p->subs[ANALOG_SUB_THREEWAY].owner->linkedid, NULL); 00589 if (ast_channel_masquerade(p->subs[ANALOG_SUB_REAL].owner, ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner))) { 00590 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 00591 ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)->name, p->subs[ANALOG_SUB_REAL].owner->name); 00592 return -1; 00593 } 00594 /* Three-way is now the REAL */ 00595 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 00596 ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner); /* unlock REAL because THREEWAY has become REAL */ 00597 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 00598 /* Tell the caller not to hangup */ 00599 return 1; 00600 } else { 00601 ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n", 00602 p->subs[ANALOG_SUB_REAL].owner->name, p->subs[ANALOG_SUB_THREEWAY].owner->name); 00603 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 00604 return -1; 00605 } 00606 return 0; 00607 }
| int analog_available | ( | struct analog_pvt * | p, | |
| int | channelmatch, | |||
| ast_group_t | groupmatch, | |||
| int * | busy, | |||
| int * | channelmatched, | |||
| int * | groupmatched | |||
| ) |
Definition at line 651 of file sig_analog.c.
References ast_channel::_state, analog_subchannel::allocd, analog_is_off_hook(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY, ast_debug, ast_log(), AST_STATE_RINGING, AST_STATE_UP, analog_pvt::callwaiting, analog_pvt::channel, analog_pvt::dnd, analog_pvt::guardtime, analog_subchannel::inthreeway, LOG_DEBUG, analog_pvt::outgoing, analog_subchannel::owner, analog_pvt::owner, analog_pvt::sig, and analog_pvt::subs.
Referenced by available().
00652 { 00653 int offhook; 00654 00655 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 00656 /* We're at least busy at this point */ 00657 if (busy) { 00658 if ((p->sig == ANALOG_SIG_FXOKS) || (p->sig == ANALOG_SIG_FXOLS) || (p->sig == ANALOG_SIG_FXOGS)) { 00659 *busy = 1; 00660 } 00661 } 00662 /* If do not disturb, definitely not */ 00663 if (p->dnd) { 00664 return 0; 00665 } 00666 /* If guard time, definitely not */ 00667 if (p->guardtime && (time(NULL) < p->guardtime)) { 00668 return 0; 00669 } 00670 00671 /* If no owner definitely available */ 00672 if (!p->owner) { 00673 if (p->sig == ANALOG_SIG_FXSLS) { 00674 return 1; 00675 } 00676 00677 offhook = analog_is_off_hook(p); 00678 00679 if ((p->sig == ANALOG_SIG_FXSKS) || (p->sig == ANALOG_SIG_FXSGS)) { 00680 /* When "onhook" that means no battery on the line, and thus 00681 it is out of service..., if it's on a TDM card... If it's a channel 00682 bank, there is no telling... */ 00683 if (offhook) { 00684 return 1; 00685 } 00686 return 0; 00687 } else if (offhook) { 00688 ast_debug(1, "Channel %d off hook, can't use\n", p->channel); 00689 /* Not available when the other end is off hook */ 00690 return 0; 00691 } 00692 return 1; 00693 } 00694 00695 /* If it's not an FXO, forget about call wait */ 00696 if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) { 00697 return 0; 00698 } 00699 00700 if (!p->callwaiting) { 00701 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 00702 return 0; 00703 } 00704 00705 if (p->subs[ANALOG_SUB_CALLWAIT].allocd) { 00706 /* If there is already a call waiting call, then we can't take a second one */ 00707 return 0; 00708 } 00709 00710 if ((p->owner->_state != AST_STATE_UP) && 00711 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 00712 /* If the current call is not up, then don't allow the call */ 00713 return 0; 00714 } 00715 if ((p->subs[ANALOG_SUB_THREEWAY].owner) && (!p->subs[ANALOG_SUB_THREEWAY].inthreeway)) { 00716 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 00717 return 0; 00718 } 00719 /* We're cool */ 00720 return 1; 00721 }
| int analog_call | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast, | |||
| char * | rdest, | |||
| int | timeout | |||
| ) |
Definition at line 837 of file sig_analog.c.
References ast_channel::_state, analog_callwait(), analog_defaultcic, analog_defaultozz, analog_dial_digits(), ANALOG_DIAL_OP_REPLACE, analog_get_index(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_set_cadence(), analog_set_dialing(), analog_set_waitingfordt(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_start(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE, analog_pvt::answeronpolarityswitch, AST_CONTROL_BUSY, AST_CONTROL_RINGING, ast_copy_string(), ast_debug, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_tvnow(), analog_pvt::callwait_name, analog_pvt::callwait_num, analog_pvt::callwaitcas, analog_pvt::channel, analog_pvt::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::connected, analog_pvt::dialdest, analog_pvt::dialednone, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, analog_pvt::finaldial, analog_pvt::hanguponpolarityswitch, ast_party_connected_line::id, analog_pvt::lastcid_name, analog_pvt::lastcid_num, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_party_id::name, ast_party_id::number, analog_dialoperation::op, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, pbx_builtin_getvar_helper(), analog_pvt::polaritydelaytv, analog_pvt::pulse, analog_pvt::sig, analog_pvt::stripmsd, analog_pvt::subs, analog_pvt::use_callerid, and analog_pvt::whichwink.
Referenced by dahdi_call().
00838 { 00839 int res, index,mysig; 00840 char *c, *n, *l; 00841 char dest[256]; /* must be same length as p->dialdest */ 00842 00843 ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n", ast->connected.id.name, ast->connected.id.number); 00844 00845 ast_copy_string(dest, rdest, sizeof(dest)); 00846 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 00847 00848 if ((ast->_state == AST_STATE_BUSY)) { 00849 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_BUSY); 00850 return 0; 00851 } 00852 00853 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 00854 ast_log(LOG_WARNING, "analog_call called on %s, neither down nor reserved\n", ast->name); 00855 return -1; 00856 } 00857 00858 p->dialednone = 0; 00859 00860 mysig = p->sig; 00861 if (p->outsigmod > -1) { 00862 mysig = p->outsigmod; 00863 } 00864 00865 switch (mysig) { 00866 case ANALOG_SIG_FXOLS: 00867 case ANALOG_SIG_FXOGS: 00868 case ANALOG_SIG_FXOKS: 00869 if (p->owner == ast) { 00870 /* Normal ring, on hook */ 00871 00872 /* Don't send audio while on hook, until the call is answered */ 00873 analog_set_dialing(p, 1); 00874 analog_set_cadence(p, ast); /* and set p->cidrings */ 00875 00876 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 00877 c = strchr(dest, '/'); 00878 if (c) { 00879 c++; 00880 } 00881 if (c && (strlen(c) < p->stripmsd)) { 00882 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 00883 c = NULL; 00884 } 00885 if (c) { 00886 p->dop.op = ANALOG_DIAL_OP_REPLACE; 00887 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 00888 ast_debug(1, "FXO: setup deferred dialstring: %s\n", c); 00889 } else { 00890 p->dop.dialstr[0] = '\0'; 00891 } 00892 00893 if (analog_ring(p)) { 00894 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 00895 return -1; 00896 } 00897 analog_set_dialing(p, 1); 00898 } else { 00899 if (ast->connected.id.number) { 00900 ast_copy_string(p->callwait_num, ast->connected.id.number, sizeof(p->callwait_num)); 00901 } else { 00902 p->callwait_num[0] = '\0'; 00903 } 00904 if (ast->connected.id.name) { 00905 ast_copy_string(p->callwait_name, ast->connected.id.name, sizeof(p->callwait_name)); 00906 } else { 00907 p->callwait_name[0] = '\0'; 00908 } 00909 00910 /* Call waiting tone instead */ 00911 if (analog_callwait(p)) { 00912 return -1; 00913 } 00914 /* Make ring-back */ 00915 if (analog_play_tone(p, ANALOG_SUB_CALLWAIT, ANALOG_TONE_RINGTONE)) { 00916 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 00917 } 00918 00919 } 00920 n = ast->connected.id.name; 00921 l = ast->connected.id.number; 00922 if (l) { 00923 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 00924 } else { 00925 p->lastcid_num[0] = '\0'; 00926 } 00927 if (n) { 00928 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 00929 } else { 00930 p->lastcid_name[0] = '\0'; 00931 } 00932 00933 if (p->use_callerid) { 00934 p->callwaitcas = 0; 00935 p->cid.cid_name = p->lastcid_name; 00936 p->cid.cid_num = p->lastcid_num; 00937 } 00938 00939 ast_setstate(ast, AST_STATE_RINGING); 00940 index = analog_get_index(ast, p, 0); 00941 if (index > -1) { 00942 ast_queue_control(p->subs[index].owner, AST_CONTROL_RINGING); 00943 } 00944 break; 00945 case ANALOG_SIG_FXSLS: 00946 case ANALOG_SIG_FXSGS: 00947 case ANALOG_SIG_FXSKS: 00948 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 00949 ast_debug(1, "Ignore possible polarity reversal on line seizure\n"); 00950 p->polaritydelaytv = ast_tvnow(); 00951 } 00952 /* fall through */ 00953 case ANALOG_SIG_EMWINK: 00954 case ANALOG_SIG_EM: 00955 case ANALOG_SIG_EM_E1: 00956 case ANALOG_SIG_FEATD: 00957 case ANALOG_SIG_FEATDMF: 00958 case ANALOG_SIG_E911: 00959 case ANALOG_SIG_FGC_CAMA: 00960 case ANALOG_SIG_FGC_CAMAMF: 00961 case ANALOG_SIG_FEATB: 00962 case ANALOG_SIG_SFWINK: 00963 case ANALOG_SIG_SF: 00964 case ANALOG_SIG_SF_FEATD: 00965 case ANALOG_SIG_SF_FEATDMF: 00966 case ANALOG_SIG_FEATDMF_TA: 00967 case ANALOG_SIG_SF_FEATB: 00968 c = strchr(dest, '/'); 00969 if (c) { 00970 c++; 00971 } else { 00972 c = ""; 00973 } 00974 if (strlen(c) < p->stripmsd) { 00975 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 00976 return -1; 00977 } 00978 res = analog_start(p); 00979 if (res < 0) { 00980 if (errno != EINPROGRESS) { 00981 return -1; 00982 } 00983 } 00984 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 00985 p->dop.op = ANALOG_DIAL_OP_REPLACE; 00986 00987 c += p->stripmsd; 00988 00989 switch (mysig) { 00990 case ANALOG_SIG_FEATD: 00991 l = ast->connected.id.number; 00992 if (l) { 00993 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 00994 } else { 00995 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 00996 } 00997 break; 00998 case ANALOG_SIG_FEATDMF: 00999 l = ast->connected.id.number; 01000 if (l) { 01001 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 01002 } else { 01003 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 01004 } 01005 break; 01006 case ANALOG_SIG_FEATDMF_TA: 01007 { 01008 const char *cic = "", *ozz = ""; 01009 01010 /* If you have to go through a Tandem Access point you need to use this */ 01011 #ifndef STANDALONE 01012 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 01013 if (!ozz) { 01014 ozz = analog_defaultozz; 01015 } 01016 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 01017 if (!cic) { 01018 cic = analog_defaultcic; 01019 } 01020 #endif 01021 if (!ozz || !cic) { 01022 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 01023 return -1; 01024 } 01025 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 01026 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 01027 p->whichwink = 0; 01028 } 01029 break; 01030 case ANALOG_SIG_E911: 01031 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 01032 break; 01033 case ANALOG_SIG_FGC_CAMA: 01034 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 01035 break; 01036 case ANALOG_SIG_FGC_CAMAMF: 01037 case ANALOG_SIG_FEATB: 01038 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 01039 break; 01040 default: 01041 if (p->pulse) { 01042 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 01043 } else { 01044 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 01045 } 01046 break; 01047 } 01048 01049 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 01050 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 01051 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 01052 p->echorest[sizeof(p->echorest) - 1] = '\0'; 01053 p->echobreak = 1; 01054 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 01055 } else { 01056 p->echobreak = 0; 01057 } 01058 analog_set_waitingfordt(p, ast); 01059 if (!res) { 01060 if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { 01061 int saveerr = errno; 01062 01063 analog_on_hook(p); 01064 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 01065 return -1; 01066 } 01067 } else { 01068 ast_debug(1, "Deferring dialing...\n"); 01069 } 01070 analog_set_dialing(p, 1); 01071 if (ast_strlen_zero(c)) { 01072 p->dialednone = 1; 01073 } 01074 ast_setstate(ast, AST_STATE_DIALING); 01075 break; 01076 default: 01077 ast_debug(1, "not yet implemented\n"); 01078 return -1; 01079 } 01080 return 0; 01081 }
| static int analog_callwait | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 735 of file sig_analog.c.
References analog_pvt::calls, analog_callback::callwait, analog_pvt::callwaitcas, analog_pvt::callwaitingcallerid, and analog_pvt::chan_pvt.
Referenced by analog_call().
00736 { 00737 if (p->callwaitingcallerid) { 00738 p->callwaitcas = 1; 00739 } 00740 if (p->calls->callwait) { 00741 return p->calls->callwait(p->chan_pvt); 00742 } 00743 return 0; 00744 }
| static void analog_cancel_cidspill | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 803 of file sig_analog.c.
References analog_pvt::calls, analog_callback::cancel_cidspill, and analog_pvt::chan_pvt.
Referenced by __analog_handle_event(), and analog_handle_init_event().
00804 { 00805 if (!p->calls->cancel_cidspill) { 00806 return; 00807 } 00808 00809 p->calls->cancel_cidspill(p->chan_pvt); 00810 }
| static void analog_cb_handle_dtmfup | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast, | |||
| enum analog_sub | analog_index, | |||
| struct ast_frame ** | dest | |||
| ) | [static] |
Definition at line 521 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::handle_dtmfup.
Referenced by analog_handle_dtmfup().
00522 { 00523 if (p->calls->handle_dtmfup) { 00524 p->calls->handle_dtmfup(p->chan_pvt, ast, analog_index, dest); 00525 } 00526 }
| static int analog_check_confirmanswer | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 794 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::check_confirmanswer.
Referenced by __analog_handle_event(), and analog_handle_dtmfup().
00795 { 00796 if (p->calls->check_confirmanswer) { 00797 return p->calls->check_confirmanswer(p->chan_pvt); 00798 } 00799 00800 return 0; 00801 }
| static int analog_check_for_conference | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 476 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::check_for_conference.
Referenced by __analog_handle_event().
00477 { 00478 if (p->calls->check_for_conference) { 00479 return p->calls->check_for_conference(p->chan_pvt); 00480 } 00481 return -1; 00482 }
| static int analog_check_waitingfordt | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 777 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::check_waitingfordt.
Referenced by __analog_handle_event().
00778 { 00779 if (p->calls->check_waitingfordt) { 00780 return p->calls->check_waitingfordt(p->chan_pvt); 00781 } 00782 00783 return 0; 00784 }
| const char* analog_cidstart_to_str | ( | enum analog_cid_start | cid_start | ) |
Definition at line 203 of file sig_analog.c.
References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.
00204 { 00205 switch (cid_start) { 00206 case ANALOG_CID_START_RING: 00207 return "Ring"; 00208 case ANALOG_CID_START_POLARITY: 00209 return "Polarity"; 00210 case ANALOG_CID_START_POLARITY_IN: 00211 return "Polarity_In"; 00212 case ANALOG_CID_START_DTMF_NOALERT: 00213 return "DTMF"; 00214 } 00215 00216 return "Unknown"; 00217 }
| const char* analog_cidtype_to_str | ( | unsigned int | cid_type | ) |
| int analog_config_complete | ( | struct analog_pvt * | p | ) |
Definition at line 3525 of file sig_analog.c.
References ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, analog_pvt::callwaiting, analog_pvt::permcallwaiting, and analog_pvt::sig.
Referenced by mkintf().
03526 { 03527 /* No call waiting on non FXS channels */ 03528 if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) { 03529 p->permcallwaiting = 0; 03530 } 03531 03532 p->callwaiting = p->permcallwaiting; 03533 03534 return 0; 03535 }
| static int analog_confmute | ( | struct analog_pvt * | p, | |
| int | mute | |||
| ) | [static] |
Definition at line 812 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::confmute.
Referenced by __analog_handle_event().
00813 { 00814 if (p->calls->confmute) { 00815 return p->calls->confmute(p->chan_pvt, mute); 00816 } 00817 return 0; 00818 }
| static int analog_decrease_ss_count | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 1426 of file sig_analog.c.
References analog_pvt::calls, and analog_callback::decrease_ss_count.
Referenced by __analog_ss_thread().
01427 { 01428 if (p->calls->decrease_ss_count) { 01429 p->calls->decrease_ss_count(); 01430 return 0; 01431 } 01432 return -1; 01433 }
| void analog_delete | ( | struct analog_pvt * | doomed | ) |
Delete the analog private structure.
| doomed | Analog private structure to delete. |
Definition at line 3520 of file sig_analog.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
03521 { 03522 ast_free(doomed); 03523 }
| static int analog_dial_digits | ( | struct analog_pvt * | p, | |
| enum analog_sub | sub, | |||
| struct analog_dialoperation * | dop | |||
| ) | [static] |
Definition at line 460 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dial_digits.
Referenced by __analog_handle_event(), and analog_call().
00461 { 00462 if (p->calls->dial_digits) { 00463 return p->calls->dial_digits(p->chan_pvt, sub, dop); 00464 } 00465 return -1; 00466 }
| static int analog_distinctive_ring | ( | struct ast_channel * | chan, | |
| struct analog_pvt * | p, | |||
| int | idx, | |||
| int * | ringdata | |||
| ) | [static] |
Definition at line 1435 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::distinctive_ring.
Referenced by __analog_ss_thread().
01436 { 01437 if (p->calls->distinctive_ring) { 01438 return p->calls->distinctive_ring(chan, p->chan_pvt, idx, ringdata); 01439 } 01440 return -1; 01441 01442 }
| int analog_dnd | ( | struct analog_pvt * | p, | |
| int | flag | |||
| ) |
Definition at line 3561 of file sig_analog.c.
References ast_verb, analog_pvt::channel, analog_pvt::dnd, EVENT_FLAG_SYSTEM, and manager_event.
Referenced by dahdi_dnd().
03562 { 03563 if (flag == -1) { 03564 return p->dnd; 03565 } 03566 03567 p->dnd = flag; 03568 03569 ast_verb(3, "%s DND on channel %d\n", 03570 flag? "Enabled" : "Disabled", 03571 p->channel); 03572 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 03573 "Channel: DAHDI/%d\r\n" 03574 "Status: %s\r\n", p->channel, 03575 flag? "enabled" : "disabled"); 03576 03577 return 0; 03578 }
| static int analog_dsp_reset_and_flush_digits | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 378 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dsp_reset_and_flush_digits.
Referenced by __analog_ss_thread().
00379 { 00380 if (p->calls->dsp_reset_and_flush_digits) { 00381 return p->calls->dsp_reset_and_flush_digits(p->chan_pvt); 00382 } 00383 00384 /* Return 0 since I think this is unnecessary to do in most cases it is used. Mostly only for ast_dsp */ 00385 return 0; 00386 }
| static int analog_dsp_set_digitmode | ( | struct analog_pvt * | p, | |
| enum analog_dsp_digitmode | mode | |||
| ) | [static] |
Definition at line 513 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dsp_set_digitmode.
Referenced by __analog_ss_thread(), and analog_hangup().
00514 { 00515 if (p->calls->dsp_set_digitmode) { 00516 return p->calls->dsp_set_digitmode(p->chan_pvt, mode); 00517 } 00518 return -1; 00519 }
| static char* analog_event2str | ( | enum analog_event | event | ) | [static] |
Definition at line 219 of file sig_analog.c.
References ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, and ANALOG_EVENT_WINKFLASH.
Referenced by __analog_handle_event(), analog_exception(), and analog_handle_init_event().
00220 { 00221 char *res; 00222 switch (event) { 00223 case ANALOG_EVENT_ONHOOK: 00224 res = "ANALOG_EVENT_ONHOOK"; 00225 break; 00226 case ANALOG_EVENT_RINGOFFHOOK: 00227 res = "ANALOG_EVENT_RINGOFFHOOK"; 00228 break; 00229 case ANALOG_EVENT_WINKFLASH: 00230 res = "ANALOG_EVENT_WINKFLASH"; 00231 break; 00232 case ANALOG_EVENT_ALARM: 00233 res = "ANALOG_EVENT_ALARM"; 00234 break; 00235 case ANALOG_EVENT_NOALARM: 00236 res = "ANALOG_EVENT_NOALARM"; 00237 break; 00238 case ANALOG_EVENT_DIALCOMPLETE: 00239 res = "ANALOG_EVENT_DIALCOMPLETE"; 00240 break; 00241 case ANALOG_EVENT_HOOKCOMPLETE: 00242 res = "ANALOG_EVENT_HOOKCOMPLETE"; 00243 break; 00244 case ANALOG_EVENT_PULSE_START: 00245 res = "ANALOG_EVENT_PULSE_START"; 00246 break; 00247 case ANALOG_EVENT_POLARITY: 00248 res = "ANALOG_EVENT_POLARITY"; 00249 break; 00250 case ANALOG_EVENT_RINGBEGIN: 00251 res = "ANALOG_EVENT_RINGBEGIN"; 00252 break; 00253 case ANALOG_EVENT_EC_DISABLED: 00254 res = "ANALOG_EVENT_EC_DISABLED"; 00255 break; 00256 case ANALOG_EVENT_RINGERON: 00257 res = "ANALOG_EVENT_RINGERON"; 00258 break; 00259 case ANALOG_EVENT_RINGEROFF: 00260 res = "ANALOG_EVENT_RINGEROFF"; 00261 break; 00262 case ANALOG_EVENT_REMOVED: 00263 res = "ANALOG_EVENT_REMOVED"; 00264 break; 00265 case ANALOG_EVENT_NEONMWI_ACTIVE: 00266 res = "ANALOG_EVENT_NEONMWI_ACTIVE"; 00267 break; 00268 case ANALOG_EVENT_NEONMWI_INACTIVE: 00269 res = "ANALOG_EVENT_NEONMWI_INACTIVE"; 00270 break; 00271 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 00272 case ANALOG_EVENT_TX_CED_DETECTED: 00273 res = "ANALOG_EVENT_TX_CED_DETECTED"; 00274 break; 00275 case ANALOG_EVENT_RX_CED_DETECTED: 00276 res = "ANALOG_EVENT_RX_CED_DETECTED"; 00277 break; 00278 case ANALOG_EVENT_EC_NLP_DISABLED: 00279 res = "ANALOG_EVENT_EC_NLP_DISABLED"; 00280 break; 00281 case ANALOG_EVENT_EC_NLP_ENABLED: 00282 res = "ANALOG_EVENT_EC_NLP_ENABLED"; 00283 break; 00284 #endif 00285 case ANALOG_EVENT_PULSEDIGIT: 00286 res = "ANALOG_EVENT_PULSEDIGIT"; 00287 break; 00288 case ANALOG_EVENT_DTMFDOWN: 00289 res = "ANALOG_EVENT_DTMFDOWN"; 00290 break; 00291 case ANALOG_EVENT_DTMFUP: 00292 res = "ANALOG_EVENT_DTMFUP"; 00293 break; 00294 default: 00295 res = "UNKNOWN/OTHER"; 00296 break; 00297 } 00298 00299 return res; 00300 }
| struct ast_frame* analog_exception | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) | [read] |
Definition at line 3147 of file sig_analog.c.
References __analog_handle_event(), ast_channel::_state, analog_event2str(), ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_event(), analog_get_index(), analog_off_hook(), analog_ring(), analog_set_dialing(), analog_set_echocanceller(), analog_stop_callwait(), ANALOG_SUB_REAL, analog_update_conf(), ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_tv(), ast_verb, analog_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, analog_subchannel::f, f, ast_channel::fds, analog_pvt::flashtime, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, ast_channel::name, ast_frame::offset, analog_subchannel::owner, analog_pvt::owner, ast_frame::ptr, ast_frame::samples, ast_frame::src, ast_frame::subclass, and analog_pvt::subs.
Referenced by dahdi_exception(), and dahdi_read().
03148 { 03149 int res; 03150 int usedindex=-1; 03151 int index; 03152 struct ast_frame *f; 03153 03154 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 03155 03156 index = analog_get_index(ast, p, 1); 03157 03158 p->subs[index].f.frametype = AST_FRAME_NULL; 03159 p->subs[index].f.datalen = 0; 03160 p->subs[index].f.samples = 0; 03161 p->subs[index].f.mallocd = 0; 03162 p->subs[index].f.offset = 0; 03163 p->subs[index].f.subclass = 0; 03164 p->subs[index].f.delivery = ast_tv(0,0); 03165 p->subs[index].f.src = "dahdi_exception"; 03166 p->subs[index].f.data.ptr = NULL; 03167 03168 03169 if (!p->owner) { 03170 /* If nobody owns us, absorb the event appropriately, otherwise 03171 we loop indefinitely. This occurs when, during call waiting, the 03172 other end hangs up our channel so that it no longer exists, but we 03173 have neither FLASH'd nor ONHOOK'd to signify our desire to 03174 change to the other channel. */ 03175 res = analog_get_event(p); 03176 03177 /* Switch to real if there is one and this isn't something really silly... */ 03178 if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) && 03179 (res != ANALOG_EVENT_HOOKCOMPLETE)) { 03180 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res); 03181 p->owner = p->subs[ANALOG_SUB_REAL].owner; 03182 if (p->owner && ast_bridged_channel(p->owner)) { 03183 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 03184 } 03185 } 03186 switch (res) { 03187 case ANALOG_EVENT_ONHOOK: 03188 analog_set_echocanceller(p, 0); 03189 if (p->owner) { 03190 ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name); 03191 analog_ring(p); 03192 analog_stop_callwait(p); 03193 } else { 03194 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 03195 } 03196 analog_update_conf(p); 03197 break; 03198 case ANALOG_EVENT_RINGOFFHOOK: 03199 analog_set_echocanceller(p, 1); 03200 analog_off_hook(p); 03201 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 03202 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER); 03203 analog_set_dialing(p, 0); 03204 } 03205 break; 03206 case ANALOG_EVENT_HOOKCOMPLETE: 03207 case ANALOG_EVENT_RINGERON: 03208 case ANALOG_EVENT_RINGEROFF: 03209 /* Do nothing */ 03210 break; 03211 case ANALOG_EVENT_WINKFLASH: 03212 gettimeofday(&p->flashtime, NULL); 03213 if (p->owner) { 03214 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 03215 if (p->owner->_state != AST_STATE_UP) { 03216 /* Answer if necessary */ 03217 usedindex = analog_get_index(p->owner, p, 0); 03218 if (usedindex > -1) { 03219 ast_queue_control(p->subs[usedindex].owner, AST_CONTROL_ANSWER); 03220 } 03221 ast_setstate(p->owner, AST_STATE_UP); 03222 } 03223 analog_stop_callwait(p); 03224 if (ast_bridged_channel(p->owner)) { 03225 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 03226 } 03227 } else { 03228 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 03229 } 03230 analog_update_conf(p); 03231 break; 03232 default: 03233 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res)); 03234 } 03235 f = &p->subs[index].f; 03236 return f; 03237 } 03238 ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 03239 /* If it's not us, return NULL immediately */ 03240 if (ast != p->owner) { 03241 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 03242 f = &p->subs[index].f; 03243 return f; 03244 } 03245 f = __analog_handle_event(p, ast); 03246 return f; 03247 }
| int analog_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan, | |||
| void * | newp | |||
| ) |
Definition at line 3543 of file sig_analog.c.
References analog_update_conf(), ast_debug, analog_pvt::channel, ast_channel::name, analog_subchannel::owner, analog_pvt::owner, and analog_pvt::subs.
Referenced by dahdi_fixup().
03544 { 03545 struct analog_pvt *new_pvt = newp; 03546 int x; 03547 ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name); 03548 if (new_pvt->owner == oldchan) { 03549 new_pvt->owner = newchan; 03550 } 03551 for (x = 0; x < 3; x++) { 03552 if (new_pvt->subs[x].owner == oldchan) { 03553 new_pvt->subs[x].owner = newchan; 03554 } 03555 } 03556 03557 analog_update_conf(new_pvt); 03558 return 0; 03559 }
| static int analog_flash | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 444 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::flash.
Referenced by __analog_ss_thread().
00445 { 00446 if (p->calls->flash) { 00447 return p->calls->flash(p->chan_pvt); 00448 } 00449 return -1; 00450 }
| void analog_free | ( | struct analog_pvt * | p | ) |
| static void analog_get_and_handle_alarms | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 1444 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_and_handle_alarms.
Referenced by __analog_handle_event(), and analog_handle_init_event().
01445 { 01446 if (p->calls->get_and_handle_alarms) { 01447 return p->calls->get_and_handle_alarms(p->chan_pvt); 01448 } 01449 }
| static void* analog_get_bridged_channel | ( | struct analog_pvt * | p, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 1451 of file sig_analog.c.
References analog_pvt::calls, and analog_callback::get_sigpvt_bridged_channel.
Referenced by __analog_ss_thread().
01452 { 01453 if (p->calls->get_sigpvt_bridged_channel) { 01454 return p->calls->get_sigpvt_bridged_channel; 01455 } 01456 return NULL; 01457 }
| static int analog_get_callerid | ( | struct analog_pvt * | p, | |
| char * | name, | |||
| char * | number, | |||
| enum analog_event * | ev, | |||
| size_t | timeout | |||
| ) | [static] |
Definition at line 164 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_callerid.
Referenced by __analog_ss_thread().
00165 { 00166 if (p->calls->get_callerid) { 00167 return p->calls->get_callerid(p->chan_pvt, name, number, ev, timeout); 00168 } 00169 return -1; 00170 }
| static int analog_get_event | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 172 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_event.
Referenced by __analog_handle_event(), and analog_exception().
00173 { 00174 if (p->calls->get_event) { 00175 return p->calls->get_event(p->chan_pvt); 00176 } 00177 return -1; 00178 }
| static int analog_get_index | ( | struct ast_channel * | ast, | |
| struct analog_pvt * | p, | |||
| int | nullok | |||
| ) | [static] |
Definition at line 360 of file sig_analog.c.
References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_log(), LOG_WARNING, analog_subchannel::owner, and analog_pvt::subs.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_call(), analog_exception(), and analog_hangup().
00361 { 00362 int res; 00363 if (p->subs[ANALOG_SUB_REAL].owner == ast) { 00364 res = ANALOG_SUB_REAL; 00365 } else if (p->subs[ANALOG_SUB_CALLWAIT].owner == ast) { 00366 res = ANALOG_SUB_CALLWAIT; 00367 } else if (p->subs[ANALOG_SUB_THREEWAY].owner == ast) { 00368 res = ANALOG_SUB_THREEWAY; 00369 } else { 00370 res = -1; 00371 if (!nullok) { 00372 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00373 } 00374 } 00375 return res; 00376 }
| static int analog_get_sub_fd | ( | struct analog_pvt * | p, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 1459 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_sub_fd.
Referenced by __analog_handle_event().
01460 { 01461 if (p->calls->get_sub_fd) { 01462 return p->calls->get_sub_fd(p->chan_pvt, sub); 01463 } 01464 return -1; 01465 }
| void analog_handle_dtmfup | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast, | |||
| enum analog_sub | index, | |||
| struct ast_frame ** | dest | |||
| ) |
Definition at line 1357 of file sig_analog.c.
References analog_cb_handle_dtmfup(), analog_check_confirmanswer(), analog_handles_digit(), analog_send_callerid(), analog_set_confirmanswer(), AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), analog_pvt::callwait_name, analog_pvt::callwait_num, analog_pvt::callwaitcas, analog_pvt::cid, ast_callerid::cid_name, ast_callerid::cid_num, analog_subchannel::f, f, ast_frame::frametype, LOG_ERROR, ast_channel::name, ast_frame::subclass, and analog_pvt::subs.
Referenced by __analog_handle_event(), and dahdi_read().
01358 { 01359 struct ast_frame *f = *dest; 01360 01361 if (analog_check_confirmanswer(p)) { 01362 ast_debug(1, "Confirm answer on %s!\n", ast->name); 01363 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 01364 of a DTMF digit */ 01365 p->subs[index].f.frametype = AST_FRAME_CONTROL; 01366 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 01367 *dest = &p->subs[index].f; 01368 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 01369 analog_set_confirmanswer(p, 0); 01370 } 01371 if (p->callwaitcas) { 01372 if ((f->subclass == 'A') || (f->subclass == 'D')) { 01373 ast_log(LOG_ERROR, "Got some DTMF, but it's for the CAS\n"); 01374 p->cid.cid_name = p->callwait_name; 01375 p->cid.cid_num = p->callwait_num; 01376 analog_send_callerid(p, 1, &p->cid); 01377 } 01378 if (analog_handles_digit(f)) 01379 p->callwaitcas = 0; 01380 p->subs[index].f.frametype = AST_FRAME_NULL; 01381 p->subs[index].f.subclass = 0; 01382 *dest = &p->subs[index].f; 01383 } else { 01384 analog_cb_handle_dtmfup(p, ast, index, dest); 01385 } 01386 }
| void* analog_handle_init_event | ( | struct analog_pvt * | i, | |
| int | event | |||
| ) |
Definition at line 3249 of file sig_analog.c.
References __analog_ss_thread(), analog_cancel_cidspill(), ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, analog_event2str(), ANALOG_EVENT_ALARM, ANALOG_EVENT_DTMFCID, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_and_handle_alarms(), analog_handle_notify_message(), analog_has_voicemail(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_echocanceller(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_sigtype_to_str(), ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALTONE, ANALOG_TONE_RINGTONE, ANALOG_TONE_STUTTER, ast_debug, ast_hangup(), ast_log(), ast_pthread_create_detached, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose, chan, analog_pvt::chan_pvt, analog_pvt::channel, analog_pvt::cid_start, errno, EVENT_FLAG_SYSTEM, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, analog_pvt::immediate, analog_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event, analog_pvt::polarity, POLARITY_REV, analog_pvt::ringt_base, analog_pvt::sig, analog_pvt::ss_astchan, analog_pvt::unknown_alarm, and VERBOSE_PREFIX_2.
Referenced by do_monitor().
03250 { 03251 int res; 03252 pthread_t threadid; 03253 struct ast_channel *chan; 03254 03255 ast_debug(1, "channel (%d) - signaling (%d) - event (%s)\n", 03256 i->channel, i->sig, analog_event2str(event)); 03257 03258 /* Handle an event on a given channel for the monitor thread. */ 03259 switch (event) { 03260 case ANALOG_EVENT_WINKFLASH: 03261 case ANALOG_EVENT_RINGOFFHOOK: 03262 if (i->inalarm) { 03263 break; 03264 } 03265 /* Got a ring/answer. What kind of channel are we? */ 03266 switch (i->sig) { 03267 case ANALOG_SIG_FXOLS: 03268 case ANALOG_SIG_FXOGS: 03269 case ANALOG_SIG_FXOKS: 03270 res = analog_off_hook(i); 03271 i->fxsoffhookstate = 1; 03272 if (res && (errno == EBUSY)) { 03273 break; 03274 } 03275 analog_cancel_cidspill(i); 03276 if (i->immediate) { 03277 analog_set_echocanceller(i, 1); 03278 /* The channel is immediately up. Start right away */ 03279 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE); 03280 chan = analog_new_ast_channel(i, AST_STATE_RING, 1, ANALOG_SUB_REAL, NULL); 03281 if (!chan) { 03282 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 03283 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03284 if (res < 0) { 03285 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03286 } 03287 } 03288 } else { 03289 /* Check for callerid, digits, etc */ 03290 chan = analog_new_ast_channel(i, AST_STATE_RESERVED, 0, ANALOG_SUB_REAL, NULL); 03291 i->ss_astchan = chan; 03292 if (chan) { 03293 if (analog_has_voicemail(i)) { 03294 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER); 03295 } else { 03296 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE); 03297 } 03298 if (res < 0) 03299 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 03300 03301 if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03302 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03303 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03304 if (res < 0) { 03305 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03306 } 03307 ast_hangup(chan); 03308 } 03309 } else 03310 ast_log(LOG_WARNING, "Unable to create channel\n"); 03311 } 03312 break; 03313 case ANALOG_SIG_FXSLS: 03314 case ANALOG_SIG_FXSGS: 03315 case ANALOG_SIG_FXSKS: 03316 analog_set_ringtimeout(i, i->ringt_base); 03317 /* Fall through */ 03318 case ANALOG_SIG_EMWINK: 03319 case ANALOG_SIG_FEATD: 03320 case ANALOG_SIG_FEATDMF: 03321 case ANALOG_SIG_FEATDMF_TA: 03322 case ANALOG_SIG_E911: 03323 case ANALOG_SIG_FGC_CAMA: 03324 case ANALOG_SIG_FGC_CAMAMF: 03325 case ANALOG_SIG_FEATB: 03326 case ANALOG_SIG_EM: 03327 case ANALOG_SIG_EM_E1: 03328 case ANALOG_SIG_SFWINK: 03329 case ANALOG_SIG_SF_FEATD: 03330 case ANALOG_SIG_SF_FEATDMF: 03331 case ANALOG_SIG_SF_FEATB: 03332 case ANALOG_SIG_SF: 03333 /* Check for callerid, digits, etc */ 03334 if (i->cid_start == ANALOG_CID_START_POLARITY_IN || i->cid_start == ANALOG_CID_START_DTMF_NOALERT) { 03335 chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL); 03336 } else { 03337 chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL); 03338 } 03339 i->ss_astchan = chan; 03340 if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03341 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03342 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03343 if (res < 0) { 03344 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03345 } 03346 ast_hangup(chan); 03347 } else if (!chan) { 03348 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 03349 } 03350 break; 03351 default: 03352 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", analog_sigtype_to_str(i->sig), i->channel); 03353 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03354 if (res < 0) { 03355 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03356 } 03357 return NULL; 03358 } 03359 break; 03360 case ANALOG_EVENT_NOALARM: 03361 i->inalarm = 0; 03362 if (!i->unknown_alarm) { 03363 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 03364 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 03365 "Channel: %d\r\n", i->channel); 03366 } else { 03367 i->unknown_alarm = 0; 03368 } 03369 break; 03370 case ANALOG_EVENT_ALARM: 03371 i->inalarm = 1; 03372 analog_get_and_handle_alarms(i); 03373 03374 /* fall thru intentionally */ 03375 case ANALOG_EVENT_ONHOOK: 03376 /* Back on hook. Hang up. */ 03377 switch (i->sig) { 03378 case ANALOG_SIG_FXOLS: 03379 case ANALOG_SIG_FXOGS: 03380 i->fxsoffhookstate = 0; 03381 case ANALOG_SIG_FEATD: 03382 case ANALOG_SIG_FEATDMF: 03383 case ANALOG_SIG_FEATDMF_TA: 03384 case ANALOG_SIG_E911: 03385 case ANALOG_SIG_FGC_CAMA: 03386 case ANALOG_SIG_FGC_CAMAMF: 03387 case ANALOG_SIG_FEATB: 03388 case ANALOG_SIG_EM: 03389 case ANALOG_SIG_EM_E1: 03390 case ANALOG_SIG_EMWINK: 03391 case ANALOG_SIG_SF_FEATD: 03392 case ANALOG_SIG_SF_FEATDMF: 03393 case ANALOG_SIG_SF_FEATB: 03394 case ANALOG_SIG_SF: 03395 case ANALOG_SIG_SFWINK: 03396 case ANALOG_SIG_FXSLS: 03397 case ANALOG_SIG_FXSGS: 03398 case ANALOG_SIG_FXSKS: 03399 analog_set_echocanceller(i, 0); 03400 res = analog_play_tone(i, ANALOG_SUB_REAL, -1); 03401 analog_on_hook(i); 03402 break; 03403 case ANALOG_SIG_FXOKS: 03404 i->fxsoffhookstate = 0; 03405 analog_set_echocanceller(i, 0); 03406 /* Diddle the battery for the zhone */ 03407 #ifdef ZHONE_HACK 03408 analog_off_hook(i); 03409 usleep(1); 03410 #endif 03411 res = analog_play_tone(i, ANALOG_SUB_REAL, -1); 03412 analog_on_hook(i); 03413 break; 03414 default: 03415 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", analog_sigtype_to_str(i->sig), i->channel); 03416 res = analog_play_tone(i, ANALOG_SUB_REAL, -1); 03417 return NULL; 03418 } 03419 break; 03420 case ANALOG_EVENT_POLARITY: 03421 switch (i->sig) { 03422 case ANALOG_SIG_FXSLS: 03423 case ANALOG_SIG_FXSKS: 03424 case ANALOG_SIG_FXSGS: 03425 /* We have already got a PR before the channel was 03426 created, but it wasn't handled. We need polarity 03427 to be REV for remote hangup detection to work. 03428 At least in Spain */ 03429 if (i->hanguponpolarityswitch) { 03430 i->polarity = POLARITY_REV; 03431 } 03432 03433 if (i->cid_start == ANALOG_CID_START_POLARITY || i->cid_start == ANALOG_CID_START_POLARITY_IN) { 03434 i->polarity = POLARITY_REV; 03435 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 03436 "CID detection on channel %d\n", 03437 i->channel); 03438 chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL); 03439 i->ss_astchan = chan; 03440 if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03441 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03442 } 03443 } 03444 break; 03445 default: 03446 ast_log(LOG_WARNING, "handle_init_event detected " 03447 "polarity reversal on non-FXO (ANALOG_SIG_FXS) " 03448 "interface %d\n", i->channel); 03449 } 03450 break; 03451 case ANALOG_EVENT_DTMFCID: 03452 switch (i->sig) { 03453 case ANALOG_SIG_FXSLS: 03454 case ANALOG_SIG_FXSKS: 03455 case ANALOG_SIG_FXSGS: 03456 if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) { 03457 ast_verbose(VERBOSE_PREFIX_2 "Starting DTMF CID detection on channel %d\n", 03458 i->channel); 03459 chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL); 03460 i->ss_astchan = chan; 03461 if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03462 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03463 } 03464 } 03465 break; 03466 default: 03467 ast_log(LOG_WARNING, "handle_init_event detected " 03468 "dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) " 03469 "interface %d\n", i->channel); 03470 } 03471 break; 03472 case ANALOG_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */ 03473 ast_log(LOG_NOTICE, 03474 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n", 03475 i->channel); 03476 return i->chan_pvt; 03477 break; 03478 case ANALOG_EVENT_NEONMWI_ACTIVE: 03479 analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_ACTIVE); 03480 break; 03481 case ANALOG_EVENT_NEONMWI_INACTIVE: 03482 analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_INACTIVE); 03483 break; 03484 } 03485 return NULL; 03486 }
| static int analog_handle_notify_message | ( | struct ast_channel * | chan, | |
| struct analog_pvt * | p, | |||
| int | cid_flags, | |||
| int | neon_mwievent | |||
| ) | [static] |
Definition at line 1408 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::handle_notify_message.
Referenced by __analog_ss_thread(), and analog_handle_init_event().
01409 { 01410 if (p->calls->handle_notify_message) { 01411 p->calls->handle_notify_message(chan, p->chan_pvt, cid_flags, neon_mwievent); 01412 return 0; 01413 } 01414 return -1; 01415 }
| static int analog_handles_digit | ( | struct ast_frame * | f | ) | [static] |
Definition at line 1332 of file sig_analog.c.
References ast_frame::subclass.
Referenced by analog_handle_dtmfup().
01333 { 01334 char subclass = toupper(f->subclass); 01335 01336 switch (subclass) { 01337 case '1': 01338 case '2': 01339 case '3': 01340 case '4': 01341 case '5': 01342 case '6': 01343 case '7': 01344 case '9': 01345 case 'A': 01346 case 'B': 01347 case 'C': 01348 case 'D': 01349 case 'E': 01350 case 'F': 01351 return 1; 01352 default: 01353 return 0; 01354 } 01355 }
| int analog_hangup | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) |
Definition at line 1083 of file sig_analog.c.
References ast_channel::_state, analog_subchannel::allocd, analog_all_subchannels_hungup(), ANALOG_DIGITMODE_DTMF, analog_dsp_set_digitmode(), analog_get_index(), analog_is_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_confirmanswer(), analog_set_dialing(), analog_set_echocanceller(), analog_set_linear_mode(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, analog_unalloc_sub(), analog_update_conf(), ast_bridged_channel(), ast_channel_setoption(), AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_log(), AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), ast_verb, analog_pvt::callwaitcas, analog_pvt::callwaiting, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, analog_pvt::cidrings, free, analog_pvt::guardtime, analog_pvt::hidecallerid, analog_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, analog_pvt::mohsuggest, ast_channel::name, analog_pvt::onhooktime, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::outgoing, analog_pvt::owner, analog_subchannel::owner, analog_pvt::permcallwaiting, analog_pvt::permhidecallerid, analog_pvt::polarity, POLARITY_IDLE, S_OR, analog_pvt::sig, analog_pvt::subs, and ast_channel::tech_pvt.
Referenced by dahdi_hangup().
01084 { 01085 int res; 01086 int index, x; 01087 01088 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 01089 if (!ast->tech_pvt) { 01090 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 01091 return 0; 01092 } 01093 01094 index = analog_get_index(ast, p, 1); 01095 01096 x = 0; 01097 if (p->origcid_num) { 01098 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 01099 free(p->origcid_num); 01100 p->origcid_num = NULL; 01101 } 01102 if (p->origcid_name) { 01103 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 01104 free(p->origcid_name); 01105 p->origcid_name = NULL; 01106 } 01107 01108 analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF); 01109 01110 ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 01111 p->channel, index, p->subs[ANALOG_SUB_REAL].allocd, p->subs[ANALOG_SUB_CALLWAIT].allocd, p->subs[ANALOG_SUB_THREEWAY].allocd); 01112 if (index > -1) { 01113 /* Real channel, do some fixup */ 01114 p->subs[index].owner = NULL; 01115 p->polarity = POLARITY_IDLE; 01116 analog_set_linear_mode(p, index, 0); 01117 if (index == ANALOG_SUB_REAL) { 01118 if (p->subs[ANALOG_SUB_CALLWAIT].allocd && p->subs[ANALOG_SUB_THREEWAY].allocd) { 01119 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n"); 01120 if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) { 01121 /* We had flipped over to answer a callwait and now it's gone */ 01122 ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n"); 01123 /* Move to the call-wait, but un-own us until they flip back. */ 01124 analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL); 01125 analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT); 01126 p->owner = NULL; 01127 } else { 01128 /* The three way hung up, but we still have a call wait */ 01129 ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 01130 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 01131 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 01132 if (p->subs[ANALOG_SUB_REAL].inthreeway) { 01133 /* This was part of a three way call. Immediately make way for 01134 another call */ 01135 ast_debug(1, "Call was complete, setting owner to former third call\n"); 01136 p->owner = p->subs[ANALOG_SUB_REAL].owner; 01137 } else { 01138 /* This call hasn't been completed yet... Set owner to NULL */ 01139 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 01140 p->owner = NULL; 01141 } 01142 p->subs[ANALOG_SUB_REAL].inthreeway = 0; 01143 } 01144 } else if (p->subs[ANALOG_SUB_CALLWAIT].allocd) { 01145 /* Move to the call-wait and switch back to them. */ 01146 analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL); 01147 analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT); 01148 p->owner = p->subs[ANALOG_SUB_REAL].owner; 01149 if (p->owner->_state != AST_STATE_UP) { 01150 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER); 01151 } 01152 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 01153 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 01154 } 01155 } else if (p->subs[ANALOG_SUB_THREEWAY].allocd) { 01156 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 01157 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 01158 if (p->subs[ANALOG_SUB_REAL].inthreeway) { 01159 /* This was part of a three way call. Immediately make way for 01160 another call */ 01161 ast_debug(1, "Call was complete, setting owner to former third call\n"); 01162 p->owner = p->subs[ANALOG_SUB_REAL].owner; 01163 } else { 01164 /* This call hasn't been completed yet... Set owner to NULL */ 01165 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 01166 p->owner = NULL; 01167 } 01168 p->subs[ANALOG_SUB_REAL].inthreeway = 0; 01169 } 01170 } else if (index == ANALOG_SUB_CALLWAIT) { 01171 /* Ditch the holding callwait call, and immediately make it availabe */ 01172 if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) { 01173 /* This is actually part of a three way, placed on hold. Place the third part 01174 on music on hold now */ 01175 if (p->subs[ANALOG_SUB_THREEWAY].owner && ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) { 01176 ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD, 01177 S_OR(p->mohsuggest, NULL), 01178 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 01179 } 01180 p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0; 01181 /* Make it the call wait now */ 01182 analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY); 01183 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 01184 } else { 01185 analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT); 01186 } 01187 } else if (index == ANALOG_SUB_THREEWAY) { 01188 if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) { 01189 /* The other party of the three way call is currently in a call-wait state. 01190 Start music on hold for them, and take the main guy out of the third call */ 01191 if (p->subs[ANALOG_SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) { 01192 ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 01193 S_OR(p->mohsuggest, NULL), 01194 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 01195 } 01196 p->subs[ANALOG_SUB_CALLWAIT].inthreeway = 0; 01197 } 01198 p->subs[ANALOG_SUB_REAL].inthreeway = 0; 01199 /* If this was part of a three way call index, let us make 01200 another three way call */ 01201 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 01202 } else { 01203 /* This wasn't any sort of call, but how are we an index? */ 01204 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 01205 } 01206 } 01207 01208 if (!p->subs[ANALOG_SUB_REAL].owner && !p->subs[ANALOG_SUB_CALLWAIT].owner && !p->subs[ANALOG_SUB_THREEWAY].owner) { 01209 p->owner = NULL; 01210 analog_set_ringtimeout(p, 0); 01211 analog_set_confirmanswer(p, 0); 01212 analog_set_pulsedial(p, 0); 01213 p->outgoing = 0; 01214 p->onhooktime = time(NULL); 01215 p->cidrings = 1; 01216 01217 /* Perform low level hangup if no owner left */ 01218 res = analog_on_hook(p); 01219 if (res < 0) { 01220 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 01221 } 01222 switch (p->sig) { 01223 case ANALOG_SIG_FXOGS: 01224 case ANALOG_SIG_FXOLS: 01225 case ANALOG_SIG_FXOKS: 01226 /* If they're off hook, try playing congestion */ 01227 if (analog_is_off_hook(p)) { 01228 analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 01229 } else { 01230 analog_play_tone(p, ANALOG_SUB_REAL, -1); 01231 } 01232 break; 01233 case ANALOG_SIG_FXSGS: 01234 case ANALOG_SIG_FXSLS: 01235 case ANALOG_SIG_FXSKS: 01236 /* Make sure we're not made available for at least two seconds assuming 01237 we were actually used for an inbound or outbound call. */ 01238 if (ast->_state != AST_STATE_RESERVED) { 01239 time(&p->guardtime); 01240 p->guardtime += 2; 01241 } 01242 break; 01243 default: 01244 analog_play_tone(p, ANALOG_SUB_REAL, -1); 01245 } 01246 01247 analog_set_echocanceller(p, 0); 01248 01249 x = 0; 01250 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 01251 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 01252 p->callwaitcas = 0; 01253 p->callwaiting = p->permcallwaiting; 01254 p->hidecallerid = p->permhidecallerid; 01255 analog_set_dialing(p, 0); 01256 analog_update_conf(p); 01257 analog_all_subchannels_hungup(p); 01258 } 01259 01260 analog_stop_callwait(p); 01261 ast->tech_pvt = NULL; 01262 01263 ast_verb(3, "Hanging up on '%s'\n", ast->name); 01264 01265 return 0; 01266 }
| static int analog_has_voicemail | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 536 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::has_voicemail.
Referenced by __analog_handle_event(), and analog_handle_init_event().
00537 { 00538 if (p->calls->has_voicemail) { 00539 return p->calls->has_voicemail(p->chan_pvt); 00540 } 00541 return -1; 00542 }
| static int analog_increase_ss_count | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 1417 of file sig_analog.c.
References analog_pvt::calls, and analog_callback::increase_ss_count.
Referenced by __analog_ss_thread().
01418 { 01419 if (p->calls->increase_ss_count) { 01420 p->calls->increase_ss_count(); 01421 return 0; 01422 } 01423 return -1; 01424 }
| static int analog_is_dialing | ( | struct analog_pvt * | p, | |
| enum analog_sub | index | |||
| ) | [static] |
Definition at line 544 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::is_dialing.
Referenced by __analog_handle_event().
00545 { 00546 if (p->calls->is_dialing) { 00547 return p->calls->is_dialing(p->chan_pvt, index); 00548 } 00549 return -1; 00550 }
| static int analog_is_off_hook | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 428 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::is_off_hook.
Referenced by analog_available(), and analog_hangup().
00429 { 00430 if (p->calls->is_off_hook) { 00431 return p->calls->is_off_hook(p->chan_pvt); 00432 } 00433 return -1; 00434 }
| static void analog_lock_private | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 498 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::lock_private.
Referenced by __analog_handle_event().
00499 { 00500 if (p->calls->lock_private) { 00501 p->calls->lock_private(p->chan_pvt); 00502 } 00503 }
| static int analog_my_getsigstr | ( | struct ast_channel * | chan, | |
| char * | str, | |||
| const char * | term, | |||
| int | ms | |||
| ) | [static] |
Definition at line 1388 of file sig_analog.c.
References ast_waitfordigit().
Referenced by __analog_ss_thread().
01389 { 01390 char c; 01391 01392 *str = 0; /* start with empty output buffer */ 01393 for (;;) { 01394 /* Wait for the first digit (up to specified ms). */ 01395 c = ast_waitfordigit(chan, ms); 01396 /* if timeout, hangup or error, return as such */ 01397 if (c < 1) { 01398 return c; 01399 } 01400 *str++ = c; 01401 *str = 0; 01402 if (strchr(term, c)) { 01403 return 1; 01404 } 01405 } 01406 }
| struct analog_pvt* analog_new | ( | enum analog_sigtype | signallingtype, | |
| struct analog_callback * | c, | |||
| void * | private_data | |||
| ) | [read] |
Definition at line 3489 of file sig_analog.c.
References analog_subchannel::allocd, ANALOG_CID_START_RING, ANALOG_SIG_NONE, ANALOG_SUB_REAL, ast_calloc, analog_pvt::calls, analog_pvt::chan_pvt, CID_SIG_BELL, analog_pvt::cid_signalling, analog_pvt::cid_start, analog_pvt::outsigmod, analog_pvt::sig, and analog_pvt::subs.
Referenced by mkintf().
03490 { 03491 struct analog_pvt *p; 03492 03493 p = ast_calloc(1, sizeof(*p)); 03494 if (!p) { 03495 return p; 03496 } 03497 03498 p->calls = c; 03499 p->outsigmod = ANALOG_SIG_NONE; 03500 p->sig = signallingtype; 03501 p->chan_pvt = private_data; 03502 03503 /* Some defaults for values */ 03504 p->cid_start = ANALOG_CID_START_RING; 03505 p->cid_signalling = CID_SIG_BELL; 03506 /* Sub real is assumed to always be alloc'd */ 03507 p->subs[ANALOG_SUB_REAL].allocd = 1; 03508 03509 return p; 03510 }
| static struct ast_channel* analog_new_ast_channel | ( | struct analog_pvt * | p, | |
| int | state, | |||
| int | startpbx, | |||
| enum analog_sub | sub, | |||
| const struct ast_channel * | requestor | |||
| ) | [static, read] |
Definition at line 396 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, analog_callback::new_ast_channel, analog_pvt::owner, analog_subchannel::owner, and analog_pvt::subs.
Referenced by __analog_handle_event(), analog_handle_init_event(), and analog_request().
00397 { 00398 struct ast_channel *c; 00399 00400 if (!p->calls->new_ast_channel) { 00401 return NULL; 00402 } 00403 00404 c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub, requestor); 00405 p->subs[sub].owner = c; 00406 if (!p->owner) { 00407 p->owner = c; 00408 } 00409 return c; 00410 }
| static int analog_off_hook | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 505 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::off_hook.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_exception(), and analog_handle_init_event().
00506 { 00507 if (p->calls->off_hook) { 00508 return p->calls->off_hook(p->chan_pvt); 00509 } 00510 return -1; 00511 }
| static int analog_on_hook | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 468 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::on_hook.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_call(), analog_handle_init_event(), and analog_hangup().
00469 { 00470 if (p->calls->on_hook) { 00471 return p->calls->on_hook(p->chan_pvt); 00472 } 00473 return -1; 00474 }
| static int analog_play_tone | ( | struct analog_pvt * | p, | |
| enum analog_sub | sub, | |||
| enum analog_tone | tone | |||
| ) | [static] |
Definition at line 388 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::play_tone.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_attempt_transfer(), analog_call(), analog_handle_init_event(), and analog_hangup().
00389 { 00390 if (p->calls->play_tone) { 00391 return p->calls->play_tone(p->chan_pvt, sub, tone); 00392 } 00393 return -1; 00394 }
| struct ast_channel* analog_request | ( | struct analog_pvt * | p, | |
| int * | callwait, | |||
| const struct ast_channel * | requestor | |||
| ) | [read] |
Definition at line 636 of file sig_analog.c.
References analog_alloc_sub(), analog_new_ast_channel(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ast_log(), AST_STATE_RESERVED, analog_pvt::channel, LOG_DEBUG, LOG_ERROR, and analog_pvt::owner.
Referenced by dahdi_request().
00637 { 00638 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 00639 *callwait = (p->owner != NULL); 00640 00641 if (p->owner) { 00642 if (analog_alloc_sub(p, ANALOG_SUB_CALLWAIT)) { 00643 ast_log(LOG_ERROR, "Unable to alloc subchannel\n"); 00644 return NULL; 00645 } 00646 } 00647 00648 return analog_new_ast_channel(p, AST_STATE_RESERVED, 0, p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor); 00649 }
| static int analog_ring | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 436 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::ring.
Referenced by __analog_handle_event(), analog_call(), and analog_exception().
00437 { 00438 if (p->calls->ring) { 00439 return p->calls->ring(p->chan_pvt); 00440 } 00441 return -1; 00442 }
| static int analog_send_callerid | ( | struct analog_pvt * | p, | |
| int | cwcid, | |||
| struct ast_callerid * | cid | |||
| ) | [static] |
Definition at line 346 of file sig_analog.c.
References ast_debug, analog_pvt::calls, analog_pvt::callwaitcas, analog_pvt::chan_pvt, ast_callerid::cid_name, ast_callerid::cid_num, and analog_callback::send_callerid.
Referenced by __analog_handle_event(), and analog_handle_dtmfup().
00347 { 00348 ast_debug(1, "Sending callerid. CID_NAME: '%s' CID_NUM: '%s'\n", cid->cid_name, cid->cid_num); 00349 00350 if (cwcid) { 00351 p->callwaitcas = 0; 00352 } 00353 00354 if (p->calls->send_callerid) { 00355 return p->calls->send_callerid(p->chan_pvt, cwcid, cid); 00356 } 00357 return 0; 00358 }
| static void analog_set_cadence | ( | struct analog_pvt * | p, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 746 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::cidrings, and analog_callback::set_cadence.
Referenced by analog_call().
00747 { 00748 if (p->calls->set_cadence) { 00749 return p->calls->set_cadence(p->chan_pvt, &p->cidrings, chan); 00750 } 00751 }
| static void analog_set_confirmanswer | ( | struct analog_pvt * | p, | |
| int | flag | |||
| ) | [static] |
Definition at line 786 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_confirmanswer.
Referenced by analog_handle_dtmfup(), and analog_hangup().
00787 { 00788 if (!p->calls->set_confirmanswer) { 00789 return; 00790 } 00791 p->calls->set_confirmanswer(p->chan_pvt, flag); 00792 }
| static void analog_set_dialing | ( | struct analog_pvt * | p, | |
| int | flag | |||
| ) | [static] |
Definition at line 753 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::dialing, and analog_callback::set_dialing.
Referenced by __analog_handle_event(), analog_answer(), analog_call(), analog_exception(), and analog_hangup().
00754 { 00755 p->dialing = flag; 00756 if (p->calls->set_dialing) { 00757 return p->calls->set_dialing(p->chan_pvt, flag); 00758 } 00759 }
| static int analog_set_echocanceller | ( | struct analog_pvt * | p, | |
| int | enable | |||
| ) | [static] |
Definition at line 412 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_echocanceller.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_exception(), analog_handle_init_event(), and analog_hangup().
00413 { 00414 if (p->calls->set_echocanceller) { 00415 return p->calls->set_echocanceller(p->chan_pvt, enable); 00416 } 00417 return -1; 00418 }
| static int analog_set_linear_mode | ( | struct analog_pvt * | p, | |
| int | index, | |||
| int | linear_mode | |||
| ) | [static] |
Definition at line 828 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_linear_mode.
Referenced by __analog_ss_thread(), and analog_hangup().
00829 { 00830 if (p->calls->set_linear_mode) { 00831 /* Return provides old linear_mode setting or error indication */ 00832 return p->calls->set_linear_mode(p->chan_pvt, index, linear_mode); 00833 } 00834 return -1; 00835 }
| static void analog_set_pulsedial | ( | struct analog_pvt * | p, | |
| int | flag | |||
| ) | [static] |
Definition at line 820 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_pulsedial.
Referenced by __analog_handle_event(), and analog_hangup().
00821 { 00822 if (!p->calls->set_pulsedial) { 00823 return; 00824 } 00825 p->calls->set_pulsedial(p->chan_pvt, flag); 00826 }
| static void analog_set_ringtimeout | ( | struct analog_pvt * | p, | |
| int | ringt | |||
| ) | [static] |
Definition at line 761 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::ringt, and analog_callback::set_ringtimeout.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_handle_init_event(), and analog_hangup().
00762 { 00763 p->ringt = ringt; 00764 if (!p->calls->set_ringtimeout) { 00765 return; 00766 } 00767 p->calls->set_ringtimeout(p->chan_pvt, ringt); 00768 }
| static void analog_set_waitingfordt | ( | struct analog_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 770 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_waitingfordt.
Referenced by analog_call().
00771 { 00772 if (p->calls->set_waitingfordt) { 00773 return p->calls->set_waitingfordt(p->chan_pvt, ast); 00774 } 00775 }
| const char* analog_sigtype_to_str | ( | enum analog_sigtype | sigtype | ) |
Definition at line 109 of file sig_analog.c.
References ARRAY_LEN, and sigtypes.
Referenced by __analog_ss_thread(), and analog_handle_init_event().
00110 { 00111 int i; 00112 00113 for (i = 0; i < ARRAY_LEN(sigtypes); i++) { 00114 if (sigtype == sigtypes[i].sigtype) { 00115 return sigtypes[i].name; 00116 } 00117 } 00118 00119 return "Unknown"; 00120 }
| int analog_ss_thread_start | ( | struct analog_pvt * | p, | |
| struct ast_channel * | chan | |||
| ) |
Definition at line 2332 of file sig_analog.c.
References __analog_ss_thread(), and ast_pthread_create_detached.
Referenced by mwi_thread().
02333 { 02334 pthread_t threadid; 02335 02336 return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p); 02337 }
| static int analog_start | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 452 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start.
Referenced by analog_call().
00453 { 00454 if (p->calls->start) { 00455 return p->calls->start(p->chan_pvt); 00456 } 00457 return -1; 00458 }
| static int analog_start_cid_detect | ( | struct analog_pvt * | p, | |
| int | cid_signalling | |||
| ) | [static] |
Definition at line 148 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start_cid_detect.
Referenced by __analog_ss_thread().
00149 { 00150 if (p->calls->start_cid_detect) { 00151 return p->calls->start_cid_detect(p->chan_pvt, cid_signalling); 00152 } 00153 return -1; 00154 }
| static int analog_stop_callwait | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 723 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::callwaitcas, analog_pvt::callwaitingcallerid, analog_pvt::chan_pvt, and analog_callback::stop_callwait.
Referenced by __analog_handle_event(), analog_exception(), and analog_hangup().
00724 { 00725 if (p->callwaitingcallerid) { 00726 p->callwaitcas = 0; 00727 } 00728 00729 if (p->calls->stop_callwait) { 00730 return p->calls->stop_callwait(p->chan_pvt); 00731 } 00732 return 0; 00733 }
| static int analog_stop_cid_detect | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 156 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::stop_cid_detect.
Referenced by __analog_ss_thread().
00157 { 00158 if (p->calls->stop_cid_detect) { 00159 return p->calls->stop_cid_detect(p->chan_pvt); 00160 } 00161 return -1; 00162 }
| enum analog_cid_start analog_str_to_cidstart | ( | const char * | value | ) |
Definition at line 188 of file sig_analog.c.
References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.
00189 { 00190 if (!strcasecmp(value, "ring")) { 00191 return ANALOG_CID_START_RING; 00192 } else if (!strcasecmp(value, "polarity")) { 00193 return ANALOG_CID_START_POLARITY; 00194 } else if (!strcasecmp(value, "polarity_in")) { 00195 return ANALOG_CID_START_POLARITY_IN; 00196 } else if (!strcasecmp(value, "dtmf")) { 00197 return ANALOG_CID_START_DTMF_NOALERT; 00198 } 00199 00200 return 0; 00201 }
| unsigned int analog_str_to_cidtype | ( | const char * | name | ) |
| enum analog_sigtype analog_str_to_sigtype | ( | const char * | name | ) |
| static void analog_swap_subs | ( | struct analog_pvt * | p, | |
| enum analog_sub | a, | |||
| enum analog_sub | b | |||
| ) | [static] |
Definition at line 302 of file sig_analog.c.
References ast_debug, analog_pvt::calls, analog_pvt::chan_pvt, analog_subchannel::inthreeway, analog_subchannel::owner, analog_pvt::subs, and analog_callback::swap_subs.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_attempt_transfer(), and analog_hangup().
00303 { 00304 int tinthreeway; 00305 struct ast_channel *towner; 00306 00307 ast_debug(1, "Swapping %d and %d\n", a, b); 00308 00309 towner = p->subs[a].owner; 00310 tinthreeway = p->subs[a].inthreeway; 00311 00312 p->subs[a].owner = p->subs[b].owner; 00313 p->subs[a].inthreeway = p->subs[b].inthreeway; 00314 00315 p->subs[b].owner = towner; 00316 p->subs[b].inthreeway = tinthreeway; 00317 00318 if (p->calls->swap_subs) { 00319 p->calls->swap_subs(p->chan_pvt, a, p->subs[a].owner, b, p->subs[b].owner); 00320 } 00321 }
| static int analog_train_echocanceller | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 420 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::train_echocanceller.
Referenced by __analog_handle_event(), and analog_answer().
00421 { 00422 if (p->calls->train_echocanceller) { 00423 return p->calls->train_echocanceller(p->chan_pvt); 00424 } 00425 return -1; 00426 }
| static int analog_unalloc_sub | ( | struct analog_pvt * | p, | |
| enum analog_sub | x | |||
| ) | [static] |
Definition at line 336 of file sig_analog.c.
References analog_subchannel::allocd, analog_pvt::calls, analog_pvt::chan_pvt, analog_subchannel::owner, analog_pvt::subs, and analog_callback::unallocate_sub.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_attempt_transfer(), and analog_hangup().
00337 { 00338 p->subs[x].allocd = 0; 00339 p->subs[x].owner = NULL; 00340 if (p->calls->unallocate_sub) { 00341 return p->calls->unallocate_sub(p->chan_pvt, x); 00342 } 00343 return 0; 00344 }
| static void analog_unlock_private | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 491 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::unlock_private.
Referenced by __analog_handle_event().
00492 { 00493 if (p->calls->unlock_private) { 00494 p->calls->unlock_private(p->chan_pvt); 00495 } 00496 }
| static int analog_update_conf | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 609 of file sig_analog.c.
References analog_subchannel::allocd, ast_debug, analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::channel, analog_callback::complete_conference_update, analog_callback::conf_add, analog_callback::conf_del, analog_subchannel::inthreeway, and analog_pvt::subs.
Referenced by __analog_handle_event(), analog_exception(), analog_fixup(), and analog_hangup().
00610 { 00611 int x; 00612 int needconf = 0; 00613 00614 /* Start with the obvious, general stuff */ 00615 for (x = 0; x < 3; x++) { 00616 /* Look for three way calls */ 00617 if ((p->subs[x].allocd) && p->subs[x].inthreeway) { 00618 if (p->calls->conf_add) { 00619 p->calls->conf_add(p->chan_pvt, x); 00620 } 00621 needconf++; 00622 } else { 00623 if (p->calls->conf_del) { 00624 p->calls->conf_del(p->chan_pvt, x); 00625 } 00626 } 00627 } 00628 ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 00629 00630 if (p->calls->complete_conference_update) { 00631 p->calls->complete_conference_update(p->chan_pvt, needconf); 00632 } 00633 return 0; 00634 }
| static int analog_wait_event | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 180 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::wait_event.
Referenced by __analog_ss_thread().
00181 { 00182 if (p->calls->wait_event) { 00183 return p->calls->wait_event(p->chan_pvt); 00184 } 00185 return -1; 00186 }
| static int analog_wink | ( | struct analog_pvt * | p, | |
| enum analog_sub | index | |||
| ) | [static] |
Definition at line 528 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::wink.
Referenced by __analog_ss_thread().
00529 { 00530 if (p->calls->wink) { 00531 return p->calls->wink(p->chan_pvt, index); 00532 } 00533 return -1; 00534 }
char analog_defaultcic[64] = "" [static] |
char analog_defaultozz[64] = "" [static] |
int analog_firstdigittimeout = 16000 [static] |
int analog_gendigittimeout = 8000 [static] |
int analog_matchdigittimeout = 3000 [static] |
| unsigned int cid_type |
Definition at line 82 of file sig_analog.c.
struct { ... } cidtypes[] [static] |
Referenced by analog_cidtype_to_str(), and analog_str_to_cidtype().
| const char const* name |
Definition at line 56 of file sig_analog.c.
| enum analog_sigtype sigtype |
Definition at line 55 of file sig_analog.c.
struct { ... } sigtypes[] [static] |
Referenced by analog_sigtype_to_str(), and analog_str_to_sigtype().
1.5.6