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