Analog signaling module. More...
#include "asterisk.h"
#include <errno.h>
#include <ctype.h>
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/say.h"
#include "asterisk/manager.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/cel.h"
#include "asterisk/causes.h"
#include "sig_analog.h"
Go to the source code of this file.
Defines | |
#define | analog_get_index(ast, p, nullok) _analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) |
#define | ANALOG_NEED_MFDETECT(p) (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB)) |
#define | ISTRUNK(p) |
#define | MIN_MS_SINCE_FLASH ( (2000) ) |
#define | POLARITY_IDLE 0 |
#define | POLARITY_REV 1 |
Functions | |
static struct ast_frame * | __analog_handle_event (struct analog_pvt *p, struct ast_channel *ast) |
static void * | __analog_ss_thread (void *data) |
static int | _analog_get_index (struct ast_channel *ast, struct analog_pvt *p, int nullok, const char *fname, unsigned long line) |
static void | analog_all_subchannels_hungup (struct analog_pvt *p) |
static int | analog_alloc_sub (struct analog_pvt *p, enum analog_sub x) |
int | analog_answer (struct analog_pvt *p, struct ast_channel *ast) |
static void | analog_answer_polarityswitch (struct analog_pvt *p) |
static int | analog_attempt_transfer (struct analog_pvt *p, int inthreeway) |
int | analog_available (struct analog_pvt *p) |
int | analog_call (struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout) |
static int | analog_callwait (struct analog_pvt *p) |
static void | analog_cancel_cidspill (struct analog_pvt *p) |
static int | analog_canmatch_featurecode (const char *exten) |
static void | analog_cb_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest) |
static int | analog_check_confirmanswer (struct analog_pvt *p) |
static int | analog_check_for_conference (struct analog_pvt *p) |
static int | analog_check_waitingfordt (struct analog_pvt *p) |
const char * | analog_cidstart_to_str (enum analog_cid_start cid_start) |
const char * | analog_cidtype_to_str (unsigned int cid_type) |
int | analog_config_complete (struct analog_pvt *p) |
static int | analog_confmute (struct analog_pvt *p, int mute) |
static int | analog_decrease_ss_count (struct analog_pvt *p) |
void | analog_delete (struct analog_pvt *doomed) |
Delete the analog private structure. | |
static int | analog_dial_digits (struct analog_pvt *p, enum analog_sub sub, struct analog_dialoperation *dop) |
static int | analog_distinctive_ring (struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata) |
int | analog_dnd (struct analog_pvt *p, int flag) |
static int | analog_dsp_reset_and_flush_digits (struct analog_pvt *p) |
static int | analog_dsp_set_digitmode (struct analog_pvt *p, enum analog_dsp_digitmode mode) |
static char * | analog_event2str (enum analog_event event) |
struct ast_frame * | analog_exception (struct analog_pvt *p, struct ast_channel *ast) |
int | analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp) |
static int | analog_flash (struct analog_pvt *p) |
void | analog_free (struct analog_pvt *p) |
static void | analog_get_and_handle_alarms (struct analog_pvt *p) |
static void * | analog_get_bridged_channel (struct analog_pvt *p, struct ast_channel *chan) |
static int | analog_get_callerid (struct analog_pvt *p, char *name, char *number, enum analog_event *ev, size_t timeout) |
static int | analog_get_event (struct analog_pvt *p) |
static const char * | analog_get_orig_dialstring (struct analog_pvt *p) |
static int | analog_get_sub_fd (struct analog_pvt *p, enum analog_sub sub) |
void | analog_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub idx, struct ast_frame **dest) |
void * | analog_handle_init_event (struct analog_pvt *i, int event) |
static int | analog_handle_notify_message (struct ast_channel *chan, struct analog_pvt *p, int cid_flags, int neon_mwievent) |
static int | analog_handles_digit (struct ast_frame *f) |
int | analog_hangup (struct analog_pvt *p, struct ast_channel *ast) |
static void | analog_hangup_polarityswitch (struct analog_pvt *p) |
static int | analog_has_voicemail (struct analog_pvt *p) |
static int | analog_have_progressdetect (struct analog_pvt *p) |
static int | analog_increase_ss_count (struct analog_pvt *p) |
static int | analog_is_dialing (struct analog_pvt *p, enum analog_sub index) |
static int | analog_is_off_hook (struct analog_pvt *p) |
static void | analog_lock_private (struct analog_pvt *p) |
static void | analog_lock_sub_owner (struct analog_pvt *pvt, enum analog_sub sub_idx) |
static int | analog_my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
struct analog_pvt * | analog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data) |
static struct ast_channel * | analog_new_ast_channel (struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor) |
static int | analog_off_hook (struct analog_pvt *p) |
static int | analog_on_hook (struct analog_pvt *p) |
static int | analog_play_tone (struct analog_pvt *p, enum analog_sub sub, enum analog_tone tone) |
struct ast_channel * | analog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor) |
static int | analog_ring (struct analog_pvt *p) |
static int | analog_send_callerid (struct analog_pvt *p, int cwcid, struct ast_party_caller *caller) |
static void | analog_set_alarm (struct analog_pvt *p, int in_alarm) |
static void | analog_set_cadence (struct analog_pvt *p, struct ast_channel *chan) |
static void | analog_set_callwaiting (struct analog_pvt *p, int callwaiting_enable) |
static void | analog_set_confirmanswer (struct analog_pvt *p, int flag) |
static void | analog_set_dialing (struct analog_pvt *p, int is_dialing) |
static int | analog_set_echocanceller (struct analog_pvt *p, int enable) |
static void | analog_set_inthreeway (struct analog_pvt *p, enum analog_sub sub, int inthreeway) |
static int | analog_set_linear_mode (struct analog_pvt *p, enum analog_sub sub, int linear_mode) |
static void | analog_set_needringing (struct analog_pvt *p, int value) |
static void | analog_set_new_owner (struct analog_pvt *p, struct ast_channel *new_owner) |
static void | analog_set_outgoing (struct analog_pvt *p, int is_outgoing) |
static void | analog_set_pulsedial (struct analog_pvt *p, int flag) |
static void | analog_set_ringtimeout (struct analog_pvt *p, int ringt) |
static void | analog_set_waitingfordt (struct analog_pvt *p, struct ast_channel *ast) |
const char * | analog_sigtype_to_str (enum analog_sigtype sigtype) |
int | analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *chan) |
static int | analog_start (struct analog_pvt *p) |
static int | analog_start_cid_detect (struct analog_pvt *p, int cid_signalling) |
static void | analog_start_polarityswitch (struct analog_pvt *p) |
static int | analog_stop_callwait (struct analog_pvt *p) |
static int | analog_stop_cid_detect (struct analog_pvt *p) |
enum analog_cid_start | analog_str_to_cidstart (const char *value) |
unsigned int | analog_str_to_cidtype (const char *name) |
enum analog_sigtype | analog_str_to_sigtype (const char *name) |
static void | analog_swap_subs (struct analog_pvt *p, enum analog_sub a, enum analog_sub b) |
static int | analog_train_echocanceller (struct analog_pvt *p) |
static int | analog_unalloc_sub (struct analog_pvt *p, enum analog_sub x) |
static void | analog_unlock_private (struct analog_pvt *p) |
static int | analog_update_conf (struct analog_pvt *p) |
static int | analog_wait_event (struct analog_pvt *p) |
static int | analog_wink (struct analog_pvt *p, enum analog_sub index) |
Variables | |
static char | analog_defaultcic [64] = "" |
static char | analog_defaultozz [64] = "" |
static int | analog_firstdigittimeout = 16000 |
static int | analog_gendigittimeout = 8000 |
static int | analog_matchdigittimeout = 3000 |
struct { | |
unsigned int cid_type | |
const char const * name | |
} | cidtypes [] |
struct { | |
const char const * name | |
enum analog_sigtype sigtype | |
} | sigtypes [] |
Analog signaling module.
Definition in file sig_analog.c.
#define analog_get_index | ( | ast, | |||
p, | |||||
nullok | ) | _analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) |
Definition at line 389 of file sig_analog.c.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_call(), analog_exception(), and analog_hangup().
#define ANALOG_NEED_MFDETECT | ( | p | ) | (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB)) |
Definition at line 1717 of file sig_analog.c.
Referenced by __analog_ss_thread().
#define ISTRUNK | ( | p | ) |
((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \ (p->sig == ANALOG_SIG_FXSGS))
Definition at line 104 of file sig_analog.c.
#define MIN_MS_SINCE_FLASH ( (2000) ) |
2000 ms
Definition at line 58 of file sig_analog.c.
#define POLARITY_IDLE 0 |
Definition at line 56 of file sig_analog.c.
#define POLARITY_REV 1 |
Definition at line 57 of file sig_analog.c.
static struct ast_frame* __analog_handle_event | ( | struct analog_pvt * | p, | |
struct ast_channel * | ast | |||
) | [static, read] |
< Digits (or equivalent) have been dialed
< Remote end is ringing
< Line is up
< Line is ringing
< Channel is down and available
< Channel is down, but reserved
< Channel is off hook
< Line is busy
< Digits (or equivalent) have been dialed while offhook
< Channel has detected an incoming call and is waiting for ring
< Digits (or equivalent) have been dialed
< Remote end is ringing
< Line is up
< Line is ringing
Definition at line 2658 of file sig_analog.c.
References __analog_ss_thread(), ast_channel::_state, analog_alloc_sub(), analog_answer_polarityswitch(), analog_attempt_transfer(), analog_cancel_cidspill(), analog_check_confirmanswer(), analog_check_for_conference(), analog_check_waitingfordt(), analog_confmute(), analog_dial_digits(), ANALOG_DIAL_OP_REPLACE, analog_event2str(), ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, ANALOG_EVENT_WINKFLASH, analog_get_and_handle_alarms(), analog_get_event(), analog_get_index, analog_get_sub_fd(), analog_handle_dtmf(), analog_has_voicemail(), analog_have_progressdetect(), analog_is_dialing(), analog_lock_private(), analog_lock_sub_owner(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_alarm(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_needringing(), analog_set_new_owner(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_start_polarityswitch(), analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_STUTTER, analog_train_echocanceller(), analog_unalloc_sub(), analog_unlock_private(), analog_update_conf(), ast_party_caller::ani, ast_party_caller::ani2, analog_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CAUSE_NO_ANSWER, ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_null_frame, ast_pthread_create_detached, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup_with_cause(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_channel::caller, analog_pvt::caller, analog_pvt::callwaitcas, analog_pvt::channel, analog_pvt::cid_name, cid_name, analog_pvt::cid_num, cid_num, analog_pvt::cidrings, analog_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, analog_pvt::dialdest, analog_pvt::dialednone, analog_pvt::dialing, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, EVENT_FLAG_SYSTEM, analog_subchannel::f, f, analog_pvt::finaldial, analog_pvt::flashtime, ast_frame::frametype, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, ast_party_caller::id, analog_pvt::inalarm, ast_frame_subclass::integer, analog_subchannel::inthreeway, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event, MIN_MS_SINCE_FLASH, analog_pvt::mohsuggest, analog_pvt::msgstate, ast_party_id::name, ast_party_id::number, ast_frame::offset, analog_pvt::onhooktime, analog_dialoperation::op, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::outgoing, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, ast_channel::pbx, analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, analog_pvt::polaritydelaytv, analog_pvt::polarityonanswerdelay, ast_frame::ptr, ast_channel::rings, analog_pvt::ringt_base, S_COR, S_OR, ast_frame::samples, analog_pvt::sig, ast_frame::src, analog_pvt::ss_astchan, ast_party_name::str, ast_party_number::str, ast_frame::subclass, analog_pvt::subs, analog_pvt::threewaycalling, analog_pvt::transfer, analog_pvt::transfertobusy, ast_party_name::valid, ast_party_number::valid, and analog_pvt::whichwink.
Referenced by analog_exception().
02659 { 02660 int res, x; 02661 int mysig; 02662 enum analog_sub idx; 02663 char *c; 02664 pthread_t threadid; 02665 struct ast_channel *chan; 02666 struct ast_frame *f; 02667 02668 ast_debug(1, "%s %d\n", __FUNCTION__, p->channel); 02669 02670 idx = analog_get_index(ast, p, 0); 02671 if (idx < 0) { 02672 return &ast_null_frame; 02673 } 02674 if (idx != ANALOG_SUB_REAL) { 02675 ast_log(LOG_ERROR, "We got an event on a non real sub. Fix it!\n"); 02676 } 02677 02678 mysig = p->sig; 02679 if (p->outsigmod > -1) { 02680 mysig = p->outsigmod; 02681 } 02682 02683 p->subs[idx].f.frametype = AST_FRAME_NULL; 02684 p->subs[idx].f.subclass.integer = 0; 02685 p->subs[idx].f.datalen = 0; 02686 p->subs[idx].f.samples = 0; 02687 p->subs[idx].f.mallocd = 0; 02688 p->subs[idx].f.offset = 0; 02689 p->subs[idx].f.src = "dahdi_handle_event"; 02690 p->subs[idx].f.data.ptr = NULL; 02691 f = &p->subs[idx].f; 02692 02693 res = analog_get_event(p); 02694 02695 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, idx); 02696 02697 if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) { 02698 analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0); 02699 ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff); 02700 analog_confmute(p, 0); 02701 p->subs[idx].f.frametype = AST_FRAME_DTMF_END; 02702 p->subs[idx].f.subclass.integer = res & 0xff; 02703 analog_handle_dtmf(p, ast, idx, &f); 02704 return f; 02705 } 02706 02707 if (res & ANALOG_EVENT_DTMFDOWN) { 02708 ast_debug(1, "DTMF Down '%c'\n", res & 0xff); 02709 /* Mute conference */ 02710 analog_confmute(p, 1); 02711 p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN; 02712 p->subs[idx].f.subclass.integer = res & 0xff; 02713 analog_handle_dtmf(p, ast, idx, &f); 02714 return f; 02715 } 02716 02717 switch (res) { 02718 case ANALOG_EVENT_EC_DISABLED: 02719 ast_verb(3, "Channel %d echo canceler disabled due to CED detection\n", p->channel); 02720 analog_set_echocanceller(p, 0); 02721 break; 02722 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 02723 case ANALOG_EVENT_TX_CED_DETECTED: 02724 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel); 02725 break; 02726 case ANALOG_EVENT_RX_CED_DETECTED: 02727 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel); 02728 break; 02729 case ANALOG_EVENT_EC_NLP_DISABLED: 02730 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel); 02731 break; 02732 case ANALOG_EVENT_EC_NLP_ENABLED: 02733 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel); 02734 break; 02735 #endif 02736 case ANALOG_EVENT_PULSE_START: 02737 /* Stop tone if there's a pulse start and the PBX isn't started */ 02738 if (!ast->pbx) 02739 analog_play_tone(p, ANALOG_SUB_REAL, -1); 02740 break; 02741 case ANALOG_EVENT_DIALCOMPLETE: 02742 if (p->inalarm) { 02743 break; 02744 } 02745 x = analog_is_dialing(p, idx); 02746 if (!x) { /* if not still dialing in driver */ 02747 analog_set_echocanceller(p, 1); 02748 if (p->echobreak) { 02749 analog_train_echocanceller(p); 02750 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 02751 p->dop.op = ANALOG_DIAL_OP_REPLACE; 02752 if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { 02753 int dial_err = errno; 02754 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(dial_err)); 02755 } 02756 p->echobreak = 0; 02757 } else { 02758 analog_set_dialing(p, 0); 02759 if ((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) { 02760 /* if thru with dialing after offhook */ 02761 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 02762 ast_setstate(ast, AST_STATE_UP); 02763 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 02764 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 02765 break; 02766 } else { /* if to state wait for offhook to dial rest */ 02767 /* we now wait for off hook */ 02768 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 02769 } 02770 } 02771 if (ast->_state == AST_STATE_DIALING) { 02772 if (analog_have_progressdetect(p)) { 02773 ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n"); 02774 } else if (analog_check_confirmanswer(p) || (!p->dialednone 02775 && ((mysig == ANALOG_SIG_EM) || (mysig == ANALOG_SIG_EM_E1) 02776 || (mysig == ANALOG_SIG_EMWINK) || (mysig == ANALOG_SIG_FEATD) 02777 || (mysig == ANALOG_SIG_FEATDMF_TA) || (mysig == ANALOG_SIG_FEATDMF) 02778 || (mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) 02779 || (mysig == ANALOG_SIG_FGC_CAMAMF) || (mysig == ANALOG_SIG_FEATB) 02780 || (mysig == ANALOG_SIG_SF) || (mysig == ANALOG_SIG_SFWINK) 02781 || (mysig == ANALOG_SIG_SF_FEATD) || (mysig == ANALOG_SIG_SF_FEATDMF) 02782 || (mysig == ANALOG_SIG_SF_FEATB)))) { 02783 ast_setstate(ast, AST_STATE_RINGING); 02784 } else if (!p->answeronpolarityswitch) { 02785 ast_setstate(ast, AST_STATE_UP); 02786 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 02787 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 02788 /* If aops=0 and hops=1, this is necessary */ 02789 p->polarity = POLARITY_REV; 02790 } else { 02791 /* Start clean, so we can catch the change to REV polarity when party answers */ 02792 p->polarity = POLARITY_IDLE; 02793 } 02794 } 02795 } 02796 } 02797 break; 02798 case ANALOG_EVENT_ALARM: 02799 analog_set_alarm(p, 1); 02800 analog_get_and_handle_alarms(p); 02801 /* Intentionally fall through to analog_set_echocanceller() call */ 02802 case ANALOG_EVENT_ONHOOK: 02803 switch (p->sig) { 02804 case ANALOG_SIG_FXOLS: 02805 case ANALOG_SIG_FXOGS: 02806 case ANALOG_SIG_FXOKS: 02807 analog_start_polarityswitch(p); 02808 p->fxsoffhookstate = 0; 02809 p->onhooktime = time(NULL); 02810 p->msgstate = -1; 02811 /* Check for some special conditions regarding call waiting */ 02812 if (idx == ANALOG_SUB_REAL) { 02813 /* The normal line was hung up */ 02814 if (p->subs[ANALOG_SUB_CALLWAIT].owner) { 02815 /* Need to hold the lock for real-call, private, and call-waiting call */ 02816 analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT); 02817 if (!p->subs[ANALOG_SUB_CALLWAIT].owner) { 02818 /* 02819 * The call waiting call dissappeared. 02820 * This is now a normal hangup. 02821 */ 02822 analog_set_echocanceller(p, 0); 02823 return NULL; 02824 } 02825 02826 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 02827 analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL); 02828 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel); 02829 analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT); 02830 analog_stop_callwait(p); 02831 analog_set_new_owner(p, NULL); 02832 /* Don't start streaming audio yet if the incoming call isn't up yet */ 02833 if (p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) { 02834 analog_set_dialing(p, 1); 02835 } 02836 /* Unlock the call-waiting call that we swapped to real-call. */ 02837 ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner); 02838 analog_ring(p); 02839 } else if (p->subs[ANALOG_SUB_THREEWAY].owner) { 02840 unsigned int mssinceflash; 02841 02842 /* Need to hold the lock for real-call, private, and 3-way call */ 02843 analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY); 02844 if (!p->subs[ANALOG_SUB_THREEWAY].owner) { 02845 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 02846 /* Just hangup */ 02847 return NULL; 02848 } 02849 if (p->owner != ast) { 02850 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02851 ast_log(LOG_WARNING, "This isn't good...\n"); 02852 /* Just hangup */ 02853 return NULL; 02854 } 02855 02856 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 02857 ast_debug(1, "Last flash was %d ms ago\n", mssinceflash); 02858 if (mssinceflash < MIN_MS_SINCE_FLASH) { 02859 /* It hasn't been long enough since the last flashook. This is probably a bounce on 02860 hanging up. Hangup both channels now */ 02861 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 02862 ast_queue_hangup_with_cause(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER); 02863 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02864 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02865 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 02866 if (p->transfer) { 02867 int inthreeway; 02868 02869 inthreeway = p->subs[ANALOG_SUB_THREEWAY].inthreeway; 02870 02871 /* In any case this isn't a threeway call anymore */ 02872 analog_set_inthreeway(p, ANALOG_SUB_REAL, 0); 02873 analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0); 02874 02875 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 02876 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 02877 /* Swap subs and dis-own channel */ 02878 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02879 /* Unlock the 3-way call that we swapped to real-call. */ 02880 ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner); 02881 analog_set_new_owner(p, NULL); 02882 /* Ring the phone */ 02883 analog_ring(p); 02884 } else { 02885 res = analog_attempt_transfer(p, inthreeway); 02886 if (res < 0) { 02887 /* Transfer attempt failed. */ 02888 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02889 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02890 } else if (res) { 02891 /* Don't actually hang up at this point */ 02892 break; 02893 } 02894 } 02895 } else { 02896 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 02897 ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); 02898 } 02899 } else { 02900 /* Swap subs and dis-own channel */ 02901 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 02902 /* Unlock the 3-way call that we swapped to real-call. */ 02903 ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner); 02904 analog_set_new_owner(p, NULL); 02905 /* Ring the phone */ 02906 analog_ring(p); 02907 } 02908 } 02909 } else { 02910 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx); 02911 } 02912 /* Fall through */ 02913 default: 02914 analog_set_echocanceller(p, 0); 02915 return NULL; 02916 } 02917 break; 02918 case ANALOG_EVENT_RINGOFFHOOK: 02919 if (p->inalarm) { 02920 break; 02921 } 02922 /* for E911, its supposed to wait for offhook then dial 02923 the second half of the dial string */ 02924 if (((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 02925 c = strchr(p->dialdest, '/'); 02926 if (c) { 02927 c++; 02928 } else { 02929 c = p->dialdest; 02930 } 02931 if (*c) { 02932 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 02933 } else { 02934 ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 02935 } 02936 if (strlen(p->dop.dialstr) > 4) { 02937 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02938 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02939 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02940 p->echobreak = 1; 02941 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02942 } else { 02943 p->echobreak = 0; 02944 } 02945 if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) { 02946 int saveerr = errno; 02947 analog_on_hook(p); 02948 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 02949 return NULL; 02950 } 02951 analog_set_dialing(p, 1); 02952 return &p->subs[idx].f; 02953 } 02954 switch (p->sig) { 02955 case ANALOG_SIG_FXOLS: 02956 case ANALOG_SIG_FXOGS: 02957 case ANALOG_SIG_FXOKS: 02958 p->fxsoffhookstate = 1; 02959 switch (ast->_state) { 02960 case AST_STATE_RINGING: 02961 analog_set_echocanceller(p, 1); 02962 analog_train_echocanceller(p); 02963 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 02964 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 02965 /* Make sure it stops ringing */ 02966 analog_set_needringing(p, 0); 02967 analog_off_hook(p); 02968 ast_debug(1, "channel %d answered\n", p->channel); 02969 02970 /* Cancel any running CallerID spill */ 02971 analog_cancel_cidspill(p); 02972 02973 analog_set_dialing(p, 0); 02974 p->callwaitcas = 0; 02975 if (analog_check_confirmanswer(p)) { 02976 /* Ignore answer if "confirm answer" is enabled */ 02977 p->subs[idx].f.frametype = AST_FRAME_NULL; 02978 p->subs[idx].f.subclass.integer = 0; 02979 } else if (!ast_strlen_zero(p->dop.dialstr)) { 02980 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 02981 res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 02982 if (res < 0) { 02983 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 02984 p->dop.dialstr[0] = '\0'; 02985 return NULL; 02986 } else { 02987 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 02988 p->subs[idx].f.frametype = AST_FRAME_NULL; 02989 p->subs[idx].f.subclass.integer = 0; 02990 analog_set_dialing(p, 1); 02991 } 02992 p->dop.dialstr[0] = '\0'; 02993 ast_setstate(ast, AST_STATE_DIALING); 02994 } else { 02995 ast_setstate(ast, AST_STATE_UP); 02996 analog_answer_polarityswitch(p); 02997 } 02998 return &p->subs[idx].f; 02999 case AST_STATE_DOWN: 03000 ast_setstate(ast, AST_STATE_RING); 03001 ast->rings = 1; 03002 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 03003 p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK; 03004 ast_debug(1, "channel %d picked up\n", p->channel); 03005 return &p->subs[idx].f; 03006 case AST_STATE_UP: 03007 /* Make sure it stops ringing */ 03008 analog_off_hook(p); 03009 /* Okay -- probably call waiting*/ 03010 if (ast_bridged_channel(p->owner)) { 03011 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 03012 } 03013 break; 03014 case AST_STATE_RESERVED: 03015 /* Start up dialtone */ 03016 if (analog_has_voicemail(p)) { 03017 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER); 03018 } else { 03019 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE); 03020 } 03021 break; 03022 default: 03023 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 03024 } 03025 break; 03026 case ANALOG_SIG_FXSLS: 03027 case ANALOG_SIG_FXSGS: 03028 case ANALOG_SIG_FXSKS: 03029 if (ast->_state == AST_STATE_RING) { 03030 analog_set_ringtimeout(p, p->ringt_base); 03031 } 03032 03033 /* Fall through */ 03034 case ANALOG_SIG_EM: 03035 case ANALOG_SIG_EM_E1: 03036 case ANALOG_SIG_EMWINK: 03037 case ANALOG_SIG_FEATD: 03038 case ANALOG_SIG_FEATDMF: 03039 case ANALOG_SIG_FEATDMF_TA: 03040 case ANALOG_SIG_E911: 03041 case ANALOG_SIG_FGC_CAMA: 03042 case ANALOG_SIG_FGC_CAMAMF: 03043 case ANALOG_SIG_FEATB: 03044 case ANALOG_SIG_SF: 03045 case ANALOG_SIG_SFWINK: 03046 case ANALOG_SIG_SF_FEATD: 03047 case ANALOG_SIG_SF_FEATDMF: 03048 case ANALOG_SIG_SF_FEATB: 03049 switch (ast->_state) { 03050 case AST_STATE_PRERING: 03051 ast_setstate(ast, AST_STATE_RING); 03052 /* Fall through */ 03053 case AST_STATE_DOWN: 03054 case AST_STATE_RING: 03055 ast_debug(1, "Ring detected\n"); 03056 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 03057 p->subs[idx].f.subclass.integer = AST_CONTROL_RING; 03058 break; 03059 case AST_STATE_RINGING: 03060 case AST_STATE_DIALING: 03061 if (p->outgoing) { 03062 ast_debug(1, "Line answered\n"); 03063 if (analog_check_confirmanswer(p)) { 03064 p->subs[idx].f.frametype = AST_FRAME_NULL; 03065 p->subs[idx].f.subclass.integer = 0; 03066 } else { 03067 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 03068 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 03069 ast_setstate(ast, AST_STATE_UP); 03070 } 03071 break; 03072 } 03073 /* Fall through */ 03074 default: 03075 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 03076 break; 03077 } 03078 break; 03079 default: 03080 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 03081 break; 03082 } 03083 break; 03084 case ANALOG_EVENT_RINGBEGIN: 03085 switch (p->sig) { 03086 case ANALOG_SIG_FXSLS: 03087 case ANALOG_SIG_FXSGS: 03088 case ANALOG_SIG_FXSKS: 03089 if (ast->_state == AST_STATE_RING) { 03090 analog_set_ringtimeout(p, p->ringt_base); 03091 } 03092 break; 03093 default: 03094 break; 03095 } 03096 break; 03097 case ANALOG_EVENT_RINGEROFF: 03098 if (p->inalarm) break; 03099 ast->rings++; 03100 if (ast->rings == p->cidrings) { 03101 analog_send_callerid(p, 0, &p->caller); 03102 } 03103 03104 if (ast->rings > p->cidrings) { 03105 analog_cancel_cidspill(p); 03106 p->callwaitcas = 0; 03107 } 03108 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 03109 p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING; 03110 break; 03111 case ANALOG_EVENT_RINGERON: 03112 break; 03113 case ANALOG_EVENT_NOALARM: 03114 analog_set_alarm(p, 0); 03115 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 03116 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 03117 "Channel: %d\r\n", p->channel); 03118 break; 03119 case ANALOG_EVENT_WINKFLASH: 03120 if (p->inalarm) { 03121 break; 03122 } 03123 /* Remember last time we got a flash-hook */ 03124 gettimeofday(&p->flashtime, NULL); 03125 switch (mysig) { 03126 case ANALOG_SIG_FXOLS: 03127 case ANALOG_SIG_FXOGS: 03128 case ANALOG_SIG_FXOKS: 03129 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 03130 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)); 03131 03132 /* Cancel any running CallerID spill */ 03133 analog_cancel_cidspill(p); 03134 p->callwaitcas = 0; 03135 03136 if (idx != ANALOG_SUB_REAL) { 03137 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel); 03138 goto winkflashdone; 03139 } 03140 03141 if (p->subs[ANALOG_SUB_CALLWAIT].owner) { 03142 /* Need to hold the lock for real-call, private, and call-waiting call */ 03143 analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT); 03144 if (!p->subs[ANALOG_SUB_CALLWAIT].owner) { 03145 /* 03146 * The call waiting call dissappeared. 03147 * Let's just ignore this flash-hook. 03148 */ 03149 ast_log(LOG_NOTICE, "Whoa, the call-waiting call disappeared.\n"); 03150 goto winkflashdone; 03151 } 03152 03153 /* Swap to call-wait */ 03154 analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT); 03155 analog_play_tone(p, ANALOG_SUB_REAL, -1); 03156 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 03157 ast_debug(1, "Making %s the new owner\n", p->owner->name); 03158 if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RINGING) { 03159 ast_setstate(p->subs[ANALOG_SUB_REAL].owner, AST_STATE_UP); 03160 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER); 03161 } 03162 analog_stop_callwait(p); 03163 03164 /* Start music on hold if appropriate */ 03165 if (!p->subs[ANALOG_SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) { 03166 ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 03167 S_OR(p->mohsuggest, NULL), 03168 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 03169 } 03170 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 03171 ast_queue_control_data(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_HOLD, 03172 S_OR(p->mohsuggest, NULL), 03173 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 03174 } 03175 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 03176 03177 /* Unlock the call-waiting call that we swapped to real-call. */ 03178 ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner); 03179 } else if (!p->subs[ANALOG_SUB_THREEWAY].owner) { 03180 if (!p->threewaycalling) { 03181 /* Just send a flash if no 3-way calling */ 03182 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_FLASH); 03183 goto winkflashdone; 03184 } else if (!analog_check_for_conference(p)) { 03185 char cid_num[256]; 03186 char cid_name[256]; 03187 03188 cid_num[0] = '\0'; 03189 cid_name[0] = '\0'; 03190 if (p->dahditrcallerid && p->owner) { 03191 if (p->owner->caller.id.number.valid 03192 && p->owner->caller.id.number.str) { 03193 ast_copy_string(cid_num, p->owner->caller.id.number.str, 03194 sizeof(cid_num)); 03195 } 03196 if (p->owner->caller.id.name.valid 03197 && p->owner->caller.id.name.str) { 03198 ast_copy_string(cid_name, p->owner->caller.id.name.str, 03199 sizeof(cid_name)); 03200 } 03201 } 03202 /* XXX This section needs much more error checking!!! XXX */ 03203 /* Start a 3-way call if feasible */ 03204 if (!((ast->pbx) || 03205 (ast->_state == AST_STATE_UP) || 03206 (ast->_state == AST_STATE_RING))) { 03207 ast_debug(1, "Flash when call not up or ringing\n"); 03208 goto winkflashdone; 03209 } 03210 if (analog_alloc_sub(p, ANALOG_SUB_THREEWAY)) { 03211 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 03212 goto winkflashdone; 03213 } 03214 03215 /* 03216 * Make new channel 03217 * 03218 * We cannot hold the p or ast locks while creating a new 03219 * channel. 03220 */ 03221 analog_unlock_private(p); 03222 ast_channel_unlock(ast); 03223 chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY, NULL); 03224 ast_channel_lock(ast); 03225 analog_lock_private(p); 03226 if (!chan) { 03227 ast_log(LOG_WARNING, 03228 "Cannot allocate new call structure on channel %d\n", 03229 p->channel); 03230 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 03231 goto winkflashdone; 03232 } 03233 if (p->dahditrcallerid) { 03234 if (!p->origcid_num) { 03235 p->origcid_num = ast_strdup(p->cid_num); 03236 } 03237 if (!p->origcid_name) { 03238 p->origcid_name = ast_strdup(p->cid_name); 03239 } 03240 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 03241 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 03242 } 03243 /* Swap things around between the three-way and real call */ 03244 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 03245 /* Disable echo canceller for better dialing */ 03246 analog_set_echocanceller(p, 0); 03247 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALRECALL); 03248 if (res) { 03249 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 03250 } 03251 analog_set_new_owner(p, chan); 03252 p->ss_astchan = chan; 03253 if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p)) { 03254 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 03255 res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03256 analog_set_echocanceller(p, 1); 03257 ast_hangup(chan); 03258 } else { 03259 ast_verb(3, "Started three way call on channel %d\n", p->channel); 03260 03261 /* Start music on hold if appropriate */ 03262 if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) { 03263 ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD, 03264 S_OR(p->mohsuggest, NULL), 03265 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 03266 } 03267 } 03268 } 03269 } else { 03270 /* Already have a 3 way call */ 03271 enum analog_sub orig_3way_sub; 03272 03273 /* Need to hold the lock for real-call, private, and 3-way call */ 03274 analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY); 03275 if (!p->subs[ANALOG_SUB_THREEWAY].owner) { 03276 /* 03277 * The 3-way call dissappeared. 03278 * Let's just ignore this flash-hook. 03279 */ 03280 ast_log(LOG_NOTICE, "Whoa, the 3-way call disappeared.\n"); 03281 goto winkflashdone; 03282 } 03283 orig_3way_sub = ANALOG_SUB_THREEWAY; 03284 03285 if (p->subs[ANALOG_SUB_THREEWAY].inthreeway) { 03286 /* Call is already up, drop the last person */ 03287 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel); 03288 /* If the primary call isn't answered yet, use it */ 03289 if ((p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) && 03290 (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 03291 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 03292 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 03293 orig_3way_sub = ANALOG_SUB_REAL; 03294 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 03295 } 03296 /* Drop the last call and stop the conference */ 03297 ast_verb(3, "Dropping three-way call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name); 03298 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 03299 analog_set_inthreeway(p, ANALOG_SUB_REAL, 0); 03300 analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0); 03301 } else { 03302 /* Lets see what we're up to */ 03303 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 03304 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 03305 ast_verb(3, "Building conference call with %s and %s\n", 03306 p->subs[ANALOG_SUB_THREEWAY].owner->name, 03307 p->subs[ANALOG_SUB_REAL].owner->name); 03308 /* Put them in the threeway, and flip */ 03309 analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 1); 03310 analog_set_inthreeway(p, ANALOG_SUB_REAL, 1); 03311 if (ast->_state == AST_STATE_UP) { 03312 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 03313 orig_3way_sub = ANALOG_SUB_REAL; 03314 } 03315 if (ast_bridged_channel(p->subs[orig_3way_sub].owner)) { 03316 ast_queue_control(p->subs[orig_3way_sub].owner, AST_CONTROL_UNHOLD); 03317 } 03318 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 03319 } else { 03320 ast_verb(3, "Dumping incomplete call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name); 03321 analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); 03322 orig_3way_sub = ANALOG_SUB_REAL; 03323 ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); 03324 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 03325 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 03326 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 03327 } 03328 analog_set_echocanceller(p, 1); 03329 } 03330 } 03331 ast_channel_unlock(p->subs[orig_3way_sub].owner); 03332 } 03333 winkflashdone: 03334 analog_update_conf(p); 03335 break; 03336 case ANALOG_SIG_EM: 03337 case ANALOG_SIG_EM_E1: 03338 case ANALOG_SIG_FEATD: 03339 case ANALOG_SIG_SF: 03340 case ANALOG_SIG_SFWINK: 03341 case ANALOG_SIG_SF_FEATD: 03342 case ANALOG_SIG_FXSLS: 03343 case ANALOG_SIG_FXSGS: 03344 if (p->dialing) { 03345 ast_debug(1, "Ignoring wink on channel %d\n", p->channel); 03346 } else { 03347 ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 03348 } 03349 break; 03350 case ANALOG_SIG_FEATDMF_TA: 03351 switch (p->whichwink) { 03352 case 0: 03353 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2, 03354 S_COR(p->owner->caller.ani.number.valid, 03355 p->owner->caller.ani.number.str, "")); 03356 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", 03357 p->owner->caller.ani2, 03358 S_COR(p->owner->caller.ani.number.valid, 03359 p->owner->caller.ani.number.str, "")); 03360 break; 03361 case 1: 03362 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 03363 break; 03364 case 2: 03365 ast_log(LOG_WARNING, "Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA\n"); 03366 return NULL; 03367 } 03368 p->whichwink++; 03369 /* Fall through */ 03370 case ANALOG_SIG_FEATDMF: 03371 case ANALOG_SIG_E911: 03372 case ANALOG_SIG_FGC_CAMAMF: 03373 case ANALOG_SIG_FGC_CAMA: 03374 case ANALOG_SIG_FEATB: 03375 case ANALOG_SIG_SF_FEATDMF: 03376 case ANALOG_SIG_SF_FEATB: 03377 case ANALOG_SIG_EMWINK: 03378 /* FGD MF and EMWINK *Must* wait for wink */ 03379 if (!ast_strlen_zero(p->dop.dialstr)) { 03380 res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 03381 if (res < 0) { 03382 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 03383 p->dop.dialstr[0] = '\0'; 03384 return NULL; 03385 } else { 03386 ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr); 03387 } 03388 } 03389 p->dop.dialstr[0] = '\0'; 03390 break; 03391 default: 03392 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 03393 } 03394 break; 03395 case ANALOG_EVENT_HOOKCOMPLETE: 03396 if (p->inalarm) break; 03397 if (analog_check_waitingfordt(p)) { 03398 break; 03399 } 03400 switch (mysig) { 03401 case ANALOG_SIG_FXSLS: /* only interesting for FXS */ 03402 case ANALOG_SIG_FXSGS: 03403 case ANALOG_SIG_FXSKS: 03404 case ANALOG_SIG_EM: 03405 case ANALOG_SIG_EM_E1: 03406 case ANALOG_SIG_EMWINK: 03407 case ANALOG_SIG_FEATD: 03408 case ANALOG_SIG_SF: 03409 case ANALOG_SIG_SFWINK: 03410 case ANALOG_SIG_SF_FEATD: 03411 if (!ast_strlen_zero(p->dop.dialstr)) { 03412 res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop); 03413 if (res < 0) { 03414 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 03415 p->dop.dialstr[0] = '\0'; 03416 return NULL; 03417 } else { 03418 ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr); 03419 } 03420 } 03421 p->dop.dialstr[0] = '\0'; 03422 p->dop.op = ANALOG_DIAL_OP_REPLACE; 03423 break; 03424 case ANALOG_SIG_FEATDMF: 03425 case ANALOG_SIG_FEATDMF_TA: 03426 case ANALOG_SIG_E911: 03427 case ANALOG_SIG_FGC_CAMA: 03428 case ANALOG_SIG_FGC_CAMAMF: 03429 case ANALOG_SIG_FEATB: 03430 case ANALOG_SIG_SF_FEATDMF: 03431 case ANALOG_SIG_SF_FEATB: 03432 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 03433 break; 03434 default: 03435 break; 03436 } 03437 break; 03438 case ANALOG_EVENT_POLARITY: 03439 /* 03440 * If we get a Polarity Switch event, this could be 03441 * due to line seizure, remote end connect or remote end disconnect. 03442 * 03443 * Check to see if we should change the polarity state and 03444 * mark the channel as UP or if this is an indication 03445 * of remote end disconnect. 03446 */ 03447 03448 if (p->polarityonanswerdelay > 0) { 03449 /* check if event is not too soon after OffHook or Answer */ 03450 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 03451 switch (ast->_state) { 03452 case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */ 03453 case AST_STATE_RINGING: /*!< Remote end is ringing */ 03454 if (p->answeronpolarityswitch) { 03455 ast_debug(1, "Answering on polarity switch! channel %d\n", p->channel); 03456 ast_setstate(p->owner, AST_STATE_UP); 03457 p->polarity = POLARITY_REV; 03458 if (p->hanguponpolarityswitch) { 03459 p->polaritydelaytv = ast_tvnow(); 03460 } 03461 } else { 03462 ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel); 03463 } 03464 break; 03465 03466 case AST_STATE_UP: /*!< Line is up */ 03467 case AST_STATE_RING: /*!< Line is ringing */ 03468 if (p->hanguponpolarityswitch) { 03469 ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel); 03470 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 03471 p->polarity = POLARITY_IDLE; 03472 } else { 03473 ast_debug(1, "Ignore Hangup on polarity switch, channel %d\n", p->channel); 03474 } 03475 break; 03476 03477 case AST_STATE_DOWN: /*!< Channel is down and available */ 03478 case AST_STATE_RESERVED: /*!< Channel is down, but reserved */ 03479 case AST_STATE_OFFHOOK: /*!< Channel is off hook */ 03480 case AST_STATE_BUSY: /*!< Line is busy */ 03481 case AST_STATE_DIALING_OFFHOOK: /*!< Digits (or equivalent) have been dialed while offhook */ 03482 case AST_STATE_PRERING: /*!< Channel has detected an incoming call and is waiting for ring */ 03483 default: 03484 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 03485 ast_debug(1, "Ignoring Polarity switch on channel %d, state %d\n", p->channel, ast->_state); 03486 } 03487 break; 03488 } 03489 03490 } else { 03491 /* event is too soon after OffHook or Answer */ 03492 switch (ast->_state) { 03493 case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */ 03494 case AST_STATE_RINGING: /*!< Remote end is ringing */ 03495 if (p->answeronpolarityswitch) { 03496 ast_debug(1, "Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %d\n", p->channel, ast->_state); 03497 } 03498 break; 03499 03500 case AST_STATE_UP: /*!< Line is up */ 03501 case AST_STATE_RING: /*!< Line is ringing */ 03502 if (p->hanguponpolarityswitch) { 03503 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); 03504 } 03505 break; 03506 03507 default: 03508 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 03509 ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %d\n", p->channel, ast->_state); 03510 } 03511 break; 03512 } 03513 } 03514 } 03515 03516 /* Added more log_debug information below to provide a better indication of what is going on */ 03517 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) ); 03518 break; 03519 default: 03520 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel); 03521 } 03522 return &p->subs[idx].f; 03523 }
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_remaining_ms(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_destroy(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), ASTOBJ_UNREF, analog_pvt::call_forward, ast_channel::caller, callerid_free(), callerid_get_dtmf(), ast_smdi_md_message::calling_st, analog_pvt::callreturn, analog_pvt::callwaiting, analog_pvt::cancallforward, analog_pvt::canpark, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, analog_pvt::cid_signalling, analog_pvt::cid_start, ast_channel::context, analog_dialoperation::dialstr, analog_pvt::dop, errno, ast_channel::exten, exten, f, callerid_state::flags, ast_frame::frametype, ast_smdi_md_message::fwd_st, analog_pvt::hanguponpolarityswitch, analog_pvt::hidecallerid, ast_party_caller::id, analog_pvt::immediate, ast_frame_subclass::integer, ISTRUNK, analog_pvt::lastcid_num, len(), LOG_WARNING, ast_party_id::name, name, ast_party_id::number, analog_subchannel::owner, pbx_builtin_setvar_helper(), analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, RING_PATTERNS, ast_channel::rings, analog_pvt::ringt, analog_pvt::ringt_base, analog_pvt::sig, analog_pvt::smdi_iface, analog_pvt::ss_astchan, ast_party_number::str, ast_frame::subclass, analog_pvt::subs, ast_channel::tech_pvt, analog_pvt::transfer, ast_smdi_md_message::type, analog_pvt::use_callerid, analog_pvt::use_smdi, and ast_party_number::valid.
Referenced by __analog_handle_event(), analog_handle_init_event(), and analog_ss_thread_start().
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) { 02309 pbridge = analog_get_bridged_channel(p, nbridge); 02310 } 02311 if (pbridge && ISTRUNK(pbridge)) { 02312 /* Clear out the dial buffer */ 02313 p->dop.dialstr[0] = '\0'; 02314 /* flash hookswitch */ 02315 if ((analog_flash(pbridge) == -1) && (errno != EINPROGRESS)) { 02316 ast_log(LOG_WARNING, 02317 "Unable to flash-hook bridged trunk from channel %s: %s\n", 02318 nbridge->name, strerror(errno)); 02319 } 02320 analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY); 02321 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 02322 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 02323 if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) { 02324 ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD); 02325 } 02326 ast_hangup(chan); 02327 goto quit; 02328 } else { 02329 analog_play_tone(p, idx, ANALOG_TONE_CONGESTION); 02330 analog_wait_event(p); 02331 analog_play_tone(p, idx, -1); 02332 analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY); 02333 analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); 02334 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 02335 ast_hangup(chan); 02336 goto quit; 02337 } 02338 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, 02339 chan->caller.id.number.valid ? chan->caller.id.number.str : NULL) 02340 && !analog_canmatch_featurecode(exten)) { 02341 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, 02342 chan->caller.id.number.valid && chan->caller.id.number.str 02343 ? chan->caller.id.number.str : "<Unknown Caller>", 02344 chan->context); 02345 break; 02346 } 02347 if (!timeout) { 02348 timeout = analog_gendigittimeout; 02349 } 02350 if (len && !ast_ignore_pattern(chan->context, exten)) { 02351 analog_play_tone(p, idx, -1); 02352 } 02353 } 02354 break; 02355 case ANALOG_SIG_FXSLS: 02356 case ANALOG_SIG_FXSGS: 02357 case ANALOG_SIG_FXSKS: 02358 /* check for SMDI messages */ 02359 if (p->use_smdi && p->smdi_iface) { 02360 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, ANALOG_SMDI_MD_WAIT_TIMEOUT); 02361 if (smdi_msg != NULL) { 02362 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 02363 02364 if (smdi_msg->type == 'B') 02365 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 02366 else if (smdi_msg->type == 'N') 02367 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 02368 02369 ast_debug(1, "Received SMDI message on %s\n", chan->name); 02370 } else { 02371 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 02372 } 02373 } 02374 02375 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 02376 number = smdi_msg->calling_st; 02377 02378 /* If we want caller id, we're in a prering state due to a polarity reversal 02379 * and we're set to use a polarity reversal to trigger the start of caller id, 02380 * grab the caller id and wait for ringing to start... */ 02381 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING 02382 && (p->cid_start == ANALOG_CID_START_POLARITY 02383 || p->cid_start == ANALOG_CID_START_POLARITY_IN 02384 || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) { 02385 /* If set to use DTMF CID signalling, listen for DTMF */ 02386 if (p->cid_signalling == CID_SIG_DTMF) { 02387 int k = 0; 02388 int oldlinearity; 02389 int timeout_ms; 02390 int ms; 02391 struct timeval start = ast_tvnow(); 02392 cs = NULL; 02393 ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name); 02394 02395 oldlinearity = analog_set_linear_mode(p, idx, 0); 02396 02397 /* 02398 * We are the only party interested in the Rx stream since 02399 * we have not answered yet. We don't need or even want DTMF 02400 * emulation. The DTMF digits can come so fast that emulation 02401 * can drop some of them. 02402 */ 02403 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 02404 timeout_ms = 4000;/* This is a typical OFF time between rings. */ 02405 for (;;) { 02406 struct ast_frame *f; 02407 02408 ms = ast_remaining_ms(start, timeout_ms); 02409 res = ast_waitfor(chan, ms); 02410 if (res <= 0) { 02411 /* 02412 * We do not need to restore the analog_set_linear_mode() 02413 * or AST_FLAG_END_DTMF_ONLY flag settings since we 02414 * are hanging up the channel. 02415 */ 02416 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 02417 "Exiting simple switch\n"); 02418 ast_hangup(chan); 02419 goto quit; 02420 } 02421 f = ast_read(chan); 02422 if (!f) { 02423 break; 02424 } 02425 if (f->frametype == AST_FRAME_DTMF) { 02426 if (k < ARRAY_LEN(dtmfbuf) - 1) { 02427 dtmfbuf[k++] = f->subclass.integer; 02428 } 02429 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer); 02430 start = ast_tvnow(); 02431 } 02432 ast_frfree(f); 02433 if (chan->_state == AST_STATE_RING || 02434 chan->_state == AST_STATE_RINGING) { 02435 break; /* Got ring */ 02436 } 02437 } 02438 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 02439 dtmfbuf[k] = '\0'; 02440 02441 analog_set_linear_mode(p, idx, oldlinearity); 02442 02443 /* Got cid and ring. */ 02444 ast_debug(1, "CID got string '%s'\n", dtmfbuf); 02445 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 02446 ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags); 02447 /* If first byte is NULL, we have no cid */ 02448 if (!ast_strlen_zero(dtmfcid)) { 02449 number = dtmfcid; 02450 } else { 02451 number = NULL; 02452 } 02453 02454 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 02455 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 02456 int timeout = 10000; /* Ten seconds */ 02457 struct timeval start = ast_tvnow(); 02458 enum analog_event ev; 02459 02460 namebuf[0] = 0; 02461 numbuf[0] = 0; 02462 02463 if (!analog_start_cid_detect(p, p->cid_signalling)) { 02464 int off_ms; 02465 int ms; 02466 struct timeval off_start; 02467 while (1) { 02468 res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start)); 02469 02470 if (res == 0) { 02471 break; 02472 } 02473 02474 if (res == 1) { 02475 if (ev == ANALOG_EVENT_NOALARM) { 02476 analog_set_alarm(p, 0); 02477 } 02478 if (p->cid_signalling == CID_SIG_V23_JP) { 02479 if (ev == ANALOG_EVENT_RINGBEGIN) { 02480 analog_off_hook(p); 02481 usleep(1); 02482 } 02483 } else { 02484 ev = ANALOG_EVENT_NONE; 02485 break; 02486 } 02487 } 02488 02489 if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) 02490 break; 02491 02492 } 02493 name = namebuf; 02494 number = numbuf; 02495 02496 analog_stop_cid_detect(p); 02497 02498 if (p->cid_signalling == CID_SIG_V23_JP) { 02499 res = analog_on_hook(p); 02500 usleep(1); 02501 } 02502 02503 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 02504 off_start = ast_tvnow(); 02505 off_ms = 4000;/* This is a typical OFF time between rings. */ 02506 while ((ms = ast_remaining_ms(off_start, off_ms))) { 02507 struct ast_frame *f; 02508 02509 res = ast_waitfor(chan, ms); 02510 if (res <= 0) { 02511 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 02512 "Exiting simple switch\n"); 02513 ast_hangup(chan); 02514 goto quit; 02515 } 02516 if (!(f = ast_read(chan))) { 02517 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n"); 02518 ast_hangup(chan); 02519 goto quit; 02520 } 02521 ast_frfree(f); 02522 if (chan->_state == AST_STATE_RING || 02523 chan->_state == AST_STATE_RINGING) 02524 break; /* Got ring */ 02525 } 02526 02527 if (analog_distinctive_ring(chan, p, idx, NULL)) { 02528 goto quit; 02529 } 02530 02531 if (res < 0) { 02532 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 02533 } 02534 } else { 02535 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 02536 } 02537 } else { 02538 ast_log(LOG_WARNING, "Channel %s in prering " 02539 "state, but I have nothing to do. " 02540 "Terminating simple switch, should be " 02541 "restarted by the actual ring.\n", 02542 chan->name); 02543 ast_hangup(chan); 02544 goto quit; 02545 } 02546 } else if (p->use_callerid && p->cid_start == ANALOG_CID_START_RING) { 02547 int timeout = 10000; /* Ten seconds */ 02548 struct timeval start = ast_tvnow(); 02549 enum analog_event ev; 02550 int curRingData[RING_PATTERNS] = { 0 }; 02551 int receivedRingT = 0; 02552 02553 namebuf[0] = 0; 02554 numbuf[0] = 0; 02555 02556 if (!analog_start_cid_detect(p, p->cid_signalling)) { 02557 while (1) { 02558 res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start)); 02559 02560 if (res == 0) { 02561 break; 02562 } 02563 02564 if (res == 1 || res == 2) { 02565 if (ev == ANALOG_EVENT_NOALARM) { 02566 analog_set_alarm(p, 0); 02567 } else if (ev == ANALOG_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 02568 ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 02569 p->polarity = POLARITY_IDLE; 02570 ast_hangup(chan); 02571 goto quit; 02572 } else if (ev != ANALOG_EVENT_NONE && ev != ANALOG_EVENT_RINGBEGIN && ev != ANALOG_EVENT_RINGOFFHOOK) { 02573 break; 02574 } 02575 if (res != 2) { 02576 /* Let us detect callerid when the telco uses distinctive ring */ 02577 curRingData[receivedRingT] = p->ringt; 02578 02579 if (p->ringt < p->ringt_base/2) { 02580 break; 02581 } 02582 /* Increment the ringT counter so we can match it against 02583 values in chan_dahdi.conf for distinctive ring */ 02584 if (++receivedRingT == RING_PATTERNS) { 02585 break; 02586 } 02587 } 02588 } 02589 02590 if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) { 02591 break; 02592 } 02593 02594 } 02595 name = namebuf; 02596 number = numbuf; 02597 02598 analog_stop_cid_detect(p); 02599 02600 if (analog_distinctive_ring(chan, p, idx, curRingData)) { 02601 goto quit; 02602 } 02603 02604 if (res < 0) { 02605 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 02606 } 02607 } else { 02608 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 02609 } 02610 } else { 02611 cs = NULL; 02612 } 02613 02614 if (number) { 02615 ast_shrink_phone_number(number); 02616 } 02617 ast_set_callerid(chan, number, name, number); 02618 02619 if (cs) { 02620 callerid_free(cs); 02621 } 02622 02623 analog_handle_notify_message(chan, p, flags, -1); 02624 02625 ast_setstate(chan, AST_STATE_RING); 02626 chan->rings = 1; 02627 analog_set_ringtimeout(p, p->ringt_base); 02628 res = ast_pbx_run(chan); 02629 if (res) { 02630 ast_hangup(chan); 02631 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 02632 } 02633 goto quit; 02634 default: 02635 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); 02636 break; 02637 } 02638 res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION); 02639 if (res < 0) { 02640 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 02641 } 02642 ast_hangup(chan); 02643 quit: 02644 if (smdi_msg) { 02645 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 02646 } 02647 analog_decrease_ss_count(p); 02648 return NULL; 02649 }
static int _analog_get_index | ( | struct ast_channel * | ast, | |
struct analog_pvt * | p, | |||
int | nullok, | |||
const char * | fname, | |||
unsigned long | line | |||
) | [static] |
Definition at line 390 of file sig_analog.c.
References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_log(), analog_pvt::channel, LOG_WARNING, analog_subchannel::owner, and analog_pvt::subs.
00391 { 00392 int res; 00393 if (p->subs[ANALOG_SUB_REAL].owner == ast) { 00394 res = ANALOG_SUB_REAL; 00395 } else if (p->subs[ANALOG_SUB_CALLWAIT].owner == ast) { 00396 res = ANALOG_SUB_CALLWAIT; 00397 } else if (p->subs[ANALOG_SUB_THREEWAY].owner == ast) { 00398 res = ANALOG_SUB_THREEWAY; 00399 } else { 00400 res = -1; 00401 if (!nullok) { 00402 ast_log(LOG_WARNING, 00403 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n", 00404 ast ? ast->name : "", p->channel, fname, line); 00405 } 00406 } 00407 return res; 00408 }
static void analog_all_subchannels_hungup | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 535 of file sig_analog.c.
References analog_callback::all_subchannels_hungup, analog_pvt::calls, and analog_pvt::chan_pvt.
Referenced by analog_hangup().
00536 { 00537 if (p->calls->all_subchannels_hungup) { 00538 p->calls->all_subchannels_hungup(p->chan_pvt); 00539 } 00540 }
static int analog_alloc_sub | ( | struct analog_pvt * | p, | |
enum analog_sub | x | |||
) | [static] |
Definition at line 350 of file sig_analog.c.
References analog_callback::allocate_sub, analog_subchannel::allocd, analog_pvt::calls, analog_pvt::chan_pvt, and analog_pvt::subs.
Referenced by __analog_handle_event(), __analog_ss_thread(), and analog_request().
00351 { 00352 if (p->calls->allocate_sub) { 00353 int res; 00354 res = p->calls->allocate_sub(p->chan_pvt, x); 00355 if (!res) { 00356 p->subs[x].allocd = 1; 00357 } 00358 return res; 00359 } 00360 return 0; 00361 }
int analog_answer | ( | struct analog_pvt * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 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, analog_subchannel::inthreeway, LOG_WARNING, analog_subchannel::owner, 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, LOG_WARNING, 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_subchannel::allocd, analog_is_off_hook(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY, ast_debug, AST_STATE_RINGING, AST_STATE_UP, analog_pvt::callwaiting, analog_pvt::channel, analog_pvt::dnd, analog_pvt::guardtime, analog_subchannel::inthreeway, analog_pvt::outgoing, analog_subchannel::owner, analog_pvt::owner, analog_pvt::sig, and analog_pvt::subs.
Referenced by available().
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, analog_pvt::channel, ast_channel::connected, analog_pvt::dialdest, analog_pvt::dialednone, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, analog_pvt::finaldial, analog_pvt::hanguponpolarityswitch, ast_party_caller::id, ast_party_connected_line::id, analog_pvt::lastcid_name, analog_pvt::lastcid_num, LOG_WARNING, ast_party_id::name, ast_party_id::number, analog_dialoperation::op, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, pbx_builtin_getvar_helper(), analog_pvt::polaritydelaytv, analog_pvt::pulse, S_COR, analog_pvt::sig, ast_party_number::str, ast_party_name::str, analog_pvt::stripmsd, analog_pvt::subs, analog_pvt::use_callerid, ast_party_number::valid, ast_party_name::valid, and analog_pvt::whichwink.
Referenced by dahdi_call().
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 3929 of file sig_analog.c.
References analog_set_callwaiting(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, analog_pvt::permcallwaiting, and analog_pvt::sig.
Referenced by mkintf().
03930 { 03931 /* No call waiting on non FXS channels */ 03932 if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) { 03933 p->permcallwaiting = 0; 03934 } 03935 03936 analog_set_callwaiting(p, p->permcallwaiting); 03937 03938 return 0; 03939 }
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().
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 3924 of file sig_analog.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
03925 { 03926 ast_free(doomed); 03927 }
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 3965 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().
03966 { 03967 if (flag == -1) { 03968 return p->dnd; 03969 } 03970 03971 p->dnd = flag; 03972 03973 ast_verb(3, "%s DND on channel %d\n", 03974 flag ? "Enabled" : "Disabled", 03975 p->channel); 03976 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 03977 "Channel: DAHDI/%d\r\n" 03978 "Status: %s\r\n", p->channel, 03979 flag ? "enabled" : "disabled"); 03980 03981 return 0; 03982 }
static int analog_dsp_reset_and_flush_digits | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 410 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dsp_reset_and_flush_digits.
Referenced by __analog_ss_thread().
00411 { 00412 if (p->calls->dsp_reset_and_flush_digits) { 00413 return p->calls->dsp_reset_and_flush_digits(p->chan_pvt); 00414 } 00415 00416 /* Return 0 since I think this is unnecessary to do in most cases it is used. Mostly only for ast_dsp */ 00417 return 0; 00418 }
static int analog_dsp_set_digitmode | ( | struct analog_pvt * | p, | |
enum analog_dsp_digitmode | mode | |||
) | [static] |
Definition at line 636 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dsp_set_digitmode.
Referenced by __analog_ss_thread(), and analog_hangup().
00637 { 00638 if (p->calls->dsp_set_digitmode) { 00639 return p->calls->dsp_set_digitmode(p->chan_pvt, mode); 00640 } 00641 return -1; 00642 }
static char* analog_event2str | ( | enum analog_event | event | ) | [static] |
Definition at line 247 of file sig_analog.c.
References ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, and ANALOG_EVENT_WINKFLASH.
Referenced by __analog_handle_event(), analog_exception(), and analog_handle_init_event().
00248 { 00249 char *res; 00250 switch (event) { 00251 case ANALOG_EVENT_ONHOOK: 00252 res = "ANALOG_EVENT_ONHOOK"; 00253 break; 00254 case ANALOG_EVENT_RINGOFFHOOK: 00255 res = "ANALOG_EVENT_RINGOFFHOOK"; 00256 break; 00257 case ANALOG_EVENT_WINKFLASH: 00258 res = "ANALOG_EVENT_WINKFLASH"; 00259 break; 00260 case ANALOG_EVENT_ALARM: 00261 res = "ANALOG_EVENT_ALARM"; 00262 break; 00263 case ANALOG_EVENT_NOALARM: 00264 res = "ANALOG_EVENT_NOALARM"; 00265 break; 00266 case ANALOG_EVENT_DIALCOMPLETE: 00267 res = "ANALOG_EVENT_DIALCOMPLETE"; 00268 break; 00269 case ANALOG_EVENT_HOOKCOMPLETE: 00270 res = "ANALOG_EVENT_HOOKCOMPLETE"; 00271 break; 00272 case ANALOG_EVENT_PULSE_START: 00273 res = "ANALOG_EVENT_PULSE_START"; 00274 break; 00275 case ANALOG_EVENT_POLARITY: 00276 res = "ANALOG_EVENT_POLARITY"; 00277 break; 00278 case ANALOG_EVENT_RINGBEGIN: 00279 res = "ANALOG_EVENT_RINGBEGIN"; 00280 break; 00281 case ANALOG_EVENT_EC_DISABLED: 00282 res = "ANALOG_EVENT_EC_DISABLED"; 00283 break; 00284 case ANALOG_EVENT_RINGERON: 00285 res = "ANALOG_EVENT_RINGERON"; 00286 break; 00287 case ANALOG_EVENT_RINGEROFF: 00288 res = "ANALOG_EVENT_RINGEROFF"; 00289 break; 00290 case ANALOG_EVENT_REMOVED: 00291 res = "ANALOG_EVENT_REMOVED"; 00292 break; 00293 case ANALOG_EVENT_NEONMWI_ACTIVE: 00294 res = "ANALOG_EVENT_NEONMWI_ACTIVE"; 00295 break; 00296 case ANALOG_EVENT_NEONMWI_INACTIVE: 00297 res = "ANALOG_EVENT_NEONMWI_INACTIVE"; 00298 break; 00299 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 00300 case ANALOG_EVENT_TX_CED_DETECTED: 00301 res = "ANALOG_EVENT_TX_CED_DETECTED"; 00302 break; 00303 case ANALOG_EVENT_RX_CED_DETECTED: 00304 res = "ANALOG_EVENT_RX_CED_DETECTED"; 00305 break; 00306 case ANALOG_EVENT_EC_NLP_DISABLED: 00307 res = "ANALOG_EVENT_EC_NLP_DISABLED"; 00308 break; 00309 case ANALOG_EVENT_EC_NLP_ENABLED: 00310 res = "ANALOG_EVENT_EC_NLP_ENABLED"; 00311 break; 00312 #endif 00313 case ANALOG_EVENT_PULSEDIGIT: 00314 res = "ANALOG_EVENT_PULSEDIGIT"; 00315 break; 00316 case ANALOG_EVENT_DTMFDOWN: 00317 res = "ANALOG_EVENT_DTMFDOWN"; 00318 break; 00319 case ANALOG_EVENT_DTMFUP: 00320 res = "ANALOG_EVENT_DTMFUP"; 00321 break; 00322 default: 00323 res = "UNKNOWN/OTHER"; 00324 break; 00325 } 00326 00327 return res; 00328 }
struct ast_frame* analog_exception | ( | struct analog_pvt * | p, | |
struct ast_channel * | ast | |||
) | [read] |
Definition at line 3525 of file sig_analog.c.
References __analog_handle_event(), ast_channel::_state, analog_event2str(), ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_event(), analog_get_index, analog_lock_private(), analog_off_hook(), analog_ring(), analog_set_dialing(), analog_set_echocanceller(), analog_set_new_owner(), analog_stop_callwait(), ANALOG_SUB_REAL, analog_unlock_private(), analog_update_conf(), ast_bridged_channel(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_tv(), ast_verb, analog_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, analog_subchannel::f, f, ast_channel::fds, analog_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::mallocd, name, ast_frame::offset, analog_subchannel::owner, analog_pvt::owner, ast_frame::ptr, ast_frame::samples, ast_frame::src, ast_frame::subclass, and analog_pvt::subs.
Referenced by dahdi_exception(), and dahdi_read().
03526 { 03527 int res; 03528 int idx; 03529 struct ast_frame *f; 03530 03531 ast_debug(1, "%s %d\n", __FUNCTION__, p->channel); 03532 03533 idx = analog_get_index(ast, p, 1); 03534 if (idx < 0) { 03535 idx = ANALOG_SUB_REAL; 03536 } 03537 03538 p->subs[idx].f.frametype = AST_FRAME_NULL; 03539 p->subs[idx].f.datalen = 0; 03540 p->subs[idx].f.samples = 0; 03541 p->subs[idx].f.mallocd = 0; 03542 p->subs[idx].f.offset = 0; 03543 p->subs[idx].f.subclass.integer = 0; 03544 p->subs[idx].f.delivery = ast_tv(0,0); 03545 p->subs[idx].f.src = "dahdi_exception"; 03546 p->subs[idx].f.data.ptr = NULL; 03547 03548 if (!p->owner) { 03549 /* If nobody owns us, absorb the event appropriately, otherwise 03550 we loop indefinitely. This occurs when, during call waiting, the 03551 other end hangs up our channel so that it no longer exists, but we 03552 have neither FLASH'd nor ONHOOK'd to signify our desire to 03553 change to the other channel. */ 03554 res = analog_get_event(p); 03555 03556 /* Switch to real if there is one and this isn't something really silly... */ 03557 if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) && 03558 (res != ANALOG_EVENT_HOOKCOMPLETE)) { 03559 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res); 03560 analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner); 03561 if (p->owner && ast != p->owner) { 03562 /* 03563 * Could this even happen? 03564 * Possible deadlock because we do not have the real-call lock. 03565 */ 03566 ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n", 03567 analog_event2str(res), ast->name, p->owner->name); 03568 } 03569 if (p->owner && ast_bridged_channel(p->owner)) { 03570 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 03571 } 03572 } 03573 switch (res) { 03574 case ANALOG_EVENT_ONHOOK: 03575 analog_set_echocanceller(p, 0); 03576 if (p->owner) { 03577 ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name); 03578 analog_ring(p); 03579 analog_stop_callwait(p); 03580 } else { 03581 ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n", 03582 analog_event2str(res)); 03583 } 03584 analog_update_conf(p); 03585 break; 03586 case ANALOG_EVENT_RINGOFFHOOK: 03587 analog_set_echocanceller(p, 1); 03588 analog_off_hook(p); 03589 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 03590 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 03591 analog_set_dialing(p, 0); 03592 } 03593 break; 03594 case ANALOG_EVENT_HOOKCOMPLETE: 03595 case ANALOG_EVENT_RINGERON: 03596 case ANALOG_EVENT_RINGEROFF: 03597 /* Do nothing */ 03598 break; 03599 case ANALOG_EVENT_WINKFLASH: 03600 gettimeofday(&p->flashtime, NULL); 03601 if (p->owner) { 03602 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 03603 if (p->owner->_state != AST_STATE_UP) { 03604 /* Answer if necessary */ 03605 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 03606 ast_setstate(p->owner, AST_STATE_UP); 03607 } 03608 analog_stop_callwait(p); 03609 if (ast_bridged_channel(p->owner)) { 03610 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 03611 } 03612 } else { 03613 ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n", 03614 analog_event2str(res)); 03615 } 03616 analog_update_conf(p); 03617 break; 03618 default: 03619 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res)); 03620 break; 03621 } 03622 f = &p->subs[idx].f; 03623 return f; 03624 } 03625 ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 03626 /* If it's not us, return NULL immediately */ 03627 if (ast != p->owner) { 03628 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 03629 f = &p->subs[idx].f; 03630 return f; 03631 } 03632 03633 f = __analog_handle_event(p, ast); 03634 if (!f) { 03635 const char *name = ast_strdupa(ast->name); 03636 03637 /* Tell the CDR this DAHDI device hung up */ 03638 analog_unlock_private(p); 03639 ast_channel_unlock(ast); 03640 ast_set_hangupsource(ast, name, 0); 03641 ast_channel_lock(ast); 03642 analog_lock_private(p); 03643 } 03644 return f; 03645 }
int analog_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan, | |||
void * | newp | |||
) |
Definition at line 3947 of file sig_analog.c.
References analog_set_new_owner(), analog_update_conf(), ast_debug, analog_pvt::channel, analog_subchannel::owner, analog_pvt::owner, and analog_pvt::subs.
Referenced by dahdi_fixup().
03948 { 03949 struct analog_pvt *new_pvt = newp; 03950 int x; 03951 ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name); 03952 if (new_pvt->owner == oldchan) { 03953 analog_set_new_owner(new_pvt, newchan); 03954 } 03955 for (x = 0; x < 3; x++) { 03956 if (new_pvt->subs[x].owner == oldchan) { 03957 new_pvt->subs[x].owner = newchan; 03958 } 03959 } 03960 03961 analog_update_conf(new_pvt); 03962 return 0; 03963 }
static int analog_flash | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 487 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::flash.
Referenced by __analog_ss_thread().
void analog_free | ( | struct analog_pvt * | p | ) |
Definition at line 3941 of file sig_analog.c.
References ast_free.
03942 { 03943 ast_free(p); 03944 }
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(chan); 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().
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, analog_subchannel::f, f, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, ast_party_id::name, ast_party_id::number, ast_party_number::str, ast_party_name::str, ast_frame::subclass, and analog_pvt::subs.
Referenced by __analog_handle_event(), and dahdi_read().
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 3647 of file sig_analog.c.
References __analog_ss_thread(), analog_cancel_cidspill(), ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, analog_event2str(), ANALOG_EVENT_ALARM, ANALOG_EVENT_DTMFCID, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_and_handle_alarms(), analog_handle_notify_message(), analog_has_voicemail(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_alarm(), analog_set_echocanceller(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_sigtype_to_str(), analog_start_polarityswitch(), ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALTONE, ANALOG_TONE_RINGTONE, ANALOG_TONE_STUTTER, ast_debug, ast_hangup(), ast_log(), ast_pthread_create_detached, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verb, analog_pvt::chan_pvt, analog_pvt::channel, analog_pvt::cid_start, errno, EVENT_FLAG_SYSTEM, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, analog_pvt::immediate, analog_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event, analog_pvt::polarity, POLARITY_REV, analog_pvt::ringt_base, analog_pvt::sig, and analog_pvt::ss_astchan.
Referenced by do_monitor().
03648 { 03649 int res; 03650 pthread_t threadid; 03651 struct ast_channel *chan; 03652 03653 ast_debug(1, "channel (%d) - signaling (%d) - event (%s)\n", 03654 i->channel, i->sig, analog_event2str(event)); 03655 03656 /* Handle an event on a given channel for the monitor thread. */ 03657 switch (event) { 03658 case ANALOG_EVENT_WINKFLASH: 03659 case ANALOG_EVENT_RINGOFFHOOK: 03660 if (i->inalarm) { 03661 break; 03662 } 03663 /* Got a ring/answer. What kind of channel are we? */ 03664 switch (i->sig) { 03665 case ANALOG_SIG_FXOLS: 03666 case ANALOG_SIG_FXOGS: 03667 case ANALOG_SIG_FXOKS: 03668 res = analog_off_hook(i); 03669 i->fxsoffhookstate = 1; 03670 if (res && (errno == EBUSY)) { 03671 break; 03672 } 03673 03674 /* Cancel VMWI spill */ 03675 analog_cancel_cidspill(i); 03676 03677 if (i->immediate) { 03678 analog_set_echocanceller(i, 1); 03679 /* The channel is immediately up. Start right away */ 03680 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE); 03681 chan = analog_new_ast_channel(i, AST_STATE_RING, 1, ANALOG_SUB_REAL, NULL); 03682 if (!chan) { 03683 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 03684 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03685 if (res < 0) { 03686 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03687 } 03688 } 03689 } else { 03690 /* Check for callerid, digits, etc */ 03691 chan = analog_new_ast_channel(i, AST_STATE_RESERVED, 0, ANALOG_SUB_REAL, NULL); 03692 i->ss_astchan = chan; 03693 if (chan) { 03694 if (analog_has_voicemail(i)) { 03695 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER); 03696 } else { 03697 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE); 03698 } 03699 if (res < 0) 03700 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 03701 03702 if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03703 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03704 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03705 if (res < 0) { 03706 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03707 } 03708 ast_hangup(chan); 03709 } 03710 } else 03711 ast_log(LOG_WARNING, "Unable to create channel\n"); 03712 } 03713 break; 03714 case ANALOG_SIG_FXSLS: 03715 case ANALOG_SIG_FXSGS: 03716 case ANALOG_SIG_FXSKS: 03717 analog_set_ringtimeout(i, i->ringt_base); 03718 /* Fall through */ 03719 case ANALOG_SIG_EMWINK: 03720 case ANALOG_SIG_FEATD: 03721 case ANALOG_SIG_FEATDMF: 03722 case ANALOG_SIG_FEATDMF_TA: 03723 case ANALOG_SIG_E911: 03724 case ANALOG_SIG_FGC_CAMA: 03725 case ANALOG_SIG_FGC_CAMAMF: 03726 case ANALOG_SIG_FEATB: 03727 case ANALOG_SIG_EM: 03728 case ANALOG_SIG_EM_E1: 03729 case ANALOG_SIG_SFWINK: 03730 case ANALOG_SIG_SF_FEATD: 03731 case ANALOG_SIG_SF_FEATDMF: 03732 case ANALOG_SIG_SF_FEATB: 03733 case ANALOG_SIG_SF: 03734 /* Check for callerid, digits, etc */ 03735 if (i->cid_start == ANALOG_CID_START_POLARITY_IN || i->cid_start == ANALOG_CID_START_DTMF_NOALERT) { 03736 chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL); 03737 } else { 03738 chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL); 03739 } 03740 i->ss_astchan = chan; 03741 if (!chan) { 03742 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 03743 } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03744 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03745 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03746 if (res < 0) { 03747 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03748 } 03749 ast_hangup(chan); 03750 } 03751 break; 03752 default: 03753 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); 03754 res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION); 03755 if (res < 0) { 03756 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 03757 } 03758 return NULL; 03759 } 03760 break; 03761 case ANALOG_EVENT_NOALARM: 03762 analog_set_alarm(i, 0); 03763 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 03764 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 03765 "Channel: %d\r\n", i->channel); 03766 break; 03767 case ANALOG_EVENT_ALARM: 03768 analog_set_alarm(i, 1); 03769 analog_get_and_handle_alarms(i); 03770 /* fall thru intentionally */ 03771 case ANALOG_EVENT_ONHOOK: 03772 /* Back on hook. Hang up. */ 03773 switch (i->sig) { 03774 case ANALOG_SIG_FXOLS: 03775 case ANALOG_SIG_FXOGS: 03776 i->fxsoffhookstate = 0; 03777 analog_start_polarityswitch(i); 03778 /* Fall through */ 03779 case ANALOG_SIG_FEATD: 03780 case ANALOG_SIG_FEATDMF: 03781 case ANALOG_SIG_FEATDMF_TA: 03782 case ANALOG_SIG_E911: 03783 case ANALOG_SIG_FGC_CAMA: 03784 case ANALOG_SIG_FGC_CAMAMF: 03785 case ANALOG_SIG_FEATB: 03786 case ANALOG_SIG_EM: 03787 case ANALOG_SIG_EM_E1: 03788 case ANALOG_SIG_EMWINK: 03789 case ANALOG_SIG_SF_FEATD: 03790 case ANALOG_SIG_SF_FEATDMF: 03791 case ANALOG_SIG_SF_FEATB: 03792 case ANALOG_SIG_SF: 03793 case ANALOG_SIG_SFWINK: 03794 case ANALOG_SIG_FXSLS: 03795 case ANALOG_SIG_FXSGS: 03796 case ANALOG_SIG_FXSKS: 03797 analog_set_echocanceller(i, 0); 03798 res = analog_play_tone(i, ANALOG_SUB_REAL, -1); 03799 analog_on_hook(i); 03800 break; 03801 case ANALOG_SIG_FXOKS: 03802 i->fxsoffhookstate = 0; 03803 analog_start_polarityswitch(i); 03804 analog_set_echocanceller(i, 0); 03805 /* Diddle the battery for the zhone */ 03806 #ifdef ZHONE_HACK 03807 analog_off_hook(i); 03808 usleep(1); 03809 #endif 03810 res = analog_play_tone(i, ANALOG_SUB_REAL, -1); 03811 analog_on_hook(i); 03812 break; 03813 default: 03814 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); 03815 res = analog_play_tone(i, ANALOG_SUB_REAL, -1); 03816 return NULL; 03817 } 03818 break; 03819 case ANALOG_EVENT_POLARITY: 03820 switch (i->sig) { 03821 case ANALOG_SIG_FXSLS: 03822 case ANALOG_SIG_FXSKS: 03823 case ANALOG_SIG_FXSGS: 03824 /* We have already got a PR before the channel was 03825 created, but it wasn't handled. We need polarity 03826 to be REV for remote hangup detection to work. 03827 At least in Spain */ 03828 if (i->hanguponpolarityswitch) { 03829 i->polarity = POLARITY_REV; 03830 } 03831 if (i->cid_start == ANALOG_CID_START_POLARITY || i->cid_start == ANALOG_CID_START_POLARITY_IN) { 03832 i->polarity = POLARITY_REV; 03833 ast_verb(2, "Starting post polarity " 03834 "CID detection on channel %d\n", 03835 i->channel); 03836 chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL); 03837 i->ss_astchan = chan; 03838 if (!chan) { 03839 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 03840 } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03841 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03842 ast_hangup(chan); 03843 } 03844 } 03845 break; 03846 default: 03847 ast_log(LOG_WARNING, "handle_init_event detected " 03848 "polarity reversal on non-FXO (ANALOG_SIG_FXS) " 03849 "interface %d\n", i->channel); 03850 break; 03851 } 03852 break; 03853 case ANALOG_EVENT_DTMFCID: 03854 switch (i->sig) { 03855 case ANALOG_SIG_FXSLS: 03856 case ANALOG_SIG_FXSKS: 03857 case ANALOG_SIG_FXSGS: 03858 if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) { 03859 ast_verb(2, "Starting DTMF CID detection on channel %d\n", 03860 i->channel); 03861 chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL); 03862 i->ss_astchan = chan; 03863 if (!chan) { 03864 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 03865 } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) { 03866 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 03867 ast_hangup(chan); 03868 } 03869 } 03870 break; 03871 default: 03872 ast_log(LOG_WARNING, "handle_init_event detected " 03873 "dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) " 03874 "interface %d\n", i->channel); 03875 break; 03876 } 03877 break; 03878 case ANALOG_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */ 03879 ast_log(LOG_NOTICE, "Got ANALOG_EVENT_REMOVED. Destroying channel %d\n", 03880 i->channel); 03881 return i->chan_pvt; 03882 case ANALOG_EVENT_NEONMWI_ACTIVE: 03883 analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_ACTIVE); 03884 break; 03885 case ANALOG_EVENT_NEONMWI_INACTIVE: 03886 analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_INACTIVE); 03887 break; 03888 } 03889 return NULL; 03890 }
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 ast_frame_subclass::integer, and ast_frame::subclass.
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_subchannel::allocd, analog_all_subchannels_hungup(), ANALOG_DIGITMODE_DTMF, analog_dsp_set_digitmode(), analog_get_index, analog_hangup_polarityswitch(), analog_is_off_hook(), analog_lock_sub_owner(), analog_on_hook(), analog_play_tone(), analog_set_callwaiting(), analog_set_confirmanswer(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_linear_mode(), analog_set_new_owner(), analog_set_outgoing(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, analog_unalloc_sub(), analog_update_conf(), ast_bridged_channel(), ast_channel_setoption(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_free, ast_log(), AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), ast_verb, analog_pvt::callwaitcas, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, analog_pvt::cidrings, analog_pvt::guardtime, analog_pvt::hidecallerid, analog_subchannel::inthreeway, LOG_ERROR, LOG_WARNING, analog_pvt::mohsuggest, analog_pvt::onhooktime, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::owner, analog_subchannel::owner, analog_pvt::permcallwaiting, analog_pvt::permhidecallerid, analog_pvt::polarity, POLARITY_IDLE, S_OR, analog_pvt::sig, analog_pvt::subs, and ast_channel::tech_pvt.
Referenced by dahdi_hangup().
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_pvt::calls, analog_pvt::chan_pvt, analog_callback::deadlock_avoidance_private, analog_subchannel::owner, and analog_pvt::subs.
Referenced by __analog_handle_event(), and analog_hangup().
00572 { 00573 for (;;) { 00574 if (!pvt->subs[sub_idx].owner) { 00575 /* No subchannel owner pointer */ 00576 break; 00577 } 00578 if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) { 00579 /* Got subchannel owner lock */ 00580 break; 00581 } 00582 /* We must unlock the private to avoid the possibility of a deadlock */ 00583 if (pvt->calls->deadlock_avoidance_private) { 00584 pvt->calls->deadlock_avoidance_private(pvt->chan_pvt); 00585 } else { 00586 /* Don't use 100% CPU if required callback not present. */ 00587 usleep(1); 00588 } 00589 } 00590 }
static int analog_my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 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 | |||
) | [read] |
Definition at line 3893 of file sig_analog.c.
References analog_subchannel::allocd, ANALOG_CID_START_RING, ANALOG_SIG_NONE, ANALOG_SUB_REAL, ast_calloc, analog_pvt::calls, analog_pvt::chan_pvt, CID_SIG_BELL, analog_pvt::cid_signalling, analog_pvt::cid_start, analog_pvt::outsigmod, analog_pvt::sig, and analog_pvt::subs.
Referenced by mkintf().
03894 { 03895 struct analog_pvt *p; 03896 03897 p = ast_calloc(1, sizeof(*p)); 03898 if (!p) { 03899 return p; 03900 } 03901 03902 p->calls = c; 03903 p->outsigmod = ANALOG_SIG_NONE; 03904 p->sig = signallingtype; 03905 p->chan_pvt = private_data; 03906 03907 /* Some defaults for values */ 03908 p->cid_start = ANALOG_CID_START_RING; 03909 p->cid_signalling = CID_SIG_BELL; 03910 /* Sub real is assumed to always be alloc'd */ 03911 p->subs[ANALOG_SUB_REAL].allocd = 1; 03912 03913 return p; 03914 }
static struct ast_channel* analog_new_ast_channel | ( | struct analog_pvt * | p, | |
int | state, | |||
int | startpbx, | |||
enum analog_sub | sub, | |||
const struct ast_channel * | requestor | |||
) | [static, read] |
Definition at line 436 of file sig_analog.c.
References analog_set_new_owner(), ast_string_field_set, analog_pvt::call_forward, analog_pvt::calls, analog_pvt::chan_pvt, analog_callback::new_ast_channel, analog_pvt::owner, analog_subchannel::owner, and analog_pvt::subs.
Referenced by __analog_handle_event(), analog_handle_init_event(), and analog_request().
00437 { 00438 struct ast_channel *c; 00439 00440 if (!p->calls->new_ast_channel) { 00441 return NULL; 00442 } 00443 00444 c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub, requestor); 00445 if (c) { 00446 ast_string_field_set(c, call_forward, p->call_forward); 00447 } 00448 p->subs[sub].owner = c; 00449 if (!p->owner) { 00450 analog_set_new_owner(p, c); 00451 } 00452 return c; 00453 }
static int analog_off_hook | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 592 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::off_hook.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_exception(), and analog_handle_init_event().
static int analog_on_hook | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 511 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::on_hook.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_call(), analog_handle_init_event(), and analog_hangup().
static int analog_play_tone | ( | struct analog_pvt * | p, | |
enum analog_sub | sub, | |||
enum analog_tone | tone | |||
) | [static] |
Definition at line 420 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::play_tone.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_call(), analog_handle_init_event(), and analog_hangup().
struct ast_channel* analog_request | ( | struct analog_pvt * | p, | |
int * | callwait, | |||
const struct ast_channel * | requestor | |||
) | [read] |
Definition at line 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().
static int analog_send_callerid | ( | struct analog_pvt * | p, | |
int | cwcid, | |||
struct ast_party_caller * | caller | |||
) | [static] |
Definition at line 373 of file sig_analog.c.
References ast_debug, analog_pvt::calls, analog_pvt::callwaitcas, analog_pvt::chan_pvt, ast_party_caller::id, ast_party_id::name, ast_party_id::number, analog_callback::send_callerid, ast_party_number::str, and ast_party_name::str.
Referenced by __analog_handle_event(), and analog_handle_dtmf().
00374 { 00375 ast_debug(1, "Sending callerid. CID_NAME: '%s' CID_NUM: '%s'\n", 00376 caller->id.name.str, 00377 caller->id.number.str); 00378 00379 if (cwcid) { 00380 p->callwaitcas = 0; 00381 } 00382 00383 if (p->calls->send_callerid) { 00384 return p->calls->send_callerid(p->chan_pvt, cwcid, caller); 00385 } 00386 return 0; 00387 }
static void analog_set_alarm | ( | struct analog_pvt * | p, | |
int | in_alarm | |||
) | [static] |
Definition at line 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().
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().
int analog_ss_thread_start | ( | struct analog_pvt * | p, | |
struct ast_channel * | chan | |||
) |
Definition at line 2651 of file sig_analog.c.
References __analog_ss_thread(), and ast_pthread_create_detached.
Referenced by mwi_thread().
02652 { 02653 pthread_t threadid; 02654 02655 return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p); 02656 }
static int analog_start | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 495 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start.
Referenced by analog_call().
static int analog_start_cid_detect | ( | struct analog_pvt * | p, | |
int | cid_signalling | |||
) | [static] |
Definition at line 159 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start_cid_detect.
Referenced by __analog_ss_thread().
00160 { 00161 if (p->calls->start_cid_detect) { 00162 return p->calls->start_cid_detect(p->chan_pvt, cid_signalling); 00163 } 00164 return -1; 00165 }
static void analog_start_polarityswitch | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 616 of file sig_analog.c.
References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start_polarityswitch.
Referenced by __analog_handle_event(), and analog_handle_init_event().
00617 { 00618 if (p->calls->start_polarityswitch) { 00619 return p->calls->start_polarityswitch(p->chan_pvt); 00620 } 00621 }
static int analog_stop_callwait | ( | struct analog_pvt * | p | ) | [static] |
Definition at line 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, ast_debug, analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::channel, analog_callback::complete_conference_update, analog_callback::conf_add, analog_callback::conf_del, analog_subchannel::inthreeway, and analog_pvt::subs.
Referenced by __analog_handle_event(), analog_exception(), analog_fixup(), and analog_hangup().
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().
char analog_defaultcic[64] = "" [static] |
Definition at line 62 of file sig_analog.c.
Referenced by analog_call().
char analog_defaultozz[64] = "" [static] |
Definition at line 63 of file sig_analog.c.
Referenced by analog_call().
int analog_firstdigittimeout = 16000 [static] |
Definition at line 61 of file sig_analog.c.
Referenced by __analog_ss_thread().
int analog_gendigittimeout = 8000 [static] |
Definition at line 60 of file sig_analog.c.
Referenced by __analog_ss_thread().
int analog_matchdigittimeout = 3000 [static] |
Definition at line 59 of file sig_analog.c.
Referenced by __analog_ss_thread().
unsigned int cid_type |
Definition at line 93 of file sig_analog.c.
struct { ... } cidtypes[] [static] |
Referenced by analog_cidtype_to_str(), and analog_str_to_cidtype().
const char const* name |
Definition at line 67 of file sig_analog.c.
enum analog_sigtype sigtype |
Definition at line 66 of file sig_analog.c.
struct { ... } sigtypes[] [static] |
Referenced by analog_sigtype_to_str(), and analog_str_to_sigtype().