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