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