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