Tue Aug 20 16:35:16 2013

Asterisk developer's documentation


sig_analog.c File Reference

Analog signaling module. More...

#include "asterisk.h"
#include <errno.h>
#include <ctype.h>
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/say.h"
#include "asterisk/manager.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/cel.h"
#include "asterisk/causes.h"
#include "sig_analog.h"

Go to the source code of this file.

Defines

#define analog_get_index(ast, p, nullok)   _analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
#define ANALOG_NEED_MFDETECT(p)   (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB))
#define ISTRUNK(p)
#define MIN_MS_SINCE_FLASH   ( (2000) )
#define POLARITY_IDLE   0
#define POLARITY_REV   1

Functions

static struct ast_frame__analog_handle_event (struct analog_pvt *p, struct ast_channel *ast)
static void * __analog_ss_thread (void *data)
static int _analog_get_index (struct ast_channel *ast, struct analog_pvt *p, int nullok, const char *fname, unsigned long line)
static void analog_all_subchannels_hungup (struct analog_pvt *p)
static int analog_alloc_sub (struct analog_pvt *p, enum analog_sub x)
int analog_answer (struct analog_pvt *p, struct ast_channel *ast)
static void analog_answer_polarityswitch (struct analog_pvt *p)
static int analog_attempt_transfer (struct analog_pvt *p, int inthreeway)
int analog_available (struct analog_pvt *p)
int analog_call (struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout)
static int analog_callwait (struct analog_pvt *p)
static void analog_cancel_cidspill (struct analog_pvt *p)
static int analog_canmatch_featurecode (const char *exten)
static void analog_cb_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
static int analog_check_confirmanswer (struct analog_pvt *p)
static int analog_check_for_conference (struct analog_pvt *p)
static int analog_check_waitingfordt (struct analog_pvt *p)
const char * analog_cidstart_to_str (enum analog_cid_start cid_start)
const char * analog_cidtype_to_str (unsigned int cid_type)
int analog_config_complete (struct analog_pvt *p)
static int analog_confmute (struct analog_pvt *p, int mute)
static int analog_decrease_ss_count (struct analog_pvt *p)
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure.
static int analog_dial_digits (struct analog_pvt *p, enum analog_sub sub, struct analog_dialoperation *dop)
static int analog_distinctive_ring (struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata)
int analog_dnd (struct analog_pvt *p, int flag)
static int analog_dsp_reset_and_flush_digits (struct analog_pvt *p)
static int analog_dsp_set_digitmode (struct analog_pvt *p, enum analog_dsp_digitmode mode)
static char * analog_event2str (enum analog_event event)
struct ast_frameanalog_exception (struct analog_pvt *p, struct ast_channel *ast)
int analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
static int analog_flash (struct analog_pvt *p)
void analog_free (struct analog_pvt *p)
static void analog_get_and_handle_alarms (struct analog_pvt *p)
static void * analog_get_bridged_channel (struct analog_pvt *p, struct ast_channel *chan)
static int analog_get_callerid (struct analog_pvt *p, char *name, char *number, enum analog_event *ev, size_t timeout)
static int analog_get_event (struct analog_pvt *p)
static const char * analog_get_orig_dialstring (struct analog_pvt *p)
static int analog_get_sub_fd (struct analog_pvt *p, enum analog_sub sub)
void analog_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub idx, struct ast_frame **dest)
void * analog_handle_init_event (struct analog_pvt *i, int event)
static int analog_handle_notify_message (struct ast_channel *chan, struct analog_pvt *p, int cid_flags, int neon_mwievent)
static int analog_handles_digit (struct ast_frame *f)
int analog_hangup (struct analog_pvt *p, struct ast_channel *ast)
static void analog_hangup_polarityswitch (struct analog_pvt *p)
static int analog_has_voicemail (struct analog_pvt *p)
static int analog_have_progressdetect (struct analog_pvt *p)
static int analog_increase_ss_count (struct analog_pvt *p)
static int analog_is_dialing (struct analog_pvt *p, enum analog_sub index)
static int analog_is_off_hook (struct analog_pvt *p)
static void analog_lock_private (struct analog_pvt *p)
static void analog_lock_sub_owner (struct analog_pvt *pvt, enum analog_sub sub_idx)
static int analog_my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
struct analog_pvtanalog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data)
static struct ast_channelanalog_new_ast_channel (struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
static int analog_off_hook (struct analog_pvt *p)
static int analog_on_hook (struct analog_pvt *p)
static int analog_play_tone (struct analog_pvt *p, enum analog_sub sub, enum analog_tone tone)
struct ast_channelanalog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
static int analog_ring (struct analog_pvt *p)
static int analog_send_callerid (struct analog_pvt *p, int cwcid, struct ast_party_caller *caller)
static void analog_set_alarm (struct analog_pvt *p, int in_alarm)
static void analog_set_cadence (struct analog_pvt *p, struct ast_channel *chan)
static void analog_set_callwaiting (struct analog_pvt *p, int callwaiting_enable)
static void analog_set_confirmanswer (struct analog_pvt *p, int flag)
static void analog_set_dialing (struct analog_pvt *p, int is_dialing)
static int analog_set_echocanceller (struct analog_pvt *p, int enable)
static void analog_set_inthreeway (struct analog_pvt *p, enum analog_sub sub, int inthreeway)
static int analog_set_linear_mode (struct analog_pvt *p, enum analog_sub sub, int linear_mode)
static void analog_set_needringing (struct analog_pvt *p, int value)
static void analog_set_new_owner (struct analog_pvt *p, struct ast_channel *new_owner)
static void analog_set_outgoing (struct analog_pvt *p, int is_outgoing)
static void analog_set_pulsedial (struct analog_pvt *p, int flag)
static void analog_set_ringtimeout (struct analog_pvt *p, int ringt)
static void analog_set_waitingfordt (struct analog_pvt *p, struct ast_channel *ast)
const char * analog_sigtype_to_str (enum analog_sigtype sigtype)
int analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *chan)
static int analog_start (struct analog_pvt *p)
static int analog_start_cid_detect (struct analog_pvt *p, int cid_signalling)
static void analog_start_polarityswitch (struct analog_pvt *p)
static int analog_stop_callwait (struct analog_pvt *p)
static int analog_stop_cid_detect (struct analog_pvt *p)
enum analog_cid_start analog_str_to_cidstart (const char *value)
unsigned int analog_str_to_cidtype (const char *name)
enum analog_sigtype analog_str_to_sigtype (const char *name)
static void analog_swap_subs (struct analog_pvt *p, enum analog_sub a, enum analog_sub b)
static int analog_train_echocanceller (struct analog_pvt *p)
static int analog_unalloc_sub (struct analog_pvt *p, enum analog_sub x)
static void analog_unlock_private (struct analog_pvt *p)
static int analog_update_conf (struct analog_pvt *p)
static int analog_wait_event (struct analog_pvt *p)
static int analog_wink (struct analog_pvt *p, enum analog_sub index)

Variables

static char analog_defaultcic [64] = ""
static char analog_defaultozz [64] = ""
static int analog_firstdigittimeout = 16000
static int analog_gendigittimeout = 8000
static int analog_matchdigittimeout = 3000
struct {
   unsigned int   cid_type
   const char const *   name
cidtypes []
struct {
   const char const *   name
   enum analog_sigtype   sigtype
sigtypes []

Detailed Description

Analog signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_analog.c.


Define Documentation

#define analog_get_index ( ast,
p,
nullok   )     _analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
#define ANALOG_NEED_MFDETECT (  )     (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB))

Definition at line 1717 of file sig_analog.c.

Referenced by __analog_ss_thread().

#define ISTRUNK (  ) 
Value:
((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \
               (p->sig == ANALOG_SIG_FXSGS))

Definition at line 104 of file sig_analog.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 58 of file sig_analog.c.

#define POLARITY_IDLE   0
Note:
Define if you want to check the hook state for an FXO (FXS signalled) interface before dialing on it. Certain FXO interfaces always think they're out of service with this method however.

Definition at line 56 of file sig_analog.c.

#define POLARITY_REV   1

Definition at line 57 of file sig_analog.c.


Function Documentation

static struct ast_frame* __analog_handle_event ( struct analog_pvt p,
struct ast_channel ast 
) [static, read]

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

< Channel is down and available

< Channel is down, but reserved

< Channel is off hook

< Line is busy

< Digits (or equivalent) have been dialed while offhook

< Channel has detected an incoming call and is waiting for ring

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

Definition at line 2658 of file sig_analog.c.

References __analog_ss_thread(), ast_channel::_state, analog_alloc_sub(), analog_answer_polarityswitch(), analog_attempt_transfer(), analog_cancel_cidspill(), analog_check_confirmanswer(), analog_check_for_conference(), analog_check_waitingfordt(), analog_confmute(), analog_dial_digits(), ANALOG_DIAL_OP_REPLACE, analog_event2str(), ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, ANALOG_EVENT_WINKFLASH, analog_get_and_handle_alarms(), analog_get_event(), analog_get_index, analog_get_sub_fd(), analog_handle_dtmf(), analog_has_voicemail(), analog_have_progressdetect(), analog_is_dialing(), analog_lock_private(), analog_lock_sub_owner(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_alarm(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_needringing(), analog_set_new_owner(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_start_polarityswitch(), analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_STUTTER, analog_train_echocanceller(), analog_unalloc_sub(), analog_unlock_private(), analog_update_conf(), ast_party_caller::ani, ast_party_caller::ani2, analog_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CAUSE_NO_ANSWER, ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_null_frame, ast_pthread_create_detached, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup_with_cause(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_channel::caller, analog_pvt::caller, analog_pvt::callwaitcas, analog_pvt::channel, analog_pvt::cid_name, cid_name, analog_pvt::cid_num, cid_num, analog_pvt::cidrings, analog_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, analog_pvt::dialdest, analog_pvt::dialednone, analog_pvt::dialing, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, EVENT_FLAG_SYSTEM, analog_subchannel::f, f, analog_pvt::finaldial, analog_pvt::flashtime, ast_frame::frametype, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, ast_party_caller::id, analog_pvt::inalarm, ast_frame_subclass::integer, analog_subchannel::inthreeway, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event, MIN_MS_SINCE_FLASH, analog_pvt::mohsuggest, analog_pvt::msgstate, ast_party_id::name, ast_party_id::number, ast_frame::offset, analog_pvt::onhooktime, analog_dialoperation::op, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::outgoing, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, ast_channel::pbx, analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, analog_pvt::polaritydelaytv, analog_pvt::polarityonanswerdelay, ast_frame::ptr, ast_channel::rings, analog_pvt::ringt_base, S_COR, S_OR, ast_frame::samples, analog_pvt::sig, ast_frame::src, analog_pvt::ss_astchan, ast_party_name::str, ast_party_number::str, ast_frame::subclass, analog_pvt::subs, analog_pvt::threewaycalling, analog_pvt::transfer, analog_pvt::transfertobusy, ast_party_name::valid, ast_party_number::valid, and analog_pvt::whichwink.

Referenced by analog_exception().

02659 {
02660    int res, x;
02661    int mysig;
02662    enum analog_sub idx;
02663    char *c;
02664    pthread_t threadid;
02665    struct ast_channel *chan;
02666    struct ast_frame *f;
02667 
02668    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
02669 
02670    idx = analog_get_index(ast, p, 0);
02671    if (idx < 0) {
02672       return &ast_null_frame;
02673    }
02674    if (idx != ANALOG_SUB_REAL) {
02675       ast_log(LOG_ERROR, "We got an event on a non real sub.  Fix it!\n");
02676    }
02677 
02678    mysig = p->sig;
02679    if (p->outsigmod > -1) {
02680       mysig = p->outsigmod;
02681    }
02682 
02683    p->subs[idx].f.frametype = AST_FRAME_NULL;
02684    p->subs[idx].f.subclass.integer = 0;
02685    p->subs[idx].f.datalen = 0;
02686    p->subs[idx].f.samples = 0;
02687    p->subs[idx].f.mallocd = 0;
02688    p->subs[idx].f.offset = 0;
02689    p->subs[idx].f.src = "dahdi_handle_event";
02690    p->subs[idx].f.data.ptr = NULL;
02691    f = &p->subs[idx].f;
02692 
02693    res = analog_get_event(p);
02694 
02695    ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, idx);
02696 
02697    if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) {
02698       analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0);
02699       ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
02700       analog_confmute(p, 0);
02701       p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
02702       p->subs[idx].f.subclass.integer = res & 0xff;
02703       analog_handle_dtmf(p, ast, idx, &f);
02704       return f;
02705    }
02706 
02707    if (res & ANALOG_EVENT_DTMFDOWN) {
02708       ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
02709       /* Mute conference */
02710       analog_confmute(p, 1);
02711       p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN;
02712       p->subs[idx].f.subclass.integer = res & 0xff;
02713       analog_handle_dtmf(p, ast, idx, &f);
02714       return f;
02715    }
02716 
02717    switch (res) {
02718    case ANALOG_EVENT_EC_DISABLED:
02719       ast_verb(3, "Channel %d echo canceler disabled due to CED detection\n", p->channel);
02720       analog_set_echocanceller(p, 0);
02721       break;
02722 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
02723    case ANALOG_EVENT_TX_CED_DETECTED:
02724       ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel);
02725       break;
02726    case ANALOG_EVENT_RX_CED_DETECTED:
02727       ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel);
02728       break;
02729    case ANALOG_EVENT_EC_NLP_DISABLED:
02730       ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel);
02731       break;
02732    case ANALOG_EVENT_EC_NLP_ENABLED:
02733       ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel);
02734       break;
02735 #endif
02736    case ANALOG_EVENT_PULSE_START:
02737       /* Stop tone if there's a pulse start and the PBX isn't started */
02738       if (!ast->pbx)
02739          analog_play_tone(p, ANALOG_SUB_REAL, -1);
02740       break;
02741    case ANALOG_EVENT_DIALCOMPLETE:
02742       if (p->inalarm) {
02743          break;
02744       }
02745       x = analog_is_dialing(p, idx);
02746       if (!x) { /* if not still dialing in driver */
02747          analog_set_echocanceller(p, 1);
02748          if (p->echobreak) {
02749             analog_train_echocanceller(p);
02750             ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
02751             p->dop.op = ANALOG_DIAL_OP_REPLACE;
02752             if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) {
02753                int dial_err = errno;
02754                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(dial_err));
02755             }
02756             p->echobreak = 0;
02757          } else {
02758             analog_set_dialing(p, 0);
02759             if ((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) {
02760                /* if thru with dialing after offhook */
02761                if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
02762                   ast_setstate(ast, AST_STATE_UP);
02763                   p->subs[idx].f.frametype = AST_FRAME_CONTROL;
02764                   p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
02765                   break;
02766                } else { /* if to state wait for offhook to dial rest */
02767                   /* we now wait for off hook */
02768                   ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
02769                }
02770             }
02771             if (ast->_state == AST_STATE_DIALING) {
02772                if (analog_have_progressdetect(p)) {
02773                   ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
02774                } else if (analog_check_confirmanswer(p) || (!p->dialednone
02775                   && ((mysig == ANALOG_SIG_EM) || (mysig == ANALOG_SIG_EM_E1)
02776                      || (mysig == ANALOG_SIG_EMWINK) || (mysig == ANALOG_SIG_FEATD)
02777                      || (mysig == ANALOG_SIG_FEATDMF_TA) || (mysig == ANALOG_SIG_FEATDMF)
02778                      || (mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA)
02779                      || (mysig == ANALOG_SIG_FGC_CAMAMF) || (mysig == ANALOG_SIG_FEATB)
02780                      || (mysig == ANALOG_SIG_SF) || (mysig == ANALOG_SIG_SFWINK)
02781                      || (mysig == ANALOG_SIG_SF_FEATD) || (mysig == ANALOG_SIG_SF_FEATDMF)
02782                      || (mysig == ANALOG_SIG_SF_FEATB)))) {
02783                   ast_setstate(ast, AST_STATE_RINGING);
02784                } else if (!p->answeronpolarityswitch) {
02785                   ast_setstate(ast, AST_STATE_UP);
02786                   p->subs[idx].f.frametype = AST_FRAME_CONTROL;
02787                   p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
02788                   /* If aops=0 and hops=1, this is necessary */
02789                   p->polarity = POLARITY_REV;
02790                } else {
02791                   /* Start clean, so we can catch the change to REV polarity when party answers */
02792                   p->polarity = POLARITY_IDLE;
02793                }
02794             }
02795          }
02796       }
02797       break;
02798    case ANALOG_EVENT_ALARM:
02799       analog_set_alarm(p, 1);
02800       analog_get_and_handle_alarms(p);
02801       /* Intentionally fall through to analog_set_echocanceller() call */
02802    case ANALOG_EVENT_ONHOOK:
02803       switch (p->sig) {
02804       case ANALOG_SIG_FXOLS:
02805       case ANALOG_SIG_FXOGS:
02806       case ANALOG_SIG_FXOKS:
02807          analog_start_polarityswitch(p);
02808          p->fxsoffhookstate = 0;
02809          p->onhooktime = time(NULL);
02810          p->msgstate = -1;
02811          /* Check for some special conditions regarding call waiting */
02812          if (idx == ANALOG_SUB_REAL) {
02813             /* The normal line was hung up */
02814             if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
02815                /* Need to hold the lock for real-call, private, and call-waiting call */
02816                analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
02817                if (!p->subs[ANALOG_SUB_CALLWAIT].owner) {
02818                   /*
02819                    * The call waiting call dissappeared.
02820                    * This is now a normal hangup.
02821                    */
02822                   analog_set_echocanceller(p, 0);
02823                   return NULL;
02824                }
02825 
02826                /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
02827                analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
02828                ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
02829                analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
02830                analog_stop_callwait(p);
02831                analog_set_new_owner(p, NULL);
02832                /* Don't start streaming audio yet if the incoming call isn't up yet */
02833                if (p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) {
02834                   analog_set_dialing(p, 1);
02835                }
02836                /* Unlock the call-waiting call that we swapped to real-call. */
02837                ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
02838                analog_ring(p);
02839             } else if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02840                unsigned int mssinceflash;
02841 
02842                /* Need to hold the lock for real-call, private, and 3-way call */
02843                analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY);
02844                if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
02845                   ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
02846                   /* Just hangup */
02847                   return NULL;
02848                }
02849                if (p->owner != ast) {
02850                   ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02851                   ast_log(LOG_WARNING, "This isn't good...\n");
02852                   /* Just hangup */
02853                   return NULL;
02854                }
02855 
02856                mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
02857                ast_debug(1, "Last flash was %d ms ago\n", mssinceflash);
02858                if (mssinceflash < MIN_MS_SINCE_FLASH) {
02859                   /* It hasn't been long enough since the last flashook.  This is probably a bounce on
02860                      hanging up.  Hangup both channels now */
02861                   ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
02862                   ast_queue_hangup_with_cause(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER);
02863                   ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02864                   ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02865                } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
02866                   if (p->transfer) {
02867                      int inthreeway;
02868 
02869                      inthreeway = p->subs[ANALOG_SUB_THREEWAY].inthreeway;
02870 
02871                      /* In any case this isn't a threeway call anymore */
02872                      analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
02873                      analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
02874 
02875                      /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
02876                      if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
02877                         /* Swap subs and dis-own channel */
02878                         analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02879                         /* Unlock the 3-way call that we swapped to real-call. */
02880                         ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
02881                         analog_set_new_owner(p, NULL);
02882                         /* Ring the phone */
02883                         analog_ring(p);
02884                      } else {
02885                         res = analog_attempt_transfer(p, inthreeway);
02886                         if (res < 0) {
02887                            /* Transfer attempt failed. */
02888                            ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02889                            ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02890                         } else if (res) {
02891                            /* Don't actually hang up at this point */
02892                            break;
02893                         }
02894                      }
02895                   } else {
02896                      ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02897                      ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02898                   }
02899                } else {
02900                   /* Swap subs and dis-own channel */
02901                   analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02902                   /* Unlock the 3-way call that we swapped to real-call. */
02903                   ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
02904                   analog_set_new_owner(p, NULL);
02905                   /* Ring the phone */
02906                   analog_ring(p);
02907                }
02908             }
02909          } else {
02910             ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx);
02911          }
02912          /* Fall through */
02913       default:
02914          analog_set_echocanceller(p, 0);
02915          return NULL;
02916       }
02917       break;
02918    case ANALOG_EVENT_RINGOFFHOOK:
02919       if (p->inalarm) {
02920          break;
02921       }
02922       /* for E911, its supposed to wait for offhook then dial
02923          the second half of the dial string */
02924       if (((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
02925          c = strchr(p->dialdest, '/');
02926          if (c) {
02927             c++;
02928          } else {
02929             c = p->dialdest;
02930          }
02931          if (*c) {
02932             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
02933          } else {
02934             ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
02935          }
02936          if (strlen(p->dop.dialstr) > 4) {
02937             memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02938             strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02939             p->echorest[sizeof(p->echorest) - 1] = '\0';
02940             p->echobreak = 1;
02941             p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02942          } else {
02943             p->echobreak = 0;
02944          }
02945          if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) {
02946             int saveerr = errno;
02947             analog_on_hook(p);
02948             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
02949             return NULL;
02950          }
02951          analog_set_dialing(p, 1);
02952          return &p->subs[idx].f;
02953       }
02954       switch (p->sig) {
02955       case ANALOG_SIG_FXOLS:
02956       case ANALOG_SIG_FXOGS:
02957       case ANALOG_SIG_FXOKS:
02958          p->fxsoffhookstate = 1;
02959          switch (ast->_state) {
02960          case AST_STATE_RINGING:
02961             analog_set_echocanceller(p, 1);
02962             analog_train_echocanceller(p);
02963             p->subs[idx].f.frametype = AST_FRAME_CONTROL;
02964             p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
02965             /* Make sure it stops ringing */
02966             analog_set_needringing(p, 0);
02967             analog_off_hook(p);
02968             ast_debug(1, "channel %d answered\n", p->channel);
02969 
02970             /* Cancel any running CallerID spill */
02971             analog_cancel_cidspill(p);
02972 
02973             analog_set_dialing(p, 0);
02974             p->callwaitcas = 0;
02975             if (analog_check_confirmanswer(p)) {
02976                /* Ignore answer if "confirm answer" is enabled */
02977                p->subs[idx].f.frametype = AST_FRAME_NULL;
02978                p->subs[idx].f.subclass.integer = 0;
02979             } else if (!ast_strlen_zero(p->dop.dialstr)) {
02980                /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
02981                res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
02982                if (res < 0) {
02983                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
02984                   p->dop.dialstr[0] = '\0';
02985                   return NULL;
02986                } else {
02987                   ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
02988                   p->subs[idx].f.frametype = AST_FRAME_NULL;
02989                   p->subs[idx].f.subclass.integer = 0;
02990                   analog_set_dialing(p, 1);
02991                }
02992                p->dop.dialstr[0] = '\0';
02993                ast_setstate(ast, AST_STATE_DIALING);
02994             } else {
02995                ast_setstate(ast, AST_STATE_UP);
02996                analog_answer_polarityswitch(p);
02997             }
02998             return &p->subs[idx].f;
02999          case AST_STATE_DOWN:
03000             ast_setstate(ast, AST_STATE_RING);
03001             ast->rings = 1;
03002             p->subs[idx].f.frametype = AST_FRAME_CONTROL;
03003             p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK;
03004             ast_debug(1, "channel %d picked up\n", p->channel);
03005             return &p->subs[idx].f;
03006          case AST_STATE_UP:
03007             /* Make sure it stops ringing */
03008             analog_off_hook(p);
03009             /* Okay -- probably call waiting*/
03010             if (ast_bridged_channel(p->owner)) {
03011                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03012             }
03013             break;
03014          case AST_STATE_RESERVED:
03015             /* Start up dialtone */
03016             if (analog_has_voicemail(p)) {
03017                res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER);
03018             } else {
03019                res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE);
03020             }
03021             break;
03022          default:
03023             ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
03024          }
03025          break;
03026       case ANALOG_SIG_FXSLS:
03027       case ANALOG_SIG_FXSGS:
03028       case ANALOG_SIG_FXSKS:
03029          if (ast->_state == AST_STATE_RING) {
03030             analog_set_ringtimeout(p, p->ringt_base);
03031          }
03032 
03033          /* Fall through */
03034       case ANALOG_SIG_EM:
03035       case ANALOG_SIG_EM_E1:
03036       case ANALOG_SIG_EMWINK:
03037       case ANALOG_SIG_FEATD:
03038       case ANALOG_SIG_FEATDMF:
03039       case ANALOG_SIG_FEATDMF_TA:
03040       case ANALOG_SIG_E911:
03041       case ANALOG_SIG_FGC_CAMA:
03042       case ANALOG_SIG_FGC_CAMAMF:
03043       case ANALOG_SIG_FEATB:
03044       case ANALOG_SIG_SF:
03045       case ANALOG_SIG_SFWINK:
03046       case ANALOG_SIG_SF_FEATD:
03047       case ANALOG_SIG_SF_FEATDMF:
03048       case ANALOG_SIG_SF_FEATB:
03049          switch (ast->_state) {
03050          case AST_STATE_PRERING:
03051             ast_setstate(ast, AST_STATE_RING);
03052             /* Fall through */
03053          case AST_STATE_DOWN:
03054          case AST_STATE_RING:
03055             ast_debug(1, "Ring detected\n");
03056             p->subs[idx].f.frametype = AST_FRAME_CONTROL;
03057             p->subs[idx].f.subclass.integer = AST_CONTROL_RING;
03058             break;
03059          case AST_STATE_RINGING:
03060          case AST_STATE_DIALING:
03061             if (p->outgoing) {
03062                ast_debug(1, "Line answered\n");
03063                if (analog_check_confirmanswer(p)) {
03064                   p->subs[idx].f.frametype = AST_FRAME_NULL;
03065                   p->subs[idx].f.subclass.integer = 0;
03066                } else {
03067                   p->subs[idx].f.frametype = AST_FRAME_CONTROL;
03068                   p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
03069                   ast_setstate(ast, AST_STATE_UP);
03070                }
03071                break;
03072             }
03073             /* Fall through */
03074          default:
03075             ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
03076             break;
03077          }
03078          break;
03079       default:
03080          ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
03081          break;
03082       }
03083       break;
03084    case ANALOG_EVENT_RINGBEGIN:
03085       switch (p->sig) {
03086       case ANALOG_SIG_FXSLS:
03087       case ANALOG_SIG_FXSGS:
03088       case ANALOG_SIG_FXSKS:
03089          if (ast->_state == AST_STATE_RING) {
03090             analog_set_ringtimeout(p, p->ringt_base);
03091          }
03092          break;
03093       default:
03094          break;
03095       }
03096       break;
03097    case ANALOG_EVENT_RINGEROFF:
03098       if (p->inalarm) break;
03099       ast->rings++;
03100       if (ast->rings == p->cidrings) {
03101          analog_send_callerid(p, 0, &p->caller);
03102       }
03103 
03104       if (ast->rings > p->cidrings) {
03105          analog_cancel_cidspill(p);
03106          p->callwaitcas = 0;
03107       }
03108       p->subs[idx].f.frametype = AST_FRAME_CONTROL;
03109       p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING;
03110       break;
03111    case ANALOG_EVENT_RINGERON:
03112       break;
03113    case ANALOG_EVENT_NOALARM:
03114       analog_set_alarm(p, 0);
03115       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
03116       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
03117          "Channel: %d\r\n", p->channel);
03118       break;
03119    case ANALOG_EVENT_WINKFLASH:
03120       if (p->inalarm) {
03121          break;
03122       }
03123       /* Remember last time we got a flash-hook */
03124       gettimeofday(&p->flashtime, NULL);
03125       switch (mysig) {
03126       case ANALOG_SIG_FXOLS:
03127       case ANALOG_SIG_FXOGS:
03128       case ANALOG_SIG_FXOKS:
03129          ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
03130             idx, analog_get_sub_fd(p, ANALOG_SUB_REAL), analog_get_sub_fd(p, ANALOG_SUB_CALLWAIT), analog_get_sub_fd(p, ANALOG_SUB_THREEWAY));
03131 
03132          /* Cancel any running CallerID spill */
03133          analog_cancel_cidspill(p);
03134          p->callwaitcas = 0;
03135 
03136          if (idx != ANALOG_SUB_REAL) {
03137             ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel);
03138             goto winkflashdone;
03139          }
03140 
03141          if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
03142             /* Need to hold the lock for real-call, private, and call-waiting call */
03143             analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
03144             if (!p->subs[ANALOG_SUB_CALLWAIT].owner) {
03145                /*
03146                 * The call waiting call dissappeared.
03147                 * Let's just ignore this flash-hook.
03148                 */
03149                ast_log(LOG_NOTICE, "Whoa, the call-waiting call disappeared.\n");
03150                goto winkflashdone;
03151             }
03152 
03153             /* Swap to call-wait */
03154             analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT);
03155             analog_play_tone(p, ANALOG_SUB_REAL, -1);
03156             analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03157             ast_debug(1, "Making %s the new owner\n", p->owner->name);
03158             if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RINGING) {
03159                ast_setstate(p->subs[ANALOG_SUB_REAL].owner, AST_STATE_UP);
03160                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
03161             }
03162             analog_stop_callwait(p);
03163 
03164             /* Start music on hold if appropriate */
03165             if (!p->subs[ANALOG_SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) {
03166                ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
03167                   S_OR(p->mohsuggest, NULL),
03168                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03169             }
03170             if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
03171                ast_queue_control_data(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_HOLD,
03172                   S_OR(p->mohsuggest, NULL),
03173                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03174             }
03175             ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
03176 
03177             /* Unlock the call-waiting call that we swapped to real-call. */
03178             ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
03179          } else if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
03180             if (!p->threewaycalling) {
03181                /* Just send a flash if no 3-way calling */
03182                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_FLASH);
03183                goto winkflashdone;
03184             } else if (!analog_check_for_conference(p)) {
03185                char cid_num[256];
03186                char cid_name[256];
03187 
03188                cid_num[0] = '\0';
03189                cid_name[0] = '\0';
03190                if (p->dahditrcallerid && p->owner) {
03191                   if (p->owner->caller.id.number.valid
03192                      && p->owner->caller.id.number.str) {
03193                      ast_copy_string(cid_num, p->owner->caller.id.number.str,
03194                         sizeof(cid_num));
03195                   }
03196                   if (p->owner->caller.id.name.valid
03197                      && p->owner->caller.id.name.str) {
03198                      ast_copy_string(cid_name, p->owner->caller.id.name.str,
03199                         sizeof(cid_name));
03200                   }
03201                }
03202                /* XXX This section needs much more error checking!!! XXX */
03203                /* Start a 3-way call if feasible */
03204                if (!((ast->pbx) ||
03205                   (ast->_state == AST_STATE_UP) ||
03206                   (ast->_state == AST_STATE_RING))) {
03207                   ast_debug(1, "Flash when call not up or ringing\n");
03208                   goto winkflashdone;
03209                }
03210                if (analog_alloc_sub(p, ANALOG_SUB_THREEWAY)) {
03211                   ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
03212                   goto winkflashdone;
03213                }
03214 
03215                /*
03216                 * Make new channel
03217                 *
03218                 * We cannot hold the p or ast locks while creating a new
03219                 * channel.
03220                 */
03221                analog_unlock_private(p);
03222                ast_channel_unlock(ast);
03223                chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY, NULL);
03224                ast_channel_lock(ast);
03225                analog_lock_private(p);
03226                if (!chan) {
03227                   ast_log(LOG_WARNING,
03228                      "Cannot allocate new call structure on channel %d\n",
03229                      p->channel);
03230                   analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
03231                   goto winkflashdone;
03232                }
03233                if (p->dahditrcallerid) {
03234                   if (!p->origcid_num) {
03235                      p->origcid_num = ast_strdup(p->cid_num);
03236                   }
03237                   if (!p->origcid_name) {
03238                      p->origcid_name = ast_strdup(p->cid_name);
03239                   }
03240                   ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
03241                   ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
03242                }
03243                /* Swap things around between the three-way and real call */
03244                analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
03245                /* Disable echo canceller for better dialing */
03246                analog_set_echocanceller(p, 0);
03247                res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALRECALL);
03248                if (res) {
03249                   ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
03250                }
03251                analog_set_new_owner(p, chan);
03252                p->ss_astchan = chan;
03253                if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p)) {
03254                   ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
03255                   res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03256                   analog_set_echocanceller(p, 1);
03257                   ast_hangup(chan);
03258                } else {
03259                   ast_verb(3, "Started three way call on channel %d\n", p->channel);
03260 
03261                   /* Start music on hold if appropriate */
03262                   if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
03263                      ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD,
03264                         S_OR(p->mohsuggest, NULL),
03265                         !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03266                   }
03267                }
03268             }
03269          } else {
03270             /* Already have a 3 way call */
03271             enum analog_sub orig_3way_sub;
03272 
03273             /* Need to hold the lock for real-call, private, and 3-way call */
03274             analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY);
03275             if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
03276                /*
03277                 * The 3-way call dissappeared.
03278                 * Let's just ignore this flash-hook.
03279                 */
03280                ast_log(LOG_NOTICE, "Whoa, the 3-way call disappeared.\n");
03281                goto winkflashdone;
03282             }
03283             orig_3way_sub = ANALOG_SUB_THREEWAY;
03284 
03285             if (p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
03286                /* Call is already up, drop the last person */
03287                ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
03288                /* If the primary call isn't answered yet, use it */
03289                if ((p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) &&
03290                   (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
03291                   /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
03292                   analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
03293                   orig_3way_sub = ANALOG_SUB_REAL;
03294                   analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03295                }
03296                /* Drop the last call and stop the conference */
03297                ast_verb(3, "Dropping three-way call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name);
03298                ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
03299                analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
03300                analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
03301             } else {
03302                /* Lets see what we're up to */
03303                if (((ast->pbx) || (ast->_state == AST_STATE_UP)) &&
03304                   (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
03305                   ast_verb(3, "Building conference call with %s and %s\n",
03306                      p->subs[ANALOG_SUB_THREEWAY].owner->name,
03307                      p->subs[ANALOG_SUB_REAL].owner->name);
03308                   /* Put them in the threeway, and flip */
03309                   analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 1);
03310                   analog_set_inthreeway(p, ANALOG_SUB_REAL, 1);
03311                   if (ast->_state == AST_STATE_UP) {
03312                      analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
03313                      orig_3way_sub = ANALOG_SUB_REAL;
03314                   }
03315                   if (ast_bridged_channel(p->subs[orig_3way_sub].owner)) {
03316                      ast_queue_control(p->subs[orig_3way_sub].owner, AST_CONTROL_UNHOLD);
03317                   }
03318                   analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03319                } else {
03320                   ast_verb(3, "Dumping incomplete call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name);
03321                   analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
03322                   orig_3way_sub = ANALOG_SUB_REAL;
03323                   ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
03324                   analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03325                   if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
03326                      ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
03327                   }
03328                   analog_set_echocanceller(p, 1);
03329                }
03330             }
03331             ast_channel_unlock(p->subs[orig_3way_sub].owner);
03332          }
03333 winkflashdone:
03334          analog_update_conf(p);
03335          break;
03336       case ANALOG_SIG_EM:
03337       case ANALOG_SIG_EM_E1:
03338       case ANALOG_SIG_FEATD:
03339       case ANALOG_SIG_SF:
03340       case ANALOG_SIG_SFWINK:
03341       case ANALOG_SIG_SF_FEATD:
03342       case ANALOG_SIG_FXSLS:
03343       case ANALOG_SIG_FXSGS:
03344          if (p->dialing) {
03345             ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
03346          } else {
03347             ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
03348          }
03349          break;
03350       case ANALOG_SIG_FEATDMF_TA:
03351          switch (p->whichwink) {
03352          case 0:
03353             ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2,
03354                S_COR(p->owner->caller.ani.number.valid,
03355                   p->owner->caller.ani.number.str, ""));
03356             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
03357                p->owner->caller.ani2,
03358                S_COR(p->owner->caller.ani.number.valid,
03359                   p->owner->caller.ani.number.str, ""));
03360             break;
03361          case 1:
03362             ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
03363             break;
03364          case 2:
03365             ast_log(LOG_WARNING, "Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA\n");
03366             return NULL;
03367          }
03368          p->whichwink++;
03369          /* Fall through */
03370       case ANALOG_SIG_FEATDMF:
03371       case ANALOG_SIG_E911:
03372       case ANALOG_SIG_FGC_CAMAMF:
03373       case ANALOG_SIG_FGC_CAMA:
03374       case ANALOG_SIG_FEATB:
03375       case ANALOG_SIG_SF_FEATDMF:
03376       case ANALOG_SIG_SF_FEATB:
03377       case ANALOG_SIG_EMWINK:
03378          /* FGD MF and EMWINK *Must* wait for wink */
03379          if (!ast_strlen_zero(p->dop.dialstr)) {
03380             res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
03381             if (res < 0) {
03382                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
03383                p->dop.dialstr[0] = '\0';
03384                return NULL;
03385             } else {
03386                ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
03387             }
03388          }
03389          p->dop.dialstr[0] = '\0';
03390          break;
03391       default:
03392          ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
03393       }
03394       break;
03395    case ANALOG_EVENT_HOOKCOMPLETE:
03396       if (p->inalarm) break;
03397       if (analog_check_waitingfordt(p)) {
03398          break;
03399       }
03400       switch (mysig) {
03401       case ANALOG_SIG_FXSLS:  /* only interesting for FXS */
03402       case ANALOG_SIG_FXSGS:
03403       case ANALOG_SIG_FXSKS:
03404       case ANALOG_SIG_EM:
03405       case ANALOG_SIG_EM_E1:
03406       case ANALOG_SIG_EMWINK:
03407       case ANALOG_SIG_FEATD:
03408       case ANALOG_SIG_SF:
03409       case ANALOG_SIG_SFWINK:
03410       case ANALOG_SIG_SF_FEATD:
03411          if (!ast_strlen_zero(p->dop.dialstr)) {
03412             res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
03413             if (res < 0) {
03414                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
03415                p->dop.dialstr[0] = '\0';
03416                return NULL;
03417             } else {
03418                ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
03419             }
03420          }
03421          p->dop.dialstr[0] = '\0';
03422          p->dop.op = ANALOG_DIAL_OP_REPLACE;
03423          break;
03424       case ANALOG_SIG_FEATDMF:
03425       case ANALOG_SIG_FEATDMF_TA:
03426       case ANALOG_SIG_E911:
03427       case ANALOG_SIG_FGC_CAMA:
03428       case ANALOG_SIG_FGC_CAMAMF:
03429       case ANALOG_SIG_FEATB:
03430       case ANALOG_SIG_SF_FEATDMF:
03431       case ANALOG_SIG_SF_FEATB:
03432          ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
03433          break;
03434       default:
03435          break;
03436       }
03437       break;
03438    case ANALOG_EVENT_POLARITY:
03439       /*
03440        * If we get a Polarity Switch event, this could be
03441        * due to line seizure, remote end connect or remote end disconnect.
03442        *
03443        * Check to see if we should change the polarity state and
03444        * mark the channel as UP or if this is an indication
03445        * of remote end disconnect.
03446        */
03447 
03448       if (p->polarityonanswerdelay > 0) {
03449          /* check if event is not too soon after OffHook or Answer */
03450          if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
03451             switch (ast->_state) {
03452             case AST_STATE_DIALING:       /*!< Digits (or equivalent) have been dialed */
03453             case AST_STATE_RINGING:       /*!< Remote end is ringing */
03454                if (p->answeronpolarityswitch) {
03455                   ast_debug(1, "Answering on polarity switch! channel %d\n", p->channel);
03456                   ast_setstate(p->owner, AST_STATE_UP);
03457                   p->polarity = POLARITY_REV;
03458                   if (p->hanguponpolarityswitch) {
03459                      p->polaritydelaytv = ast_tvnow();
03460                   }
03461                } else {
03462                   ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel);
03463                }
03464                break;
03465 
03466             case AST_STATE_UP:            /*!< Line is up */
03467             case AST_STATE_RING:       /*!< Line is ringing */
03468                if (p->hanguponpolarityswitch) {
03469                   ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel);
03470                   ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
03471                   p->polarity = POLARITY_IDLE;
03472                } else {
03473                   ast_debug(1, "Ignore Hangup on polarity switch, channel %d\n", p->channel);
03474                }
03475                break;
03476 
03477             case AST_STATE_DOWN:          /*!< Channel is down and available */
03478             case AST_STATE_RESERVED:         /*!< Channel is down, but reserved */
03479             case AST_STATE_OFFHOOK:          /*!< Channel is off hook */
03480             case AST_STATE_BUSY:          /*!< Line is busy */
03481             case AST_STATE_DIALING_OFFHOOK:     /*!< Digits (or equivalent) have been dialed while offhook */
03482             case AST_STATE_PRERING:          /*!< Channel has detected an incoming call and is waiting for ring */
03483             default:
03484                if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
03485                   ast_debug(1, "Ignoring Polarity switch on channel %d, state %d\n", p->channel, ast->_state);
03486                }
03487                break;
03488             }
03489 
03490          } else {
03491             /* event is too soon after OffHook or Answer */
03492             switch (ast->_state) {
03493             case AST_STATE_DIALING:    /*!< Digits (or equivalent) have been dialed */
03494             case AST_STATE_RINGING:    /*!< Remote end is ringing */
03495                if (p->answeronpolarityswitch) {
03496                   ast_debug(1, "Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %d\n", p->channel, ast->_state);
03497                }
03498                break;
03499 
03500             case AST_STATE_UP:         /*!< Line is up */
03501             case AST_STATE_RING:    /*!< Line is ringing */
03502                if (p->hanguponpolarityswitch) {
03503                   ast_debug(1, "Polarity switch detected but NOT hanging up (too close to Answer event) on channel %d, state %d\n", p->channel, ast->_state);
03504                }
03505                break;
03506 
03507             default:
03508                if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
03509                   ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %d\n", p->channel, ast->_state);
03510                }
03511                break;
03512             }
03513          }
03514       }
03515 
03516       /* Added more log_debug information below to provide a better indication of what is going on */
03517       ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
03518       break;
03519    default:
03520       ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
03521    }
03522    return &p->subs[idx].f;
03523 }

static void* __analog_ss_thread ( void *  data  )  [static]

Definition at line 1746 of file sig_analog.c.

References ast_channel::_state, analog_alloc_sub(), analog_canmatch_featurecode(), ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, ANALOG_CID_START_RING, analog_decrease_ss_count(), ANALOG_DIGITMODE_DTMF, ANALOG_DIGITMODE_MF, analog_distinctive_ring(), analog_dnd(), analog_dsp_reset_and_flush_digits(), analog_dsp_set_digitmode(), ANALOG_EVENT_NOALARM, ANALOG_EVENT_NONE, ANALOG_EVENT_POLARITY, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGOFFHOOK, analog_firstdigittimeout, analog_flash(), analog_gendigittimeout, analog_get_bridged_channel(), analog_get_callerid(), analog_get_index, analog_handle_notify_message(), analog_increase_ss_count(), analog_matchdigittimeout, ANALOG_MAX_CID, analog_my_getsigstr(), ANALOG_NEED_MFDETECT, analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_alarm(), analog_set_callwaiting(), analog_set_echocanceller(), analog_set_linear_mode(), analog_set_new_owner(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_sigtype_to_str(), ANALOG_SMDI_MD_WAIT_TIMEOUT, analog_start_cid_detect(), analog_stop_cid_detect(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_INFO, analog_unalloc_sub(), analog_wait_event(), analog_wink(), ARRAY_LEN, ast_bridged_channel(), ast_canmatch_extension(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_copy_string(), ast_db_put(), ast_debug, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), ast_log(), ast_masq_park_call_exten(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext_valid(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_remaining_ms(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_destroy(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), ASTOBJ_UNREF, analog_pvt::call_forward, ast_channel::caller, callerid_free(), callerid_get_dtmf(), ast_smdi_md_message::calling_st, analog_pvt::callreturn, analog_pvt::callwaiting, analog_pvt::cancallforward, analog_pvt::canpark, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, analog_pvt::cid_signalling, analog_pvt::cid_start, ast_channel::context, analog_dialoperation::dialstr, analog_pvt::dop, errno, ast_channel::exten, exten, f, callerid_state::flags, ast_frame::frametype, ast_smdi_md_message::fwd_st, analog_pvt::hanguponpolarityswitch, analog_pvt::hidecallerid, ast_party_caller::id, analog_pvt::immediate, ast_frame_subclass::integer, ISTRUNK, analog_pvt::lastcid_num, len(), LOG_WARNING, ast_party_id::name, name, ast_party_id::number, analog_subchannel::owner, pbx_builtin_setvar_helper(), analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, RING_PATTERNS, ast_channel::rings, analog_pvt::ringt, analog_pvt::ringt_base, analog_pvt::sig, analog_pvt::smdi_iface, analog_pvt::ss_astchan, ast_party_number::str, ast_frame::subclass, analog_pvt::subs, ast_channel::tech_pvt, analog_pvt::transfer, ast_smdi_md_message::type, analog_pvt::use_callerid, analog_pvt::use_smdi, and ast_party_number::valid.

Referenced by __analog_handle_event(), analog_handle_init_event(), and analog_ss_thread_start().

01747 {
01748    struct analog_pvt *p = data;
01749    struct ast_channel *chan = p->ss_astchan;
01750    char exten[AST_MAX_EXTENSION] = "";
01751    char exten2[AST_MAX_EXTENSION] = "";
01752    char dtmfcid[300];
01753    char dtmfbuf[300];
01754    char namebuf[ANALOG_MAX_CID];
01755    char numbuf[ANALOG_MAX_CID];
01756    struct callerid_state *cs = NULL;
01757    char *name = NULL, *number = NULL;
01758    int flags = 0;
01759    struct ast_smdi_md_message *smdi_msg = NULL;
01760    int timeout;
01761    int getforward = 0;
01762    char *s1, *s2;
01763    int len = 0;
01764    int res;
01765    int idx;
01766 
01767    analog_increase_ss_count(p);
01768 
01769    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
01770 
01771    if (!chan) {
01772       /* What happened to the channel? */
01773       goto quit;
01774    }
01775    /* in the bizarre case where the channel has become a zombie before we
01776       even get started here, abort safely
01777    */
01778    if (!chan->tech_pvt) {
01779       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
01780       ast_hangup(chan);
01781       goto quit;
01782    }
01783 
01784    ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
01785    idx = analog_get_index(chan, p, 0);
01786    if (idx < 0) {
01787       ast_hangup(chan);
01788       goto quit;
01789    }
01790    analog_dsp_reset_and_flush_digits(p);
01791    switch (p->sig) {
01792    case ANALOG_SIG_FEATD:
01793    case ANALOG_SIG_FEATDMF:
01794    case ANALOG_SIG_FEATDMF_TA:
01795    case ANALOG_SIG_E911:
01796    case ANALOG_SIG_FGC_CAMAMF:
01797    case ANALOG_SIG_FEATB:
01798    case ANALOG_SIG_EMWINK:
01799    case ANALOG_SIG_SF_FEATD:
01800    case ANALOG_SIG_SF_FEATDMF:
01801    case ANALOG_SIG_SF_FEATB:
01802    case ANALOG_SIG_SFWINK:
01803       if (analog_wink(p, idx))
01804          goto quit;
01805       /* Fall through */
01806    case ANALOG_SIG_EM:
01807    case ANALOG_SIG_EM_E1:
01808    case ANALOG_SIG_SF:
01809    case ANALOG_SIG_FGC_CAMA:
01810       res = analog_play_tone(p, idx, -1);
01811 
01812       analog_dsp_reset_and_flush_digits(p);
01813 
01814       /* set digit mode appropriately */
01815       if (ANALOG_NEED_MFDETECT(p)) {
01816          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);
01817       } else {
01818          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01819       }
01820 
01821       memset(dtmfbuf, 0, sizeof(dtmfbuf));
01822       /* Wait for the first digit only if immediate=no */
01823       if (!p->immediate) {
01824          /* Wait for the first digit (up to 5 seconds). */
01825          res = ast_waitfordigit(chan, 5000);
01826       } else {
01827          res = 0;
01828       }
01829       if (res > 0) {
01830          /* save first char */
01831          dtmfbuf[0] = res;
01832          switch (p->sig) {
01833          case ANALOG_SIG_FEATD:
01834          case ANALOG_SIG_SF_FEATD:
01835             res = analog_my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
01836             if (res > 0) {
01837                res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
01838             }
01839             if (res < 1) {
01840                analog_dsp_reset_and_flush_digits(p);
01841             }
01842             break;
01843          case ANALOG_SIG_FEATDMF_TA:
01844             res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01845             if (res < 1) {
01846                analog_dsp_reset_and_flush_digits(p);
01847             }
01848             if (analog_wink(p, idx)) {
01849                goto quit;
01850             }
01851             dtmfbuf[0] = 0;
01852             /* Wait for the first digit (up to 5 seconds). */
01853             res = ast_waitfordigit(chan, 5000);
01854             if (res <= 0) {
01855                break;
01856             }
01857             dtmfbuf[0] = res;
01858             /* fall through intentionally */
01859          case ANALOG_SIG_FEATDMF:
01860          case ANALOG_SIG_E911:
01861          case ANALOG_SIG_FGC_CAMAMF:
01862          case ANALOG_SIG_SF_FEATDMF:
01863             res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01864             /* if international caca, do it again to get real ANO */
01865             if ((p->sig == ANALOG_SIG_FEATDMF) && (dtmfbuf[1] != '0') 
01866                && (strlen(dtmfbuf) != 14)) {
01867                if (analog_wink(p, idx)) {
01868                   goto quit;
01869                }
01870                dtmfbuf[0] = 0;
01871                /* Wait for the first digit (up to 5 seconds). */
01872                res = ast_waitfordigit(chan, 5000);
01873                if (res <= 0) {
01874                   break;
01875                }
01876                dtmfbuf[0] = res;
01877                res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01878             }
01879             if (res > 0) {
01880                /* if E911, take off hook */
01881                if (p->sig == ANALOG_SIG_E911) {
01882                   analog_off_hook(p);
01883                }
01884                res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
01885             }
01886             if (res < 1) {
01887                analog_dsp_reset_and_flush_digits(p);
01888             }
01889             break;
01890          case ANALOG_SIG_FEATB:
01891          case ANALOG_SIG_SF_FEATB:
01892             res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01893             if (res < 1) {
01894                analog_dsp_reset_and_flush_digits(p);
01895             }
01896             break;
01897          case ANALOG_SIG_EMWINK:
01898             /* if we received a '*', we are actually receiving Feature Group D
01899                dial syntax, so use that mode; otherwise, fall through to normal
01900                mode
01901             */
01902             if (res == '*') {
01903                res = analog_my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
01904                if (res > 0) {
01905                   res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
01906                }
01907                if (res < 1) {
01908                   analog_dsp_reset_and_flush_digits(p);
01909                }
01910                break;
01911             }
01912          default:
01913             /* If we got the first digit, get the rest */
01914             len = 1;
01915             dtmfbuf[len] = '\0';
01916             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
01917                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
01918                   timeout = analog_matchdigittimeout;
01919                } else {
01920                   timeout = analog_gendigittimeout;
01921                }
01922                res = ast_waitfordigit(chan, timeout);
01923                if (res < 0) {
01924                   ast_debug(1, "waitfordigit returned < 0...\n");
01925                   ast_hangup(chan);
01926                   goto quit;
01927                } else if (res) {
01928                   dtmfbuf[len++] = res;
01929                   dtmfbuf[len] = '\0';
01930                } else {
01931                   break;
01932                }
01933             }
01934             break;
01935          }
01936       }
01937       if (res == -1) {
01938          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
01939          ast_hangup(chan);
01940          goto quit;
01941       } else if (res < 0) {
01942          ast_debug(1, "Got hung up before digits finished\n");
01943          ast_hangup(chan);
01944          goto quit;
01945       }
01946 
01947       if (p->sig == ANALOG_SIG_FGC_CAMA) {
01948          char anibuf[100];
01949 
01950          if (ast_safe_sleep(chan,1000) == -1) {
01951             ast_hangup(chan);
01952             goto quit;
01953          }
01954          analog_off_hook(p);
01955          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);
01956          res = analog_my_getsigstr(chan, anibuf, "#", 10000);
01957          if ((res > 0) && (strlen(anibuf) > 2)) {
01958             if (anibuf[strlen(anibuf) - 1] == '#') {
01959                anibuf[strlen(anibuf) - 1] = 0;
01960             }
01961             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
01962          }
01963          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01964       }
01965 
01966       ast_copy_string(exten, dtmfbuf, sizeof(exten));
01967       if (ast_strlen_zero(exten)) {
01968          ast_copy_string(exten, "s", sizeof(exten));
01969       }
01970       if (p->sig == ANALOG_SIG_FEATD || p->sig == ANALOG_SIG_EMWINK) {
01971          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
01972          if (exten[0] == '*') {
01973             char *stringp=NULL;
01974             ast_copy_string(exten2, exten, sizeof(exten2));
01975             /* Parse out extension and callerid */
01976             stringp=exten2 +1;
01977             s1 = strsep(&stringp, "*");
01978             s2 = strsep(&stringp, "*");
01979             if (s2) {
01980                if (!ast_strlen_zero(p->cid_num)) {
01981                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
01982                } else {
01983                   ast_set_callerid(chan, s1, NULL, s1);
01984                }
01985                ast_copy_string(exten, s2, sizeof(exten));
01986             } else {
01987                ast_copy_string(exten, s1, sizeof(exten));
01988             }
01989          } else if (p->sig == ANALOG_SIG_FEATD) {
01990             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
01991          }
01992       }
01993       if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {
01994          if (exten[0] == '*') {
01995             char *stringp=NULL;
01996             ast_copy_string(exten2, exten, sizeof(exten2));
01997             /* Parse out extension and callerid */
01998             stringp=exten2 +1;
01999             s1 = strsep(&stringp, "#");
02000             s2 = strsep(&stringp, "#");
02001             if (s2) {
02002                if (!ast_strlen_zero(p->cid_num)) {
02003                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
02004                } else {
02005                   if (*(s1 + 2)) {
02006                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
02007                   }
02008                }
02009                ast_copy_string(exten, s2 + 1, sizeof(exten));
02010             } else {
02011                ast_copy_string(exten, s1 + 2, sizeof(exten));
02012             }
02013          } else {
02014             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
02015          }
02016       }
02017       if ((p->sig == ANALOG_SIG_E911) || (p->sig == ANALOG_SIG_FGC_CAMAMF)) {
02018          if (exten[0] == '*') {
02019             char *stringp=NULL;
02020             ast_copy_string(exten2, exten, sizeof(exten2));
02021             /* Parse out extension and callerid */
02022             stringp=exten2 +1;
02023             s1 = strsep(&stringp, "#");
02024             s2 = strsep(&stringp, "#");
02025             if (s2 && (*(s2 + 1) == '0')) {
02026                if (*(s2 + 2)) {
02027                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
02028                }
02029             }
02030             if (s1) {
02031                ast_copy_string(exten, s1, sizeof(exten));
02032             } else {
02033                ast_copy_string(exten, "911", sizeof(exten));
02034             }
02035          } else {
02036             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
02037          }
02038       }
02039       if (p->sig == ANALOG_SIG_FEATB) {
02040          if (exten[0] == '*') {
02041             char *stringp=NULL;
02042             ast_copy_string(exten2, exten, sizeof(exten2));
02043             /* Parse out extension and callerid */
02044             stringp=exten2 +1;
02045             s1 = strsep(&stringp, "#");
02046             ast_copy_string(exten, exten2 + 1, sizeof(exten));
02047          } else {
02048             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
02049          }
02050       }
02051       if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {
02052          analog_wink(p, idx);
02053          /*
02054           * Some switches require a minimum guard time between the last
02055           * FGD wink and something that answers immediately.  This
02056           * ensures it.
02057           */
02058          if (ast_safe_sleep(chan, 100)) {
02059             ast_hangup(chan);
02060             goto quit;
02061          }
02062       }
02063       analog_set_echocanceller(p, 1);
02064 
02065       analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
02066 
02067       if (ast_exists_extension(chan, chan->context, exten, 1,
02068          chan->caller.id.number.valid ? chan->caller.id.number.str : NULL)) {
02069          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
02070          analog_dsp_reset_and_flush_digits(p);
02071          res = ast_pbx_run(chan);
02072          if (res) {
02073             ast_log(LOG_WARNING, "PBX exited non-zero\n");
02074             res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02075          }
02076          goto quit;
02077       } else {
02078          ast_verb(3, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
02079          sleep(2);
02080          res = analog_play_tone(p, idx, ANALOG_TONE_INFO);
02081          if (res < 0) {
02082             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
02083          } else {
02084             sleep(1);
02085          }
02086          res = ast_streamfile(chan, "ss-noservice", chan->language);
02087          if (res >= 0) {
02088             ast_waitstream(chan, "");
02089          }
02090          res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02091          ast_hangup(chan);
02092          goto quit;
02093       }
02094       break;
02095    case ANALOG_SIG_FXOLS:
02096    case ANALOG_SIG_FXOGS:
02097    case ANALOG_SIG_FXOKS:
02098       /* Read the first digit */
02099       timeout = analog_firstdigittimeout;
02100       /* If starting a threeway call, never timeout on the first digit so someone
02101          can use flash-hook as a "hold" feature */
02102       if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02103          timeout = 999999;
02104       }
02105       while (len < AST_MAX_EXTENSION-1) {
02106          /* Read digit unless it's supposed to be immediate, in which case the
02107             only answer is 's' */
02108          if (p->immediate) {
02109             res = 's';
02110          } else {
02111             res = ast_waitfordigit(chan, timeout);
02112          }
02113          timeout = 0;
02114          if (res < 0) {
02115             ast_debug(1, "waitfordigit returned < 0...\n");
02116             res = analog_play_tone(p, idx, -1);
02117             ast_hangup(chan);
02118             goto quit;
02119          } else if (res) {
02120             ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
02121             exten[len++]=res;
02122             exten[len] = '\0';
02123          }
02124          if (!ast_ignore_pattern(chan->context, exten)) {
02125             analog_play_tone(p, idx, -1);
02126          } else {
02127             analog_play_tone(p, idx, ANALOG_TONE_DIALTONE);
02128          }
02129          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, chan->context)) {
02130             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
02131                if (getforward) {
02132                   /* Record this as the forwarding extension */
02133                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
02134                   ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
02135                   res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02136                   if (res) {
02137                      break;
02138                   }
02139                   usleep(500000);
02140                   res = analog_play_tone(p, idx, -1);
02141                   sleep(1);
02142                   memset(exten, 0, sizeof(exten));
02143                   res = analog_play_tone(p, idx, ANALOG_TONE_DIALTONE);
02144                   len = 0;
02145                   getforward = 0;
02146                } else {
02147                   res = analog_play_tone(p, idx, -1);
02148                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
02149                   if (!ast_strlen_zero(p->cid_num)) {
02150                      if (!p->hidecallerid) {
02151                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
02152                      } else {
02153                         ast_set_callerid(chan, NULL, NULL, p->cid_num);
02154                      }
02155                   }
02156                   if (!ast_strlen_zero(p->cid_name)) {
02157                      if (!p->hidecallerid) {
02158                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
02159                      }
02160                   }
02161                   ast_setstate(chan, AST_STATE_RING);
02162                   analog_set_echocanceller(p, 1);
02163                   res = ast_pbx_run(chan);
02164                   if (res) {
02165                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
02166                      res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02167                   }
02168                   goto quit;
02169                }
02170             } else {
02171                /* It's a match, but they just typed a digit, and there is an ambiguous match,
02172                   so just set the timeout to analog_matchdigittimeout and wait some more */
02173                timeout = analog_matchdigittimeout;
02174             }
02175          } else if (res == 0) {
02176             ast_debug(1, "not enough digits (and no ambiguous match)...\n");
02177             res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02178             analog_wait_event(p);
02179             ast_hangup(chan);
02180             goto quit;
02181          } else if (p->callwaiting && !strcmp(exten, "*70")) {
02182             ast_verb(3, "Disabling call waiting on %s\n", chan->name);
02183             /* Disable call waiting if enabled */
02184             analog_set_callwaiting(p, 0);
02185             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02186             if (res) {
02187                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
02188                   chan->name, strerror(errno));
02189             }
02190             len = 0;
02191             memset(exten, 0, sizeof(exten));
02192             timeout = analog_firstdigittimeout;
02193 
02194          } else if (!strcmp(exten,ast_pickup_ext())) {
02195             /* Scan all channels and see if there are any
02196              * ringing channels that have call groups
02197              * that equal this channels pickup group
02198              */
02199             if (idx == ANALOG_SUB_REAL) {
02200                /* Switch us from Third call to Call Wait */
02201                if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02202                   /* If you make a threeway call and the *8# a call, it should actually
02203                      look like a callwait */
02204                   analog_alloc_sub(p, ANALOG_SUB_CALLWAIT);
02205                   analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY);
02206                   analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
02207                }
02208                analog_set_echocanceller(p, 1);
02209                if (ast_pickup_call(chan)) {
02210                   ast_debug(1, "No call pickup possible...\n");
02211                   res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02212                   analog_wait_event(p);
02213                }
02214                ast_hangup(chan);
02215                goto quit;
02216             } else {
02217                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
02218                ast_hangup(chan);
02219                goto quit;
02220             }
02221 
02222          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
02223             ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
02224             /* Disable Caller*ID if enabled */
02225             p->hidecallerid = 1;
02226             ast_party_number_free(&chan->caller.id.number);
02227             ast_party_number_init(&chan->caller.id.number);
02228             ast_party_name_free(&chan->caller.id.name);
02229             ast_party_name_init(&chan->caller.id.name);
02230             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02231             if (res) {
02232                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
02233                   chan->name, strerror(errno));
02234             }
02235             len = 0;
02236             memset(exten, 0, sizeof(exten));
02237             timeout = analog_firstdigittimeout;
02238          } else if (p->callreturn && !strcmp(exten, "*69")) {
02239             res = 0;
02240             if (!ast_strlen_zero(p->lastcid_num)) {
02241                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
02242             }
02243             if (!res) {
02244                res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02245             }
02246             break;
02247          } else if (!strcmp(exten, "*78")) {
02248             /* Do not disturb enabled */
02249             analog_dnd(p, 1);
02250             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02251             getforward = 0;
02252             memset(exten, 0, sizeof(exten));
02253             len = 0;
02254          } else if (!strcmp(exten, "*79")) {
02255             /* Do not disturb disabled */
02256             analog_dnd(p, 0);
02257             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02258             getforward = 0;
02259             memset(exten, 0, sizeof(exten));
02260             len = 0;
02261          } else if (p->cancallforward && !strcmp(exten, "*72")) {
02262             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02263             getforward = 1;
02264             memset(exten, 0, sizeof(exten));
02265             len = 0;
02266          } else if (p->cancallforward && !strcmp(exten, "*73")) {
02267             ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
02268             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02269             memset(p->call_forward, 0, sizeof(p->call_forward));
02270             getforward = 0;
02271             memset(exten, 0, sizeof(exten));
02272             len = 0;
02273          } else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, chan->context) &&
02274                   p->subs[ANALOG_SUB_THREEWAY].owner &&
02275                   ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
02276             /* This is a three way call, the main call being a real channel,
02277                and we're parking the first call. */
02278             ast_masq_park_call_exten(
02279                ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner), chan, exten,
02280                chan->context, 0, NULL);
02281             ast_verb(3, "Parking call to '%s'\n", chan->name);
02282             break;
02283          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
02284             ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);
02285             res = ast_db_put("blacklist", p->lastcid_num, "1");
02286             if (!res) {
02287                res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02288                memset(exten, 0, sizeof(exten));
02289                len = 0;
02290             }
02291          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
02292             ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
02293             /* Enable Caller*ID if enabled */
02294             p->hidecallerid = 0;
02295             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
02296             res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
02297             if (res) {
02298                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
02299                   chan->name, strerror(errno));
02300             }
02301             len = 0;
02302             memset(exten, 0, sizeof(exten));
02303             timeout = analog_firstdigittimeout;
02304          } else if (!strcmp(exten, "*0")) {
02305             struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;
02306             struct analog_pvt *pbridge = NULL;
02307             /* set up the private struct of the bridged one, if any */
02308             if (nbridge) {
02309                pbridge = analog_get_bridged_channel(p, nbridge);
02310             }
02311             if (pbridge && ISTRUNK(pbridge)) {
02312                /* Clear out the dial buffer */
02313                p->dop.dialstr[0] = '\0';
02314                /* flash hookswitch */
02315                if ((analog_flash(pbridge) == -1) && (errno != EINPROGRESS)) {
02316                   ast_log(LOG_WARNING,
02317                      "Unable to flash-hook bridged trunk from channel %s: %s\n",
02318                      nbridge->name, strerror(errno));
02319                }
02320                analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
02321                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
02322                analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
02323                if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
02324                   ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
02325                }
02326                ast_hangup(chan);
02327                goto quit;
02328             } else {
02329                analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02330                analog_wait_event(p);
02331                analog_play_tone(p, idx, -1);
02332                analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
02333                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
02334                analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
02335                ast_hangup(chan);
02336                goto quit;
02337             }
02338          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1,
02339             chan->caller.id.number.valid ? chan->caller.id.number.str : NULL)
02340             && !analog_canmatch_featurecode(exten)) {
02341             ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
02342                chan->caller.id.number.valid && chan->caller.id.number.str
02343                   ? chan->caller.id.number.str : "<Unknown Caller>",
02344                chan->context);
02345             break;
02346          }
02347          if (!timeout) {
02348             timeout = analog_gendigittimeout;
02349          }
02350          if (len && !ast_ignore_pattern(chan->context, exten)) {
02351             analog_play_tone(p, idx, -1);
02352          }
02353       }
02354       break;
02355    case ANALOG_SIG_FXSLS:
02356    case ANALOG_SIG_FXSGS:
02357    case ANALOG_SIG_FXSKS:
02358       /* check for SMDI messages */
02359       if (p->use_smdi && p->smdi_iface) {
02360          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, ANALOG_SMDI_MD_WAIT_TIMEOUT);
02361          if (smdi_msg != NULL) {
02362             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
02363 
02364             if (smdi_msg->type == 'B')
02365                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
02366             else if (smdi_msg->type == 'N')
02367                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
02368 
02369             ast_debug(1, "Received SMDI message on %s\n", chan->name);
02370          } else {
02371             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
02372          }
02373       }
02374 
02375       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
02376          number = smdi_msg->calling_st;
02377 
02378       /* If we want caller id, we're in a prering state due to a polarity reversal
02379        * and we're set to use a polarity reversal to trigger the start of caller id,
02380        * grab the caller id and wait for ringing to start... */
02381       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING
02382          && (p->cid_start == ANALOG_CID_START_POLARITY
02383             || p->cid_start == ANALOG_CID_START_POLARITY_IN
02384             || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) {
02385          /* If set to use DTMF CID signalling, listen for DTMF */
02386          if (p->cid_signalling == CID_SIG_DTMF) {
02387             int k = 0;
02388             int oldlinearity; 
02389             int timeout_ms;
02390             int ms;
02391             struct timeval start = ast_tvnow();
02392             cs = NULL;
02393             ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name);
02394 
02395             oldlinearity = analog_set_linear_mode(p, idx, 0);
02396 
02397             /*
02398              * We are the only party interested in the Rx stream since
02399              * we have not answered yet.  We don't need or even want DTMF
02400              * emulation.  The DTMF digits can come so fast that emulation
02401              * can drop some of them.
02402              */
02403             ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
02404             timeout_ms = 4000;/* This is a typical OFF time between rings. */
02405             for (;;) {
02406                struct ast_frame *f;
02407 
02408                ms = ast_remaining_ms(start, timeout_ms);
02409                res = ast_waitfor(chan, ms);
02410                if (res <= 0) {
02411                   /*
02412                    * We do not need to restore the analog_set_linear_mode()
02413                    * or AST_FLAG_END_DTMF_ONLY flag settings since we
02414                    * are hanging up the channel.
02415                    */
02416                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
02417                      "Exiting simple switch\n");
02418                   ast_hangup(chan);
02419                   goto quit;
02420                }
02421                f = ast_read(chan);
02422                if (!f) {
02423                   break;
02424                }
02425                if (f->frametype == AST_FRAME_DTMF) {
02426                   if (k < ARRAY_LEN(dtmfbuf) - 1) {
02427                      dtmfbuf[k++] = f->subclass.integer;
02428                   }
02429                   ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
02430                   start = ast_tvnow();
02431                }
02432                ast_frfree(f);
02433                if (chan->_state == AST_STATE_RING ||
02434                   chan->_state == AST_STATE_RINGING) {
02435                   break; /* Got ring */
02436                }
02437             }
02438             ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
02439             dtmfbuf[k] = '\0';
02440 
02441             analog_set_linear_mode(p, idx, oldlinearity);
02442 
02443             /* Got cid and ring. */
02444             ast_debug(1, "CID got string '%s'\n", dtmfbuf);
02445             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
02446             ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
02447             /* If first byte is NULL, we have no cid */
02448             if (!ast_strlen_zero(dtmfcid)) {
02449                number = dtmfcid;
02450             } else {
02451                number = NULL;
02452             }
02453 
02454          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
02455          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
02456             int timeout = 10000;  /* Ten seconds */
02457             struct timeval start = ast_tvnow();
02458             enum analog_event ev;
02459 
02460             namebuf[0] = 0;
02461             numbuf[0] = 0;
02462 
02463             if (!analog_start_cid_detect(p, p->cid_signalling)) {
02464                int off_ms;
02465                int ms;
02466                struct timeval off_start;
02467                while (1) {
02468                   res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start));
02469 
02470                   if (res == 0) {
02471                      break;
02472                   }
02473 
02474                   if (res == 1) {
02475                      if (ev == ANALOG_EVENT_NOALARM) {
02476                         analog_set_alarm(p, 0);
02477                      }
02478                      if (p->cid_signalling == CID_SIG_V23_JP) {
02479                         if (ev == ANALOG_EVENT_RINGBEGIN) {
02480                            analog_off_hook(p);
02481                            usleep(1);
02482                         }
02483                      } else {
02484                         ev = ANALOG_EVENT_NONE;
02485                         break;
02486                      }
02487                   }
02488 
02489                   if (ast_tvdiff_ms(ast_tvnow(), start) > timeout)
02490                      break;
02491 
02492                }
02493                name = namebuf;
02494                number = numbuf;
02495 
02496                analog_stop_cid_detect(p);
02497 
02498                if (p->cid_signalling == CID_SIG_V23_JP) {
02499                   res = analog_on_hook(p);
02500                   usleep(1);
02501                }
02502 
02503                /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
02504                off_start = ast_tvnow();
02505                off_ms = 4000;/* This is a typical OFF time between rings. */
02506                while ((ms = ast_remaining_ms(off_start, off_ms))) {
02507                   struct ast_frame *f;
02508 
02509                   res = ast_waitfor(chan, ms);
02510                   if (res <= 0) {
02511                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
02512                         "Exiting simple switch\n");
02513                      ast_hangup(chan);
02514                      goto quit;
02515                   }
02516                   if (!(f = ast_read(chan))) {
02517                      ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
02518                      ast_hangup(chan);
02519                      goto quit;
02520                   }
02521                   ast_frfree(f);
02522                   if (chan->_state == AST_STATE_RING ||
02523                      chan->_state == AST_STATE_RINGING)
02524                      break; /* Got ring */
02525                }
02526 
02527                if (analog_distinctive_ring(chan, p, idx, NULL)) {
02528                   goto quit;
02529                }
02530 
02531                if (res < 0) {
02532                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
02533                }
02534             } else {
02535                ast_log(LOG_WARNING, "Unable to get caller ID space\n");
02536             }
02537          } else {
02538             ast_log(LOG_WARNING, "Channel %s in prering "
02539                "state, but I have nothing to do. "
02540                "Terminating simple switch, should be "
02541                "restarted by the actual ring.\n",
02542                chan->name);
02543             ast_hangup(chan);
02544             goto quit;
02545          }
02546       } else if (p->use_callerid && p->cid_start == ANALOG_CID_START_RING) {
02547          int timeout = 10000;  /* Ten seconds */
02548          struct timeval start = ast_tvnow();
02549          enum analog_event ev;
02550          int curRingData[RING_PATTERNS] = { 0 };
02551          int receivedRingT = 0;
02552 
02553          namebuf[0] = 0;
02554          numbuf[0] = 0;
02555 
02556          if (!analog_start_cid_detect(p, p->cid_signalling)) {
02557             while (1) {
02558                res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start));
02559 
02560                if (res == 0) {
02561                   break;
02562                }
02563 
02564                if (res == 1 || res == 2) {
02565                   if (ev == ANALOG_EVENT_NOALARM) {
02566                      analog_set_alarm(p, 0);
02567                   } else if (ev == ANALOG_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
02568                      ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
02569                      p->polarity = POLARITY_IDLE;
02570                      ast_hangup(chan);
02571                      goto quit;
02572                   } else if (ev != ANALOG_EVENT_NONE && ev != ANALOG_EVENT_RINGBEGIN && ev != ANALOG_EVENT_RINGOFFHOOK) {
02573                      break;
02574                   }
02575                   if (res != 2) {
02576                      /* Let us detect callerid when the telco uses distinctive ring */
02577                      curRingData[receivedRingT] = p->ringt;
02578 
02579                      if (p->ringt < p->ringt_base/2) {
02580                         break;
02581                      }
02582                      /* Increment the ringT counter so we can match it against
02583                         values in chan_dahdi.conf for distinctive ring */
02584                      if (++receivedRingT == RING_PATTERNS) {
02585                         break;
02586                      }
02587                   }
02588                }
02589 
02590                if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) {
02591                   break;
02592                }
02593 
02594             }
02595             name = namebuf;
02596             number = numbuf;
02597 
02598             analog_stop_cid_detect(p);
02599 
02600             if (analog_distinctive_ring(chan, p, idx, curRingData)) {
02601                goto quit;
02602             }
02603 
02604             if (res < 0) {
02605                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
02606             }
02607          } else {
02608             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
02609          }
02610       } else {
02611          cs = NULL;
02612       }
02613 
02614       if (number) {
02615          ast_shrink_phone_number(number);
02616       }
02617       ast_set_callerid(chan, number, name, number);
02618 
02619       if (cs) {
02620          callerid_free(cs);
02621       }
02622 
02623       analog_handle_notify_message(chan, p, flags, -1);
02624 
02625       ast_setstate(chan, AST_STATE_RING);
02626       chan->rings = 1;
02627       analog_set_ringtimeout(p, p->ringt_base);
02628       res = ast_pbx_run(chan);
02629       if (res) {
02630          ast_hangup(chan);
02631          ast_log(LOG_WARNING, "PBX exited non-zero\n");
02632       }
02633       goto quit;
02634    default:
02635       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", analog_sigtype_to_str(p->sig), p->channel);
02636       break;
02637    }
02638    res = analog_play_tone(p, idx, ANALOG_TONE_CONGESTION);
02639    if (res < 0) {
02640       ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
02641    }
02642    ast_hangup(chan);
02643 quit:
02644    if (smdi_msg) {
02645       ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
02646    }
02647    analog_decrease_ss_count(p);
02648    return NULL;
02649 }

static int _analog_get_index ( struct ast_channel ast,
struct analog_pvt p,
int  nullok,
const char *  fname,
unsigned long  line 
) [static]

Definition at line 390 of file sig_analog.c.

References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_log(), analog_pvt::channel, LOG_WARNING, analog_subchannel::owner, and analog_pvt::subs.

00391 {
00392    int res;
00393    if (p->subs[ANALOG_SUB_REAL].owner == ast) {
00394       res = ANALOG_SUB_REAL;
00395    } else if (p->subs[ANALOG_SUB_CALLWAIT].owner == ast) {
00396       res = ANALOG_SUB_CALLWAIT;
00397    } else if (p->subs[ANALOG_SUB_THREEWAY].owner == ast) {
00398       res = ANALOG_SUB_THREEWAY;
00399    } else {
00400       res = -1;
00401       if (!nullok) {
00402          ast_log(LOG_WARNING,
00403             "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
00404             ast ? ast->name : "", p->channel, fname, line);
00405       }
00406    }
00407    return res;
00408 }

static void analog_all_subchannels_hungup ( struct analog_pvt p  )  [static]

Definition at line 535 of file sig_analog.c.

References analog_callback::all_subchannels_hungup, analog_pvt::calls, and analog_pvt::chan_pvt.

Referenced by analog_hangup().

00536 {
00537    if (p->calls->all_subchannels_hungup) {
00538       p->calls->all_subchannels_hungup(p->chan_pvt);
00539    }
00540 }

static int analog_alloc_sub ( struct analog_pvt p,
enum analog_sub  x 
) [static]

Definition at line 350 of file sig_analog.c.

References analog_callback::allocate_sub, analog_subchannel::allocd, analog_pvt::calls, analog_pvt::chan_pvt, and analog_pvt::subs.

Referenced by __analog_handle_event(), __analog_ss_thread(), and analog_request().

00351 {
00352    if (p->calls->allocate_sub) {
00353       int res;
00354       res = p->calls->allocate_sub(p->chan_pvt, x);
00355       if (!res) {
00356          p->subs[x].allocd = 1;
00357       }
00358       return res;
00359    }
00360    return 0;
00361 }

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1493 of file sig_analog.c.

References ast_channel::_state, analog_answer_polarityswitch(), analog_get_index, analog_off_hook(), analog_play_tone(), analog_set_dialing(), analog_set_echocanceller(), analog_set_new_owner(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), analog_train_echocanceller(), ast_debug, ast_log(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, analog_pvt::channel, analog_pvt::hanguponpolarityswitch, analog_subchannel::inthreeway, LOG_WARNING, analog_subchannel::owner, analog_pvt::polaritydelaytv, analog_pvt::sig, and analog_pvt::subs.

Referenced by dahdi_answer().

01494 {
01495    int res = 0;
01496    int idx;
01497    int oldstate = ast->_state;
01498 
01499    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
01500    ast_setstate(ast, AST_STATE_UP);
01501    idx = analog_get_index(ast, p, 1);
01502    if (idx < 0) {
01503       idx = ANALOG_SUB_REAL;
01504    }
01505    switch (p->sig) {
01506    case ANALOG_SIG_FXSLS:
01507    case ANALOG_SIG_FXSGS:
01508    case ANALOG_SIG_FXSKS:
01509       analog_set_ringtimeout(p, 0);
01510       /* Fall through */
01511    case ANALOG_SIG_EM:
01512    case ANALOG_SIG_EM_E1:
01513    case ANALOG_SIG_EMWINK:
01514    case ANALOG_SIG_FEATD:
01515    case ANALOG_SIG_FEATDMF:
01516    case ANALOG_SIG_FEATDMF_TA:
01517    case ANALOG_SIG_E911:
01518    case ANALOG_SIG_FGC_CAMA:
01519    case ANALOG_SIG_FGC_CAMAMF:
01520    case ANALOG_SIG_FEATB:
01521    case ANALOG_SIG_SF:
01522    case ANALOG_SIG_SFWINK:
01523    case ANALOG_SIG_SF_FEATD:
01524    case ANALOG_SIG_SF_FEATDMF:
01525    case ANALOG_SIG_SF_FEATB:
01526    case ANALOG_SIG_FXOLS:
01527    case ANALOG_SIG_FXOGS:
01528    case ANALOG_SIG_FXOKS:
01529       /* Pick up the line */
01530       ast_debug(1, "Took %s off hook\n", ast->name);
01531       if (p->hanguponpolarityswitch) {
01532          gettimeofday(&p->polaritydelaytv, NULL);
01533       }
01534       res = analog_off_hook(p);
01535       analog_play_tone(p, idx, -1);
01536       analog_set_dialing(p, 0);
01537       if ((idx == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
01538          if (oldstate == AST_STATE_RINGING) {
01539             ast_debug(1, "Finally swapping real and threeway\n");
01540             analog_play_tone(p, ANALOG_SUB_THREEWAY, -1);
01541             analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01542             analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
01543          }
01544       }
01545 
01546       switch (p->sig) {
01547       case ANALOG_SIG_FXSLS:
01548       case ANALOG_SIG_FXSKS:
01549       case ANALOG_SIG_FXSGS:
01550          analog_set_echocanceller(p, 1);
01551          analog_train_echocanceller(p);
01552          break;
01553       case ANALOG_SIG_FXOLS:
01554       case ANALOG_SIG_FXOKS:
01555       case ANALOG_SIG_FXOGS:
01556          analog_answer_polarityswitch(p);
01557          break;
01558       default:
01559          break;
01560       }
01561       break;
01562    default:
01563       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
01564       res = -1;
01565       break;
01566    }
01567    ast_setstate(ast, AST_STATE_UP);
01568    return res;
01569 }

static void analog_answer_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 622 of file sig_analog.c.

References analog_callback::answer_polarityswitch, analog_pvt::calls, and analog_pvt::chan_pvt.

Referenced by __analog_handle_event(), and analog_answer().

00623 {
00624    if (p->calls->answer_polarityswitch) {
00625       return p->calls->answer_polarityswitch(p->chan_pvt);
00626    }
00627 }

static int analog_attempt_transfer ( struct analog_pvt p,
int  inthreeway 
) [static]

Definition at line 690 of file sig_analog.c.

References ast_channel::_state, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), analog_unalloc_sub(), ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_transfer_masquerade(), ast_channel_unlock, ast_debug, ast_log(), AST_STATE_RINGING, ast_verb, ast_channel::connected, LOG_WARNING, analog_subchannel::owner, and analog_pvt::subs.

Referenced by __analog_handle_event().

00691 {
00692    struct ast_channel *owner_real;
00693    struct ast_channel *owner_3way;
00694    struct ast_channel *bridge_real;
00695    struct ast_channel *bridge_3way;
00696 
00697    owner_real = p->subs[ANALOG_SUB_REAL].owner;
00698    owner_3way = p->subs[ANALOG_SUB_THREEWAY].owner;
00699    bridge_real = ast_bridged_channel(owner_real);
00700    bridge_3way = ast_bridged_channel(owner_3way);
00701 
00702    /*
00703     * In order to transfer, we need at least one of the channels to
00704     * actually be in a call bridge.  We can't conference two
00705     * applications together.  Why would we want to?
00706     */
00707    if (bridge_3way) {
00708       ast_verb(3, "TRANSFERRING %s to %s\n", owner_3way->name, owner_real->name);
00709       ast_cel_report_event(owner_3way,
00710          (owner_real->_state == AST_STATE_RINGING
00711             || owner_3way->_state == AST_STATE_RINGING)
00712             ? AST_CEL_BLINDTRANSFER : AST_CEL_ATTENDEDTRANSFER,
00713          NULL, owner_3way->linkedid, NULL);
00714 
00715       /*
00716        * The three-way party we're about to transfer is on hold if he
00717        * is not in a three way conference.
00718        */
00719       if (ast_channel_transfer_masquerade(owner_real, &owner_real->connected, 0,
00720          bridge_3way, &owner_3way->connected, !inthreeway)) {
00721          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
00722             bridge_3way->name, owner_real->name);
00723          return -1;
00724       }
00725 
00726       /* Three-way is now the REAL */
00727       analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
00728       ast_channel_unlock(owner_3way);
00729       analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
00730       /* Tell the caller not to hangup */
00731       return 1;
00732    } else if (bridge_real) {
00733       /* Try transferring the other way. */
00734       ast_verb(3, "TRANSFERRING %s to %s\n", owner_real->name, owner_3way->name);
00735       ast_cel_report_event(owner_3way,
00736          (owner_real->_state == AST_STATE_RINGING
00737             || owner_3way->_state == AST_STATE_RINGING)
00738             ? AST_CEL_BLINDTRANSFER : AST_CEL_ATTENDEDTRANSFER,
00739          NULL, owner_3way->linkedid, NULL);
00740 
00741       /*
00742        * The three-way party we're about to transfer is on hold if he
00743        * is not in a three way conference.
00744        */
00745       if (ast_channel_transfer_masquerade(owner_3way, &owner_3way->connected,
00746          !inthreeway, bridge_real, &owner_real->connected, 0)) {
00747          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
00748             bridge_real->name, owner_3way->name);
00749          return -1;
00750       }
00751 
00752       /* Orphan the channel after releasing the lock */
00753       ast_channel_unlock(owner_3way);
00754       analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
00755       return 0;
00756    } else {
00757       ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
00758          owner_real->name, owner_3way->name);
00759       return -1;
00760    }
00761 }

int analog_available ( struct analog_pvt p  ) 

Definition at line 813 of file sig_analog.c.

References ast_channel::_state, analog_subchannel::allocd, analog_is_off_hook(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY, ast_debug, AST_STATE_RINGING, AST_STATE_UP, analog_pvt::callwaiting, analog_pvt::channel, analog_pvt::dnd, analog_pvt::guardtime, analog_subchannel::inthreeway, analog_pvt::outgoing, analog_subchannel::owner, analog_pvt::owner, analog_pvt::sig, and analog_pvt::subs.

Referenced by available().

00814 {
00815    int offhook;
00816 
00817    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
00818 
00819    /* If do not disturb, definitely not */
00820    if (p->dnd) {
00821       return 0;
00822    }
00823    /* If guard time, definitely not */
00824    if (p->guardtime && (time(NULL) < p->guardtime)) {
00825       return 0;
00826    }
00827 
00828    /* If no owner definitely available */
00829    if (!p->owner) {
00830       offhook = analog_is_off_hook(p);
00831 
00832       /* TDM FXO card, "onhook" means out of service (no battery on the line) */
00833       if ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || (p->sig == ANALOG_SIG_FXSGS)) {
00834 #ifdef DAHDI_CHECK_HOOKSTATE
00835          if (offhook) {
00836             return 1;
00837          }
00838          return 0;
00839 #endif
00840       /* TDM FXS card, "offhook" means someone took the hook off so it's unavailable! */
00841       } else if (offhook) {
00842          ast_debug(1, "Channel %d off hook, can't use\n", p->channel);
00843          /* Not available when the other end is off hook */
00844          return 0;
00845       }
00846       return 1;
00847    }
00848 
00849    /* If it's not an FXO, forget about call wait */
00850    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
00851       return 0;
00852    }
00853 
00854    if (!p->callwaiting) {
00855       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
00856       return 0;
00857    }
00858 
00859    if (p->subs[ANALOG_SUB_CALLWAIT].allocd) {
00860       /* If there is already a call waiting call, then we can't take a second one */
00861       return 0;
00862    }
00863 
00864    if ((p->owner->_state != AST_STATE_UP) &&
00865        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
00866       /* If the current call is not up, then don't allow the call */
00867       return 0;
00868    }
00869    if ((p->subs[ANALOG_SUB_THREEWAY].owner) && (!p->subs[ANALOG_SUB_THREEWAY].inthreeway)) {
00870       /* Can't take a call wait when the three way calling hasn't been merged yet. */
00871       return 0;
00872    }
00873    /* We're cool */
00874    return 1;
00875 }

int analog_call ( struct analog_pvt p,
struct ast_channel ast,
char *  rdest,
int  timeout 
)

Definition at line 1010 of file sig_analog.c.

References ast_channel::_state, analog_callwait(), analog_defaultcic, analog_defaultozz, analog_dial_digits(), ANALOG_DIAL_OP_REPLACE, analog_get_index, analog_get_orig_dialstring(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_set_cadence(), analog_set_dialing(), analog_set_outgoing(), analog_set_waitingfordt(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_start(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE, analog_pvt::answeronpolarityswitch, AST_CC_CCNR, AST_CC_GENERIC_MONITOR_TYPE, AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_cc_config_params(), AST_CONTROL_BUSY, AST_CONTROL_RINGING, ast_copy_string(), ast_debug, ast_get_cc_monitor_policy(), ast_log(), ast_queue_cc_frame(), ast_queue_control(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_tvnow(), analog_pvt::caller, analog_pvt::callwait_name, analog_pvt::callwait_num, analog_pvt::channel, ast_channel::connected, analog_pvt::dialdest, analog_pvt::dialednone, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, analog_pvt::finaldial, analog_pvt::hanguponpolarityswitch, ast_party_caller::id, ast_party_connected_line::id, analog_pvt::lastcid_name, analog_pvt::lastcid_num, LOG_WARNING, ast_party_id::name, ast_party_id::number, analog_dialoperation::op, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, pbx_builtin_getvar_helper(), analog_pvt::polaritydelaytv, analog_pvt::pulse, S_COR, analog_pvt::sig, ast_party_number::str, ast_party_name::str, analog_pvt::stripmsd, analog_pvt::subs, analog_pvt::use_callerid, ast_party_number::valid, ast_party_name::valid, and analog_pvt::whichwink.

Referenced by dahdi_call().

01011 {
01012    int res, idx, mysig;
01013    char *c, *n, *l;
01014    char dest[256]; /* must be same length as p->dialdest */
01015 
01016    ast_debug(1, "CALLING CID_NAME: %s CID_NUM:: %s\n",
01017       S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
01018       S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
01019 
01020    ast_copy_string(dest, rdest, sizeof(dest));
01021    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01022 
01023    if ((ast->_state == AST_STATE_BUSY)) {
01024       ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_BUSY);
01025       return 0;
01026    }
01027 
01028    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01029       ast_log(LOG_WARNING, "analog_call called on %s, neither down nor reserved\n", ast->name);
01030       return -1;
01031    }
01032 
01033    p->dialednone = 0;
01034    analog_set_outgoing(p, 1);
01035 
01036    mysig = p->sig;
01037    if (p->outsigmod > -1) {
01038       mysig = p->outsigmod;
01039    }
01040 
01041    switch (mysig) {
01042    case ANALOG_SIG_FXOLS:
01043    case ANALOG_SIG_FXOGS:
01044    case ANALOG_SIG_FXOKS:
01045       if (p->owner == ast) {
01046          /* Normal ring, on hook */
01047 
01048          /* Don't send audio while on hook, until the call is answered */
01049          analog_set_dialing(p, 1);
01050          analog_set_cadence(p, ast); /* and set p->cidrings */
01051 
01052          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01053          c = strchr(dest, '/');
01054          if (c) {
01055             c++;
01056          }
01057          if (c && (strlen(c) < p->stripmsd)) {
01058             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01059             c = NULL;
01060          }
01061          if (c) {
01062             p->dop.op = ANALOG_DIAL_OP_REPLACE;
01063             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01064             ast_debug(1, "FXO: setup deferred dialstring: %s\n", c);
01065          } else {
01066             p->dop.dialstr[0] = '\0';
01067          }
01068 
01069          if (analog_ring(p)) {
01070             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01071             return -1;
01072          }
01073          analog_set_dialing(p, 1);
01074       } else {
01075          /* Call waiting call */
01076          if (ast->connected.id.number.valid && ast->connected.id.number.str) {
01077             ast_copy_string(p->callwait_num, ast->connected.id.number.str, sizeof(p->callwait_num));
01078          } else {
01079             p->callwait_num[0] = '\0';
01080          }
01081          if (ast->connected.id.name.valid && ast->connected.id.name.str) {
01082             ast_copy_string(p->callwait_name, ast->connected.id.name.str, sizeof(p->callwait_name));
01083          } else {
01084             p->callwait_name[0] = '\0';
01085          }
01086 
01087          /* Call waiting tone instead */
01088          if (analog_callwait(p)) {
01089             return -1;
01090          }
01091          /* Make ring-back */
01092          if (analog_play_tone(p, ANALOG_SUB_CALLWAIT, ANALOG_TONE_RINGTONE)) {
01093             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01094          }
01095 
01096       }
01097       n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
01098       l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
01099       if (l) {
01100          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01101       } else {
01102          p->lastcid_num[0] = '\0';
01103       }
01104       if (n) {
01105          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01106       } else {
01107          p->lastcid_name[0] = '\0';
01108       }
01109 
01110       if (p->use_callerid) {
01111          p->caller.id.name.str = p->lastcid_name;
01112          p->caller.id.number.str = p->lastcid_num;
01113       }
01114 
01115       ast_setstate(ast, AST_STATE_RINGING);
01116       idx = analog_get_index(ast, p, 0);
01117       if (idx > -1) {
01118          struct ast_cc_config_params *cc_params;
01119 
01120          /* This is where the initial ringing frame is queued for an analog call.
01121           * As such, this is a great time to offer CCNR to the caller if it's available.
01122           */
01123          cc_params = ast_channel_get_cc_config_params(p->subs[idx].owner);
01124          if (cc_params) {
01125             switch (ast_get_cc_monitor_policy(cc_params)) {
01126             case AST_CC_MONITOR_NEVER:
01127                break;
01128             case AST_CC_MONITOR_NATIVE:
01129             case AST_CC_MONITOR_ALWAYS:
01130             case AST_CC_MONITOR_GENERIC:
01131                ast_queue_cc_frame(p->subs[idx].owner, AST_CC_GENERIC_MONITOR_TYPE,
01132                   analog_get_orig_dialstring(p), AST_CC_CCNR, NULL);
01133                break;
01134             }
01135          }
01136          ast_queue_control(p->subs[idx].owner, AST_CONTROL_RINGING);
01137       }
01138       break;
01139    case ANALOG_SIG_FXSLS:
01140    case ANALOG_SIG_FXSGS:
01141    case ANALOG_SIG_FXSKS:
01142       if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
01143          ast_debug(1, "Ignore possible polarity reversal on line seizure\n");
01144          p->polaritydelaytv = ast_tvnow();
01145       }
01146       /* fall through */
01147    case ANALOG_SIG_EMWINK:
01148    case ANALOG_SIG_EM:
01149    case ANALOG_SIG_EM_E1:
01150    case ANALOG_SIG_FEATD:
01151    case ANALOG_SIG_FEATDMF:
01152    case ANALOG_SIG_E911:
01153    case ANALOG_SIG_FGC_CAMA:
01154    case ANALOG_SIG_FGC_CAMAMF:
01155    case ANALOG_SIG_FEATB:
01156    case ANALOG_SIG_SFWINK:
01157    case ANALOG_SIG_SF:
01158    case ANALOG_SIG_SF_FEATD:
01159    case ANALOG_SIG_SF_FEATDMF:
01160    case ANALOG_SIG_FEATDMF_TA:
01161    case ANALOG_SIG_SF_FEATB:
01162       c = strchr(dest, '/');
01163       if (c) {
01164          c++;
01165       } else {
01166          c = "";
01167       }
01168       if (strlen(c) < p->stripmsd) {
01169          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01170          return -1;
01171       }
01172       res = analog_start(p);
01173       if (res < 0) {
01174          if (errno != EINPROGRESS) {
01175             return -1;
01176          }
01177       }
01178       ast_debug(1, "Dialing '%s'\n", c);
01179       p->dop.op = ANALOG_DIAL_OP_REPLACE;
01180 
01181       c += p->stripmsd;
01182 
01183       switch (mysig) {
01184       case ANALOG_SIG_FEATD:
01185          l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
01186          if (l) {
01187             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01188          } else {
01189             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01190          }
01191          break;
01192       case ANALOG_SIG_FEATDMF:
01193          l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
01194          if (l) {
01195             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01196          } else {
01197             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01198          }
01199          break;
01200       case ANALOG_SIG_FEATDMF_TA:
01201       {
01202          const char *cic = "", *ozz = "";
01203 
01204          /* If you have to go through a Tandem Access point you need to use this */
01205 #ifndef STANDALONE
01206          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01207          if (!ozz) {
01208             ozz = analog_defaultozz;
01209          }
01210          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01211          if (!cic) {
01212             cic = analog_defaultcic;
01213          }
01214 #endif
01215          if (!ozz || !cic) {
01216             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01217             return -1;
01218          }
01219          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01220          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01221          p->whichwink = 0;
01222       }
01223          break;
01224       case ANALOG_SIG_E911:
01225          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01226          break;
01227       case ANALOG_SIG_FGC_CAMA:
01228          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
01229          break;
01230       case ANALOG_SIG_FGC_CAMAMF:
01231       case ANALOG_SIG_FEATB:
01232          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
01233          break;
01234       default:
01235          if (p->pulse) {
01236             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
01237          } else {
01238             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
01239          }
01240          break;
01241       }
01242 
01243       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
01244          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
01245          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
01246          p->echorest[sizeof(p->echorest) - 1] = '\0';
01247          p->echobreak = 1;
01248          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
01249       } else {
01250          p->echobreak = 0;
01251       }
01252       analog_set_waitingfordt(p, ast);
01253       if (!res) {
01254          if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) {
01255             int saveerr = errno;
01256 
01257             analog_on_hook(p);
01258             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
01259             return -1;
01260          }
01261       } else {
01262          ast_debug(1, "Deferring dialing...\n");
01263       }
01264       analog_set_dialing(p, 1);
01265       if (ast_strlen_zero(c)) {
01266          p->dialednone = 1;
01267       }
01268       ast_setstate(ast, AST_STATE_DIALING);
01269       break;
01270    default:
01271       ast_debug(1, "not yet implemented\n");
01272       return -1;
01273    }
01274    return 0;
01275 }

static int analog_callwait ( struct analog_pvt p  )  [static]

Definition at line 886 of file sig_analog.c.

References analog_pvt::calls, analog_callback::callwait, analog_pvt::callwaitcas, analog_pvt::callwaitingcallerid, and analog_pvt::chan_pvt.

Referenced by analog_call().

00887 {
00888    p->callwaitcas = p->callwaitingcallerid;
00889    if (p->calls->callwait) {
00890       return p->calls->callwait(p->chan_pvt);
00891    }
00892    return 0;
00893 }

static void analog_cancel_cidspill ( struct analog_pvt p  )  [static]

Definition at line 968 of file sig_analog.c.

References analog_pvt::calls, analog_callback::cancel_cidspill, and analog_pvt::chan_pvt.

Referenced by __analog_handle_event(), and analog_handle_init_event().

00969 {
00970    if (!p->calls->cancel_cidspill) {
00971       return;
00972    }
00973 
00974    p->calls->cancel_cidspill(p->chan_pvt);
00975 }

static int analog_canmatch_featurecode ( const char *  exten  )  [static]

Definition at line 1719 of file sig_analog.c.

References ast_pickup_ext(), and pickup_ext.

Referenced by __analog_ss_thread().

01720 {
01721    int extlen = strlen(exten);
01722    const char *pickup_ext;
01723    if (!extlen) {
01724       return 1;
01725    }
01726    pickup_ext = ast_pickup_ext();
01727    if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) {
01728       return 1;
01729    }
01730    /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
01731    if (exten[0] == '*' && extlen < 3) {
01732       if (extlen == 1) {
01733          return 1;
01734       }
01735       /* "*0" should be processed before it gets here */
01736       switch (exten[1]) {
01737       case '6':
01738       case '7':
01739       case '8':
01740          return 1;
01741       }
01742    }
01743    return 0;
01744 }

static void analog_cb_handle_dtmf ( struct analog_pvt p,
struct ast_channel ast,
enum analog_sub  analog_index,
struct ast_frame **  dest 
) [static]

Definition at line 644 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::handle_dtmf.

Referenced by analog_handle_dtmf().

00645 {
00646    if (p->calls->handle_dtmf) {
00647       p->calls->handle_dtmf(p->chan_pvt, ast, analog_index, dest);
00648    }
00649 }

static int analog_check_confirmanswer ( struct analog_pvt p  )  [static]

Definition at line 959 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::check_confirmanswer.

Referenced by __analog_handle_event(), and analog_handle_dtmf().

00960 {
00961    if (p->calls->check_confirmanswer) {
00962       return p->calls->check_confirmanswer(p->chan_pvt);
00963    }
00964 
00965    return 0;
00966 }

static int analog_check_for_conference ( struct analog_pvt p  )  [static]

Definition at line 527 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::check_for_conference.

Referenced by __analog_handle_event().

00528 {
00529    if (p->calls->check_for_conference) {
00530       return p->calls->check_for_conference(p->chan_pvt);
00531    }
00532    return -1;
00533 }

static int analog_check_waitingfordt ( struct analog_pvt p  )  [static]

Definition at line 942 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::check_waitingfordt.

Referenced by __analog_handle_event().

00943 {
00944    if (p->calls->check_waitingfordt) {
00945       return p->calls->check_waitingfordt(p->chan_pvt);
00946    }
00947 
00948    return 0;
00949 }

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

Definition at line 231 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

00232 {
00233    switch (cid_start) {
00234    case ANALOG_CID_START_RING:
00235       return "Ring";
00236    case ANALOG_CID_START_POLARITY:
00237       return "Polarity";
00238    case ANALOG_CID_START_POLARITY_IN:
00239       return "Polarity_In";
00240    case ANALOG_CID_START_DTMF_NOALERT:
00241       return "DTMF";
00242    }
00243 
00244    return "Unknown";
00245 }

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 146 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00147 {
00148    int i;
00149 
00150    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00151       if (cid_type == cidtypes[i].cid_type) {
00152          return cidtypes[i].name;
00153       }
00154    }
00155 
00156    return "Unknown";
00157 }

int analog_config_complete ( struct analog_pvt p  ) 

Definition at line 3929 of file sig_analog.c.

References analog_set_callwaiting(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, analog_pvt::permcallwaiting, and analog_pvt::sig.

Referenced by mkintf().

03930 {
03931    /* No call waiting on non FXS channels */
03932    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03933       p->permcallwaiting = 0;
03934    }
03935 
03936    analog_set_callwaiting(p, p->permcallwaiting);
03937 
03938    return 0;
03939 }

static int analog_confmute ( struct analog_pvt p,
int  mute 
) [static]

Definition at line 977 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::confmute.

Referenced by __analog_handle_event().

00978 {
00979    if (p->calls->confmute) {
00980       return p->calls->confmute(p->chan_pvt, mute);
00981    }
00982    return 0;
00983 }

static int analog_decrease_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1676 of file sig_analog.c.

References analog_pvt::calls, and analog_callback::decrease_ss_count.

Referenced by __analog_ss_thread().

01677 {
01678    if (p->calls->decrease_ss_count) {
01679       p->calls->decrease_ss_count();
01680       return 0;
01681    }
01682    return -1;
01683 }

void analog_delete ( struct analog_pvt doomed  ) 

Delete the analog private structure.

Since:
1.8
Parameters:
doomed Analog private structure to delete.
Returns:
Nothing

Definition at line 3924 of file sig_analog.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

03925 {
03926    ast_free(doomed);
03927 }

static int analog_dial_digits ( struct analog_pvt p,
enum analog_sub  sub,
struct analog_dialoperation dop 
) [static]

Definition at line 503 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dial_digits.

Referenced by __analog_handle_event(), and analog_call().

00504 {
00505    if (p->calls->dial_digits) {
00506       return p->calls->dial_digits(p->chan_pvt, sub, dop);
00507    }
00508    return -1;
00509 }

static int analog_distinctive_ring ( struct ast_channel chan,
struct analog_pvt p,
int  idx,
int *  ringdata 
) [static]

Definition at line 1685 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::distinctive_ring.

Referenced by __analog_ss_thread().

01686 {
01687    if (p->calls->distinctive_ring) {
01688       return p->calls->distinctive_ring(chan, p->chan_pvt, idx, ringdata);
01689    }
01690    return -1;
01691 
01692 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

Definition at line 3965 of file sig_analog.c.

References ast_verb, analog_pvt::channel, analog_pvt::dnd, EVENT_FLAG_SYSTEM, and manager_event.

Referenced by __analog_ss_thread(), and dahdi_dnd().

03966 {
03967    if (flag == -1) {
03968       return p->dnd;
03969    }
03970 
03971    p->dnd = flag;
03972 
03973    ast_verb(3, "%s DND on channel %d\n",
03974          flag ? "Enabled" : "Disabled",
03975          p->channel);
03976    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03977          "Channel: DAHDI/%d\r\n"
03978          "Status: %s\r\n", p->channel,
03979          flag ? "enabled" : "disabled");
03980 
03981    return 0;
03982 }

static int analog_dsp_reset_and_flush_digits ( struct analog_pvt p  )  [static]

Definition at line 410 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dsp_reset_and_flush_digits.

Referenced by __analog_ss_thread().

00411 {
00412    if (p->calls->dsp_reset_and_flush_digits) {
00413       return p->calls->dsp_reset_and_flush_digits(p->chan_pvt);
00414    }
00415 
00416    /* Return 0 since I think this is unnecessary to do in most cases it is used.  Mostly only for ast_dsp */
00417    return 0;
00418 }

static int analog_dsp_set_digitmode ( struct analog_pvt p,
enum analog_dsp_digitmode  mode 
) [static]

Definition at line 636 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::dsp_set_digitmode.

Referenced by __analog_ss_thread(), and analog_hangup().

00637 {
00638    if (p->calls->dsp_set_digitmode) {
00639       return p->calls->dsp_set_digitmode(p->chan_pvt, mode);
00640    }
00641    return -1;
00642 }

static char* analog_event2str ( enum analog_event  event  )  [static]

Definition at line 247 of file sig_analog.c.

References ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, and ANALOG_EVENT_WINKFLASH.

Referenced by __analog_handle_event(), analog_exception(), and analog_handle_init_event().

00248 {
00249    char *res;
00250    switch (event) {
00251    case ANALOG_EVENT_ONHOOK:
00252       res = "ANALOG_EVENT_ONHOOK";
00253       break;
00254    case ANALOG_EVENT_RINGOFFHOOK:
00255       res = "ANALOG_EVENT_RINGOFFHOOK";
00256       break;
00257    case ANALOG_EVENT_WINKFLASH:
00258       res = "ANALOG_EVENT_WINKFLASH";
00259       break;
00260    case ANALOG_EVENT_ALARM:
00261       res = "ANALOG_EVENT_ALARM";
00262       break;
00263    case ANALOG_EVENT_NOALARM:
00264       res = "ANALOG_EVENT_NOALARM";
00265       break;
00266    case ANALOG_EVENT_DIALCOMPLETE:
00267       res = "ANALOG_EVENT_DIALCOMPLETE";
00268       break;
00269    case ANALOG_EVENT_HOOKCOMPLETE:
00270       res = "ANALOG_EVENT_HOOKCOMPLETE";
00271       break;
00272    case ANALOG_EVENT_PULSE_START:
00273       res = "ANALOG_EVENT_PULSE_START";
00274       break;
00275    case ANALOG_EVENT_POLARITY:
00276       res = "ANALOG_EVENT_POLARITY";
00277       break;
00278    case ANALOG_EVENT_RINGBEGIN:
00279       res = "ANALOG_EVENT_RINGBEGIN";
00280       break;
00281    case ANALOG_EVENT_EC_DISABLED:
00282       res = "ANALOG_EVENT_EC_DISABLED";
00283       break;
00284    case ANALOG_EVENT_RINGERON:
00285       res = "ANALOG_EVENT_RINGERON";
00286       break;
00287    case ANALOG_EVENT_RINGEROFF:
00288       res = "ANALOG_EVENT_RINGEROFF";
00289       break;
00290    case ANALOG_EVENT_REMOVED:
00291       res = "ANALOG_EVENT_REMOVED";
00292       break;
00293    case ANALOG_EVENT_NEONMWI_ACTIVE:
00294       res = "ANALOG_EVENT_NEONMWI_ACTIVE";
00295       break;
00296    case ANALOG_EVENT_NEONMWI_INACTIVE:
00297       res = "ANALOG_EVENT_NEONMWI_INACTIVE";
00298       break;
00299 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
00300    case ANALOG_EVENT_TX_CED_DETECTED:
00301       res = "ANALOG_EVENT_TX_CED_DETECTED";
00302       break;
00303    case ANALOG_EVENT_RX_CED_DETECTED:
00304       res = "ANALOG_EVENT_RX_CED_DETECTED";
00305       break;
00306    case ANALOG_EVENT_EC_NLP_DISABLED:
00307       res = "ANALOG_EVENT_EC_NLP_DISABLED";
00308       break;
00309    case ANALOG_EVENT_EC_NLP_ENABLED:
00310       res = "ANALOG_EVENT_EC_NLP_ENABLED";
00311       break;
00312 #endif
00313    case ANALOG_EVENT_PULSEDIGIT:
00314       res = "ANALOG_EVENT_PULSEDIGIT";
00315       break;
00316    case ANALOG_EVENT_DTMFDOWN:
00317       res = "ANALOG_EVENT_DTMFDOWN";
00318       break;
00319    case ANALOG_EVENT_DTMFUP:
00320       res = "ANALOG_EVENT_DTMFUP";
00321       break;
00322    default:
00323       res = "UNKNOWN/OTHER";
00324       break;
00325    }
00326 
00327    return res;
00328 }

struct ast_frame* analog_exception ( struct analog_pvt p,
struct ast_channel ast 
) [read]

Definition at line 3525 of file sig_analog.c.

References __analog_handle_event(), ast_channel::_state, analog_event2str(), ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_event(), analog_get_index, analog_lock_private(), analog_off_hook(), analog_ring(), analog_set_dialing(), analog_set_echocanceller(), analog_set_new_owner(), analog_stop_callwait(), ANALOG_SUB_REAL, analog_unlock_private(), analog_update_conf(), ast_bridged_channel(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_tv(), ast_verb, analog_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, analog_subchannel::f, f, ast_channel::fds, analog_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::mallocd, name, ast_frame::offset, analog_subchannel::owner, analog_pvt::owner, ast_frame::ptr, ast_frame::samples, ast_frame::src, ast_frame::subclass, and analog_pvt::subs.

Referenced by dahdi_exception(), and dahdi_read().

03526 {
03527    int res;
03528    int idx;
03529    struct ast_frame *f;
03530 
03531    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
03532 
03533    idx = analog_get_index(ast, p, 1);
03534    if (idx < 0) {
03535       idx = ANALOG_SUB_REAL;
03536    }
03537 
03538    p->subs[idx].f.frametype = AST_FRAME_NULL;
03539    p->subs[idx].f.datalen = 0;
03540    p->subs[idx].f.samples = 0;
03541    p->subs[idx].f.mallocd = 0;
03542    p->subs[idx].f.offset = 0;
03543    p->subs[idx].f.subclass.integer = 0;
03544    p->subs[idx].f.delivery = ast_tv(0,0);
03545    p->subs[idx].f.src = "dahdi_exception";
03546    p->subs[idx].f.data.ptr = NULL;
03547 
03548    if (!p->owner) {
03549       /* If nobody owns us, absorb the event appropriately, otherwise
03550          we loop indefinitely.  This occurs when, during call waiting, the
03551          other end hangs up our channel so that it no longer exists, but we
03552          have neither FLASH'd nor ONHOOK'd to signify our desire to
03553          change to the other channel. */
03554       res = analog_get_event(p);
03555 
03556       /* Switch to real if there is one and this isn't something really silly... */
03557       if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
03558          (res != ANALOG_EVENT_HOOKCOMPLETE)) {
03559          ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
03560          analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03561          if (p->owner && ast != p->owner) {
03562             /*
03563              * Could this even happen?
03564              * Possible deadlock because we do not have the real-call lock.
03565              */
03566             ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n",
03567                analog_event2str(res), ast->name, p->owner->name);
03568          }
03569          if (p->owner && ast_bridged_channel(p->owner)) {
03570             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03571          }
03572       }
03573       switch (res) {
03574       case ANALOG_EVENT_ONHOOK:
03575          analog_set_echocanceller(p, 0);
03576          if (p->owner) {
03577             ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name);
03578             analog_ring(p);
03579             analog_stop_callwait(p);
03580          } else {
03581             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03582                analog_event2str(res));
03583          }
03584          analog_update_conf(p);
03585          break;
03586       case ANALOG_EVENT_RINGOFFHOOK:
03587          analog_set_echocanceller(p, 1);
03588          analog_off_hook(p);
03589          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
03590             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03591             analog_set_dialing(p, 0);
03592          }
03593          break;
03594       case ANALOG_EVENT_HOOKCOMPLETE:
03595       case ANALOG_EVENT_RINGERON:
03596       case ANALOG_EVENT_RINGEROFF:
03597          /* Do nothing */
03598          break;
03599       case ANALOG_EVENT_WINKFLASH:
03600          gettimeofday(&p->flashtime, NULL);
03601          if (p->owner) {
03602             ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
03603             if (p->owner->_state != AST_STATE_UP) {
03604                /* Answer if necessary */
03605                ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03606                ast_setstate(p->owner, AST_STATE_UP);
03607             }
03608             analog_stop_callwait(p);
03609             if (ast_bridged_channel(p->owner)) {
03610                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03611             }
03612          } else {
03613             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03614                analog_event2str(res));
03615          }
03616          analog_update_conf(p);
03617          break;
03618       default:
03619          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res));
03620          break;
03621       }
03622       f = &p->subs[idx].f;
03623       return f;
03624    }
03625    ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
03626    /* If it's not us, return NULL immediately */
03627    if (ast != p->owner) {
03628       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
03629       f = &p->subs[idx].f;
03630       return f;
03631    }
03632 
03633    f = __analog_handle_event(p, ast);
03634    if (!f) {
03635       const char *name = ast_strdupa(ast->name);
03636 
03637       /* Tell the CDR this DAHDI device hung up */
03638       analog_unlock_private(p);
03639       ast_channel_unlock(ast);
03640       ast_set_hangupsource(ast, name, 0);
03641       ast_channel_lock(ast);
03642       analog_lock_private(p);
03643    }
03644    return f;
03645 }

int analog_fixup ( struct ast_channel oldchan,
struct ast_channel newchan,
void *  newp 
)

Definition at line 3947 of file sig_analog.c.

References analog_set_new_owner(), analog_update_conf(), ast_debug, analog_pvt::channel, analog_subchannel::owner, analog_pvt::owner, and analog_pvt::subs.

Referenced by dahdi_fixup().

03948 {
03949    struct analog_pvt *new_pvt = newp;
03950    int x;
03951    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03952    if (new_pvt->owner == oldchan) {
03953       analog_set_new_owner(new_pvt, newchan);
03954    }
03955    for (x = 0; x < 3; x++) {
03956       if (new_pvt->subs[x].owner == oldchan) {
03957          new_pvt->subs[x].owner = newchan;
03958       }
03959    }
03960 
03961    analog_update_conf(new_pvt);
03962    return 0;
03963 }

static int analog_flash ( struct analog_pvt p  )  [static]

Definition at line 487 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::flash.

Referenced by __analog_ss_thread().

00488 {
00489    if (p->calls->flash) {
00490       return p->calls->flash(p->chan_pvt);
00491    }
00492    return -1;
00493 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3941 of file sig_analog.c.

References ast_free.

03942 {
03943    ast_free(p);
03944 }

static void analog_get_and_handle_alarms ( struct analog_pvt p  )  [static]

Definition at line 1694 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_and_handle_alarms.

Referenced by __analog_handle_event(), and analog_handle_init_event().

01695 {
01696    if (p->calls->get_and_handle_alarms) {
01697       return p->calls->get_and_handle_alarms(p->chan_pvt);
01698    }
01699 }

static void* analog_get_bridged_channel ( struct analog_pvt p,
struct ast_channel chan 
) [static]

Definition at line 1701 of file sig_analog.c.

References analog_pvt::calls, and analog_callback::get_sigpvt_bridged_channel.

Referenced by __analog_ss_thread().

01702 {
01703    if (p->calls->get_sigpvt_bridged_channel) {
01704       return p->calls->get_sigpvt_bridged_channel(chan);
01705    }
01706    return NULL;
01707 }

static int analog_get_callerid ( struct analog_pvt p,
char *  name,
char *  number,
enum analog_event ev,
size_t  timeout 
) [static]

Definition at line 175 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_callerid.

Referenced by __analog_ss_thread().

00176 {
00177    if (p->calls->get_callerid) {
00178       return p->calls->get_callerid(p->chan_pvt, name, number, ev, timeout);
00179    }
00180    return -1;
00181 }

static int analog_get_event ( struct analog_pvt p  )  [static]

Definition at line 191 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_event.

Referenced by __analog_handle_event(), and analog_exception().

00192 {
00193    if (p->calls->get_event) {
00194       return p->calls->get_event(p->chan_pvt);
00195    }
00196    return -1;
00197 }

static const char* analog_get_orig_dialstring ( struct analog_pvt p  )  [static]

Definition at line 183 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_orig_dialstring.

Referenced by analog_call().

00184 {
00185    if (p->calls->get_orig_dialstring) {
00186       return p->calls->get_orig_dialstring(p->chan_pvt);
00187    }
00188    return "";
00189 }

static int analog_get_sub_fd ( struct analog_pvt p,
enum analog_sub  sub 
) [static]

Definition at line 1709 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::get_sub_fd.

Referenced by __analog_handle_event().

01710 {
01711    if (p->calls->get_sub_fd) {
01712       return p->calls->get_sub_fd(p->chan_pvt, sub);
01713    }
01714    return -1;
01715 }

void analog_handle_dtmf ( struct analog_pvt p,
struct ast_channel ast,
enum analog_sub  idx,
struct ast_frame **  dest 
)

Definition at line 1596 of file sig_analog.c.

References analog_cb_handle_dtmf(), analog_check_confirmanswer(), analog_handles_digit(), analog_send_callerid(), analog_set_confirmanswer(), AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, analog_pvt::caller, analog_pvt::callwait_name, analog_pvt::callwait_num, analog_pvt::callwaitcas, analog_subchannel::f, f, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, ast_party_id::name, ast_party_id::number, ast_party_number::str, ast_party_name::str, ast_frame::subclass, and analog_pvt::subs.

Referenced by __analog_handle_event(), and dahdi_read().

01597 {
01598    struct ast_frame *f = *dest;
01599 
01600    ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
01601       f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
01602       f->subclass.integer, f->subclass.integer, ast->name);
01603 
01604    if (analog_check_confirmanswer(p)) {
01605       if (f->frametype == AST_FRAME_DTMF_END) {
01606          ast_debug(1, "Confirm answer on %s!\n", ast->name);
01607          /* Upon receiving a DTMF digit, consider this an answer confirmation instead
01608          of a DTMF digit */
01609          p->subs[idx].f.frametype = AST_FRAME_CONTROL;
01610          p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
01611          /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
01612          analog_set_confirmanswer(p, 0);
01613       } else {
01614          p->subs[idx].f.frametype = AST_FRAME_NULL;
01615          p->subs[idx].f.subclass.integer = 0;
01616       }
01617       *dest = &p->subs[idx].f;
01618    } else if (p->callwaitcas) {
01619       if (f->frametype == AST_FRAME_DTMF_END) {
01620          if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
01621             ast_debug(1, "Got some DTMF, but it's for the CAS\n");
01622             p->caller.id.name.str = p->callwait_name;
01623             p->caller.id.number.str = p->callwait_num;
01624             analog_send_callerid(p, 1, &p->caller);
01625          }
01626          if (analog_handles_digit(f)) {
01627             p->callwaitcas = 0;
01628          }
01629       }
01630       p->subs[idx].f.frametype = AST_FRAME_NULL;
01631       p->subs[idx].f.subclass.integer = 0;
01632       *dest = &p->subs[idx].f;
01633    } else {
01634       analog_cb_handle_dtmf(p, ast, idx, dest);
01635    }
01636 }

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3647 of file sig_analog.c.

References __analog_ss_thread(), analog_cancel_cidspill(), ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, analog_event2str(), ANALOG_EVENT_ALARM, ANALOG_EVENT_DTMFCID, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_and_handle_alarms(), analog_handle_notify_message(), analog_has_voicemail(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_alarm(), analog_set_echocanceller(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_sigtype_to_str(), analog_start_polarityswitch(), ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALTONE, ANALOG_TONE_RINGTONE, ANALOG_TONE_STUTTER, ast_debug, ast_hangup(), ast_log(), ast_pthread_create_detached, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verb, analog_pvt::chan_pvt, analog_pvt::channel, analog_pvt::cid_start, errno, EVENT_FLAG_SYSTEM, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, analog_pvt::immediate, analog_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event, analog_pvt::polarity, POLARITY_REV, analog_pvt::ringt_base, analog_pvt::sig, and analog_pvt::ss_astchan.

Referenced by do_monitor().

03648 {
03649    int res;
03650    pthread_t threadid;
03651    struct ast_channel *chan;
03652 
03653    ast_debug(1, "channel (%d) - signaling (%d) - event (%s)\n",
03654             i->channel, i->sig, analog_event2str(event));
03655 
03656    /* Handle an event on a given channel for the monitor thread. */
03657    switch (event) {
03658    case ANALOG_EVENT_WINKFLASH:
03659    case ANALOG_EVENT_RINGOFFHOOK:
03660       if (i->inalarm) {
03661          break;
03662       }
03663       /* Got a ring/answer.  What kind of channel are we? */
03664       switch (i->sig) {
03665       case ANALOG_SIG_FXOLS:
03666       case ANALOG_SIG_FXOGS:
03667       case ANALOG_SIG_FXOKS:
03668          res = analog_off_hook(i);
03669          i->fxsoffhookstate = 1;
03670          if (res && (errno == EBUSY)) {
03671             break;
03672          }
03673 
03674          /* Cancel VMWI spill */
03675          analog_cancel_cidspill(i);
03676 
03677          if (i->immediate) {
03678             analog_set_echocanceller(i, 1);
03679             /* The channel is immediately up.  Start right away */
03680             res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE);
03681             chan = analog_new_ast_channel(i, AST_STATE_RING, 1, ANALOG_SUB_REAL, NULL);
03682             if (!chan) {
03683                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
03684                res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03685                if (res < 0) {
03686                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03687                }
03688             }
03689          } else {
03690             /* Check for callerid, digits, etc */
03691             chan = analog_new_ast_channel(i, AST_STATE_RESERVED, 0, ANALOG_SUB_REAL, NULL);
03692             i->ss_astchan = chan;
03693             if (chan) {
03694                if (analog_has_voicemail(i)) {
03695                   res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER);
03696                } else {
03697                   res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE);
03698                }
03699                if (res < 0)
03700                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
03701 
03702                if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03703                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03704                   res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03705                   if (res < 0) {
03706                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03707                   }
03708                   ast_hangup(chan);
03709                }
03710             } else
03711                ast_log(LOG_WARNING, "Unable to create channel\n");
03712          }
03713          break;
03714       case ANALOG_SIG_FXSLS:
03715       case ANALOG_SIG_FXSGS:
03716       case ANALOG_SIG_FXSKS:
03717          analog_set_ringtimeout(i, i->ringt_base);
03718          /* Fall through */
03719       case ANALOG_SIG_EMWINK:
03720       case ANALOG_SIG_FEATD:
03721       case ANALOG_SIG_FEATDMF:
03722       case ANALOG_SIG_FEATDMF_TA:
03723       case ANALOG_SIG_E911:
03724       case ANALOG_SIG_FGC_CAMA:
03725       case ANALOG_SIG_FGC_CAMAMF:
03726       case ANALOG_SIG_FEATB:
03727       case ANALOG_SIG_EM:
03728       case ANALOG_SIG_EM_E1:
03729       case ANALOG_SIG_SFWINK:
03730       case ANALOG_SIG_SF_FEATD:
03731       case ANALOG_SIG_SF_FEATDMF:
03732       case ANALOG_SIG_SF_FEATB:
03733       case ANALOG_SIG_SF:
03734          /* Check for callerid, digits, etc */
03735          if (i->cid_start == ANALOG_CID_START_POLARITY_IN || i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
03736             chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
03737          } else {
03738             chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL);
03739          }
03740          i->ss_astchan = chan;
03741          if (!chan) {
03742             ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
03743          } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03744             ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03745             res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03746             if (res < 0) {
03747                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03748             }
03749             ast_hangup(chan);
03750          }
03751          break;
03752       default:
03753          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", analog_sigtype_to_str(i->sig), i->channel);
03754          res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03755          if (res < 0) {
03756             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03757          }
03758          return NULL;
03759       }
03760       break;
03761    case ANALOG_EVENT_NOALARM:
03762       analog_set_alarm(i, 0);
03763       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
03764       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
03765          "Channel: %d\r\n", i->channel);
03766       break;
03767    case ANALOG_EVENT_ALARM:
03768       analog_set_alarm(i, 1);
03769       analog_get_and_handle_alarms(i);
03770       /* fall thru intentionally */
03771    case ANALOG_EVENT_ONHOOK:
03772       /* Back on hook.  Hang up. */
03773       switch (i->sig) {
03774       case ANALOG_SIG_FXOLS:
03775       case ANALOG_SIG_FXOGS:
03776          i->fxsoffhookstate = 0;
03777          analog_start_polarityswitch(i);
03778          /* Fall through */
03779       case ANALOG_SIG_FEATD:
03780       case ANALOG_SIG_FEATDMF:
03781       case ANALOG_SIG_FEATDMF_TA:
03782       case ANALOG_SIG_E911:
03783       case ANALOG_SIG_FGC_CAMA:
03784       case ANALOG_SIG_FGC_CAMAMF:
03785       case ANALOG_SIG_FEATB:
03786       case ANALOG_SIG_EM:
03787       case ANALOG_SIG_EM_E1:
03788       case ANALOG_SIG_EMWINK:
03789       case ANALOG_SIG_SF_FEATD:
03790       case ANALOG_SIG_SF_FEATDMF:
03791       case ANALOG_SIG_SF_FEATB:
03792       case ANALOG_SIG_SF:
03793       case ANALOG_SIG_SFWINK:
03794       case ANALOG_SIG_FXSLS:
03795       case ANALOG_SIG_FXSGS:
03796       case ANALOG_SIG_FXSKS:
03797          analog_set_echocanceller(i, 0);
03798          res = analog_play_tone(i, ANALOG_SUB_REAL, -1);
03799          analog_on_hook(i);
03800          break;
03801       case ANALOG_SIG_FXOKS:
03802          i->fxsoffhookstate = 0;
03803          analog_start_polarityswitch(i);
03804          analog_set_echocanceller(i, 0);
03805          /* Diddle the battery for the zhone */
03806 #ifdef ZHONE_HACK
03807          analog_off_hook(i);
03808          usleep(1);
03809 #endif
03810          res = analog_play_tone(i, ANALOG_SUB_REAL, -1);
03811          analog_on_hook(i);
03812          break;
03813       default:
03814          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", analog_sigtype_to_str(i->sig), i->channel);
03815          res = analog_play_tone(i, ANALOG_SUB_REAL, -1);
03816          return NULL;
03817       }
03818       break;
03819    case ANALOG_EVENT_POLARITY:
03820       switch (i->sig) {
03821       case ANALOG_SIG_FXSLS:
03822       case ANALOG_SIG_FXSKS:
03823       case ANALOG_SIG_FXSGS:
03824          /* We have already got a PR before the channel was
03825             created, but it wasn't handled. We need polarity
03826             to be REV for remote hangup detection to work.
03827             At least in Spain */
03828          if (i->hanguponpolarityswitch) {
03829             i->polarity = POLARITY_REV;
03830          }
03831          if (i->cid_start == ANALOG_CID_START_POLARITY || i->cid_start == ANALOG_CID_START_POLARITY_IN) {
03832             i->polarity = POLARITY_REV;
03833             ast_verb(2, "Starting post polarity "
03834                "CID detection on channel %d\n",
03835                i->channel);
03836             chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
03837             i->ss_astchan = chan;
03838             if (!chan) {
03839                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
03840             } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03841                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03842                ast_hangup(chan);
03843             }
03844          }
03845          break;
03846       default:
03847          ast_log(LOG_WARNING, "handle_init_event detected "
03848             "polarity reversal on non-FXO (ANALOG_SIG_FXS) "
03849             "interface %d\n", i->channel);
03850          break;
03851       }
03852       break;
03853    case ANALOG_EVENT_DTMFCID:
03854       switch (i->sig) {
03855       case ANALOG_SIG_FXSLS:
03856       case ANALOG_SIG_FXSKS:
03857       case ANALOG_SIG_FXSGS:
03858          if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
03859             ast_verb(2, "Starting DTMF CID detection on channel %d\n",
03860                i->channel);
03861             chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
03862             i->ss_astchan = chan;
03863             if (!chan) {
03864                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
03865             } else if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03866                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03867                ast_hangup(chan);
03868             }
03869          }
03870          break;
03871       default:
03872          ast_log(LOG_WARNING, "handle_init_event detected "
03873             "dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) "
03874             "interface %d\n", i->channel);
03875          break;
03876       }
03877       break;
03878    case ANALOG_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
03879       ast_log(LOG_NOTICE, "Got ANALOG_EVENT_REMOVED. Destroying channel %d\n",
03880          i->channel);
03881       return i->chan_pvt;
03882    case ANALOG_EVENT_NEONMWI_ACTIVE:
03883       analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_ACTIVE);
03884       break;
03885    case ANALOG_EVENT_NEONMWI_INACTIVE:
03886       analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_INACTIVE);
03887       break;
03888    }
03889    return NULL;
03890 }

static int analog_handle_notify_message ( struct ast_channel chan,
struct analog_pvt p,
int  cid_flags,
int  neon_mwievent 
) [static]

Definition at line 1658 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::handle_notify_message.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

01659 {
01660    if (p->calls->handle_notify_message) {
01661       p->calls->handle_notify_message(chan, p->chan_pvt, cid_flags, neon_mwievent);
01662       return 0;
01663    }
01664    return -1;
01665 }

static int analog_handles_digit ( struct ast_frame f  )  [static]

Definition at line 1571 of file sig_analog.c.

References ast_frame_subclass::integer, and ast_frame::subclass.

Referenced by analog_handle_dtmf().

01572 {
01573    char subclass = toupper(f->subclass.integer);
01574 
01575    switch (subclass) {
01576    case '1':
01577    case '2':
01578    case '3':
01579    case '4':
01580    case '5':
01581    case '6':
01582    case '7':
01583    case '9':
01584    case 'A':
01585    case 'B':
01586    case 'C':
01587    case 'D':
01588    case 'E':
01589    case 'F':
01590       return 1;
01591    default:
01592       return 0;
01593    }
01594 }

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1277 of file sig_analog.c.

References ast_channel::_state, analog_subchannel::allocd, analog_all_subchannels_hungup(), ANALOG_DIGITMODE_DTMF, analog_dsp_set_digitmode(), analog_get_index, analog_hangup_polarityswitch(), analog_is_off_hook(), analog_lock_sub_owner(), analog_on_hook(), analog_play_tone(), analog_set_callwaiting(), analog_set_confirmanswer(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_linear_mode(), analog_set_new_owner(), analog_set_outgoing(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, analog_unalloc_sub(), analog_update_conf(), ast_bridged_channel(), ast_channel_setoption(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_free, ast_log(), AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), ast_verb, analog_pvt::callwaitcas, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, analog_pvt::cidrings, analog_pvt::guardtime, analog_pvt::hidecallerid, analog_subchannel::inthreeway, LOG_ERROR, LOG_WARNING, analog_pvt::mohsuggest, analog_pvt::onhooktime, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::owner, analog_subchannel::owner, analog_pvt::permcallwaiting, analog_pvt::permhidecallerid, analog_pvt::polarity, POLARITY_IDLE, S_OR, analog_pvt::sig, analog_pvt::subs, and ast_channel::tech_pvt.

Referenced by dahdi_hangup().

01278 {
01279    int res;
01280    int idx, x;
01281 
01282    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
01283    if (!ast->tech_pvt) {
01284       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
01285       return 0;
01286    }
01287 
01288    idx = analog_get_index(ast, p, 1);
01289 
01290    x = 0;
01291    if (p->origcid_num) {
01292       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
01293       ast_free(p->origcid_num);
01294       p->origcid_num = NULL;
01295    }
01296    if (p->origcid_name) {
01297       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
01298       ast_free(p->origcid_name);
01299       p->origcid_name = NULL;
01300    }
01301 
01302    analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01303 
01304    ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
01305       p->channel, idx, p->subs[ANALOG_SUB_REAL].allocd, p->subs[ANALOG_SUB_CALLWAIT].allocd, p->subs[ANALOG_SUB_THREEWAY].allocd);
01306    if (idx > -1) {
01307       /* Real channel, do some fixup */
01308       p->subs[idx].owner = NULL;
01309       p->polarity = POLARITY_IDLE;
01310       analog_set_linear_mode(p, idx, 0);
01311       switch (idx) {
01312       case ANALOG_SUB_REAL:
01313          if (p->subs[ANALOG_SUB_CALLWAIT].allocd && p->subs[ANALOG_SUB_THREEWAY].allocd) {
01314             ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
01315             if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
01316                /* We had flipped over to answer a callwait and now it's gone */
01317                ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
01318                /* Move to the call-wait, but un-own us until they flip back. */
01319                analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
01320                analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
01321                analog_set_new_owner(p, NULL);
01322             } else {
01323                /* The three way hung up, but we still have a call wait */
01324                ast_debug(1, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
01325                analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01326                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01327                if (p->subs[ANALOG_SUB_REAL].inthreeway) {
01328                   /* This was part of a three way call.  Immediately make way for
01329                      another call */
01330                   ast_debug(1, "Call was complete, setting owner to former third call\n");
01331                   analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
01332                   analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
01333                } else {
01334                   /* This call hasn't been completed yet...  Set owner to NULL */
01335                   ast_debug(1, "Call was incomplete, setting owner to NULL\n");
01336                   analog_set_new_owner(p, NULL);
01337                }
01338             }
01339          } else if (p->subs[ANALOG_SUB_CALLWAIT].allocd) {
01340             /* Need to hold the lock for real-call, private, and call-waiting call */
01341             analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
01342             if (!p->subs[ANALOG_SUB_CALLWAIT].owner) {
01343                /* The call waiting call dissappeared. */
01344                analog_set_new_owner(p, NULL);
01345                break;
01346             }
01347 
01348             /* Move to the call-wait and switch back to them. */
01349             analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
01350             analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
01351             analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
01352             if (p->owner->_state != AST_STATE_UP) {
01353                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
01354             }
01355             if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
01356                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
01357             }
01358             /* Unlock the call-waiting call that we swapped to real-call. */
01359             ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
01360          } else if (p->subs[ANALOG_SUB_THREEWAY].allocd) {
01361             analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01362             analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01363             if (p->subs[ANALOG_SUB_REAL].inthreeway) {
01364                /* This was part of a three way call.  Immediately make way for
01365                   another call */
01366                ast_debug(1, "Call was complete, setting owner to former third call\n");
01367                analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
01368                analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
01369             } else {
01370                /* This call hasn't been completed yet...  Set owner to NULL */
01371                ast_debug(1, "Call was incomplete, setting owner to NULL\n");
01372                analog_set_new_owner(p, NULL);
01373             }
01374          }
01375          break;
01376       case ANALOG_SUB_CALLWAIT:
01377          /* Ditch the holding callwait call, and immediately make it available */
01378          if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
01379             /* Need to hold the lock for call-waiting call, private, and 3-way call */
01380             analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY);
01381 
01382             /* This is actually part of a three way, placed on hold.  Place the third part
01383                on music on hold now */
01384             if (p->subs[ANALOG_SUB_THREEWAY].owner && ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
01385                ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD,
01386                   S_OR(p->mohsuggest, NULL),
01387                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
01388             }
01389             analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
01390             /* Make it the call wait now */
01391             analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY);
01392             analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01393             if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
01394                /* Unlock the 3-way call that we swapped to call-waiting call. */
01395                ast_channel_unlock(p->subs[ANALOG_SUB_CALLWAIT].owner);
01396             }
01397          } else {
01398             analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
01399          }
01400          break;
01401       case ANALOG_SUB_THREEWAY:
01402          /* Need to hold the lock for 3-way call, private, and call-waiting call */
01403          analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
01404          if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
01405             /* The other party of the three way call is currently in a call-wait state.
01406                Start music on hold for them, and take the main guy out of the third call */
01407             analog_set_inthreeway(p, ANALOG_SUB_CALLWAIT, 0);
01408             if (p->subs[ANALOG_SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) {
01409                ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
01410                   S_OR(p->mohsuggest, NULL),
01411                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
01412             }
01413          }
01414          if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
01415             ast_channel_unlock(p->subs[ANALOG_SUB_CALLWAIT].owner);
01416          }
01417          analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
01418          /* If this was part of a three way call index, let us make
01419             another three way call */
01420          analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01421          break;
01422       default:
01423          /*
01424           * Should never happen.
01425           * This wasn't any sort of call, so how are we an index?
01426           */
01427          ast_log(LOG_ERROR, "Index found but not any type of call?\n");
01428          break;
01429       }
01430    }
01431 
01432    if (!p->subs[ANALOG_SUB_REAL].owner && !p->subs[ANALOG_SUB_CALLWAIT].owner && !p->subs[ANALOG_SUB_THREEWAY].owner) {
01433       analog_set_new_owner(p, NULL);
01434       analog_set_ringtimeout(p, 0);
01435       analog_set_confirmanswer(p, 0);
01436       analog_set_pulsedial(p, 0);
01437       analog_set_outgoing(p, 0);
01438       p->onhooktime = time(NULL);
01439       p->cidrings = 1;
01440 
01441       /* Perform low level hangup if no owner left */
01442       res = analog_on_hook(p);
01443       if (res < 0) {
01444          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
01445       }
01446       switch (p->sig) {
01447       case ANALOG_SIG_FXOGS:
01448       case ANALOG_SIG_FXOLS:
01449       case ANALOG_SIG_FXOKS:
01450          /* If they're off hook, try playing congestion */
01451          if (analog_is_off_hook(p)) {
01452             analog_hangup_polarityswitch(p);
01453             analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
01454          } else {
01455             analog_play_tone(p, ANALOG_SUB_REAL, -1);
01456          }
01457          break;
01458       case ANALOG_SIG_FXSGS:
01459       case ANALOG_SIG_FXSLS:
01460       case ANALOG_SIG_FXSKS:
01461          /* Make sure we're not made available for at least two seconds assuming
01462             we were actually used for an inbound or outbound call. */
01463          if (ast->_state != AST_STATE_RESERVED) {
01464             time(&p->guardtime);
01465             p->guardtime += 2;
01466          }
01467          break;
01468       default:
01469          analog_play_tone(p, ANALOG_SUB_REAL, -1);
01470          break;
01471       }
01472 
01473       analog_set_echocanceller(p, 0);
01474 
01475       x = 0;
01476       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
01477       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
01478       p->callwaitcas = 0;
01479       analog_set_callwaiting(p, p->permcallwaiting);
01480       p->hidecallerid = p->permhidecallerid;
01481       analog_set_dialing(p, 0);
01482       analog_update_conf(p);
01483       analog_all_subchannels_hungup(p);
01484    }
01485 
01486    analog_stop_callwait(p);
01487 
01488    ast_verb(3, "Hanging up on '%s'\n", ast->name);
01489 
01490    return 0;
01491 }

static void analog_hangup_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 629 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::hangup_polarityswitch.

Referenced by analog_hangup().

00630 {
00631    if (p->calls->hangup_polarityswitch) {
00632       return p->calls->hangup_polarityswitch(p->chan_pvt);
00633    }
00634 }

static int analog_has_voicemail ( struct analog_pvt p  )  [static]

Definition at line 659 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::has_voicemail.

Referenced by __analog_handle_event(), and analog_handle_init_event().

00660 {
00661    if (p->calls->has_voicemail) {
00662       return p->calls->has_voicemail(p->chan_pvt);
00663    }
00664    return -1;
00665 }

static int analog_have_progressdetect ( struct analog_pvt p  )  [static]

Definition at line 207 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::have_progressdetect.

Referenced by __analog_handle_event().

00208 {
00209    if (p->calls->have_progressdetect) {
00210       return p->calls->have_progressdetect(p->chan_pvt);
00211    }
00212    /* Don't have progress detection. */
00213    return 0;
00214 }

static int analog_increase_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1667 of file sig_analog.c.

References analog_pvt::calls, and analog_callback::increase_ss_count.

Referenced by __analog_ss_thread().

01668 {
01669    if (p->calls->increase_ss_count) {
01670       p->calls->increase_ss_count();
01671       return 0;
01672    }
01673    return -1;
01674 }

static int analog_is_dialing ( struct analog_pvt p,
enum analog_sub  index 
) [static]

Definition at line 667 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::is_dialing.

Referenced by __analog_handle_event().

00668 {
00669    if (p->calls->is_dialing) {
00670       return p->calls->is_dialing(p->chan_pvt, index);
00671    }
00672    return -1;
00673 }

static int analog_is_off_hook ( struct analog_pvt p  )  [static]

Definition at line 471 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::is_off_hook.

Referenced by analog_available(), and analog_hangup().

00472 {
00473    if (p->calls->is_off_hook) {
00474       return p->calls->is_off_hook(p->chan_pvt);
00475    }
00476    return -1;
00477 }

static void analog_lock_private ( struct analog_pvt p  )  [static]

Definition at line 549 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::lock_private.

Referenced by __analog_handle_event(), and analog_exception().

00550 {
00551    if (p->calls->lock_private) {
00552       p->calls->lock_private(p->chan_pvt);
00553    }
00554 }

static void analog_lock_sub_owner ( struct analog_pvt pvt,
enum analog_sub  sub_idx 
) [static]

Definition at line 571 of file sig_analog.c.

References ast_channel_trylock, analog_pvt::calls, analog_pvt::chan_pvt, analog_callback::deadlock_avoidance_private, analog_subchannel::owner, and analog_pvt::subs.

Referenced by __analog_handle_event(), and analog_hangup().

00572 {
00573    for (;;) {
00574       if (!pvt->subs[sub_idx].owner) {
00575          /* No subchannel owner pointer */
00576          break;
00577       }
00578       if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
00579          /* Got subchannel owner lock */
00580          break;
00581       }
00582       /* We must unlock the private to avoid the possibility of a deadlock */
00583       if (pvt->calls->deadlock_avoidance_private) {
00584          pvt->calls->deadlock_avoidance_private(pvt->chan_pvt);
00585       } else {
00586          /* Don't use 100% CPU if required callback not present. */
00587          usleep(1);
00588       }
00589    }
00590 }

static int analog_my_getsigstr ( struct ast_channel chan,
char *  str,
const char *  term,
int  ms 
) [static]

Definition at line 1638 of file sig_analog.c.

References ast_waitfordigit().

Referenced by __analog_ss_thread().

01639 {
01640    char c;
01641 
01642    *str = 0; /* start with empty output buffer */
01643    for (;;) {
01644       /* Wait for the first digit (up to specified ms). */
01645       c = ast_waitfordigit(chan, ms);
01646       /* if timeout, hangup or error, return as such */
01647       if (c < 1) {
01648          return c;
01649       }
01650       *str++ = c;
01651       *str = 0;
01652       if (strchr(term, c)) {
01653          return 1;
01654       }
01655    }
01656 }

struct analog_pvt* analog_new ( enum analog_sigtype  signallingtype,
struct analog_callback c,
void *  private_data 
) [read]

Definition at line 3893 of file sig_analog.c.

References analog_subchannel::allocd, ANALOG_CID_START_RING, ANALOG_SIG_NONE, ANALOG_SUB_REAL, ast_calloc, analog_pvt::calls, analog_pvt::chan_pvt, CID_SIG_BELL, analog_pvt::cid_signalling, analog_pvt::cid_start, analog_pvt::outsigmod, analog_pvt::sig, and analog_pvt::subs.

Referenced by mkintf().

03894 {
03895    struct analog_pvt *p;
03896 
03897    p = ast_calloc(1, sizeof(*p));
03898    if (!p) {
03899       return p;
03900    }
03901 
03902    p->calls = c;
03903    p->outsigmod = ANALOG_SIG_NONE;
03904    p->sig = signallingtype;
03905    p->chan_pvt = private_data;
03906 
03907    /* Some defaults for values */
03908    p->cid_start = ANALOG_CID_START_RING;
03909    p->cid_signalling = CID_SIG_BELL;
03910    /* Sub real is assumed to always be alloc'd */
03911    p->subs[ANALOG_SUB_REAL].allocd = 1;
03912 
03913    return p;
03914 }

static struct ast_channel* analog_new_ast_channel ( struct analog_pvt p,
int  state,
int  startpbx,
enum analog_sub  sub,
const struct ast_channel requestor 
) [static, read]

Definition at line 436 of file sig_analog.c.

References analog_set_new_owner(), ast_string_field_set, analog_pvt::call_forward, analog_pvt::calls, analog_pvt::chan_pvt, analog_callback::new_ast_channel, analog_pvt::owner, analog_subchannel::owner, and analog_pvt::subs.

Referenced by __analog_handle_event(), analog_handle_init_event(), and analog_request().

00437 {
00438    struct ast_channel *c;
00439 
00440    if (!p->calls->new_ast_channel) {
00441       return NULL;
00442    }
00443 
00444    c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub, requestor);
00445    if (c) {
00446       ast_string_field_set(c, call_forward, p->call_forward);
00447    }
00448    p->subs[sub].owner = c;
00449    if (!p->owner) {
00450       analog_set_new_owner(p, c);
00451    }
00452    return c;
00453 }

static int analog_off_hook ( struct analog_pvt p  )  [static]

Definition at line 592 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::off_hook.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_exception(), and analog_handle_init_event().

00593 {
00594    if (p->calls->off_hook) {
00595       return p->calls->off_hook(p->chan_pvt);
00596    }
00597    return -1;
00598 }

static int analog_on_hook ( struct analog_pvt p  )  [static]

Definition at line 511 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::on_hook.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_call(), analog_handle_init_event(), and analog_hangup().

00512 {
00513    if (p->calls->on_hook) {
00514       return p->calls->on_hook(p->chan_pvt);
00515    }
00516    return -1;
00517 }

static int analog_play_tone ( struct analog_pvt p,
enum analog_sub  sub,
enum analog_tone  tone 
) [static]

Definition at line 420 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::play_tone.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_call(), analog_handle_init_event(), and analog_hangup().

00421 {
00422    if (p->calls->play_tone) {
00423       return p->calls->play_tone(p->chan_pvt, sub, tone);
00424    }
00425    return -1;
00426 }

struct ast_channel* analog_request ( struct analog_pvt p,
int *  callwait,
const struct ast_channel requestor 
) [read]

Definition at line 790 of file sig_analog.c.

References analog_alloc_sub(), analog_new_ast_channel(), analog_set_outgoing(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ast_debug, ast_log(), AST_STATE_RESERVED, analog_pvt::channel, LOG_ERROR, and analog_pvt::owner.

Referenced by dahdi_request().

00791 {
00792    struct ast_channel *ast;
00793 
00794    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
00795    *callwait = (p->owner != NULL);
00796 
00797    if (p->owner) {
00798       if (analog_alloc_sub(p, ANALOG_SUB_CALLWAIT)) {
00799          ast_log(LOG_ERROR, "Unable to alloc subchannel\n");
00800          return NULL;
00801       }
00802    }
00803 
00804    analog_set_outgoing(p, 1);
00805    ast = analog_new_ast_channel(p, AST_STATE_RESERVED, 0,
00806       p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor);
00807    if (!ast) {
00808       analog_set_outgoing(p, 0);
00809    }
00810    return ast;
00811 }

static int analog_ring ( struct analog_pvt p  )  [static]

Definition at line 479 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::ring.

Referenced by __analog_handle_event(), analog_call(), and analog_exception().

00480 {
00481    if (p->calls->ring) {
00482       return p->calls->ring(p->chan_pvt);
00483    }
00484    return -1;
00485 }

static int analog_send_callerid ( struct analog_pvt p,
int  cwcid,
struct ast_party_caller caller 
) [static]

Definition at line 373 of file sig_analog.c.

References ast_debug, analog_pvt::calls, analog_pvt::callwaitcas, analog_pvt::chan_pvt, ast_party_caller::id, ast_party_id::name, ast_party_id::number, analog_callback::send_callerid, ast_party_number::str, and ast_party_name::str.

Referenced by __analog_handle_event(), and analog_handle_dtmf().

00374 {
00375    ast_debug(1, "Sending callerid.  CID_NAME: '%s' CID_NUM: '%s'\n",
00376       caller->id.name.str,
00377       caller->id.number.str);
00378 
00379    if (cwcid) {
00380       p->callwaitcas = 0;
00381    }
00382 
00383    if (p->calls->send_callerid) {
00384       return p->calls->send_callerid(p->chan_pvt, cwcid, caller);
00385    }
00386    return 0;
00387 }

static void analog_set_alarm ( struct analog_pvt p,
int  in_alarm 
) [static]

Definition at line 918 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::inalarm, and analog_callback::set_alarm.

Referenced by __analog_handle_event(), __analog_ss_thread(), and analog_handle_init_event().

00919 {
00920    p->inalarm = in_alarm;
00921    if (p->calls->set_alarm) {
00922       return p->calls->set_alarm(p->chan_pvt, in_alarm);
00923    }
00924 }

static void analog_set_cadence ( struct analog_pvt p,
struct ast_channel chan 
) [static]

Definition at line 903 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::cidrings, and analog_callback::set_cadence.

Referenced by analog_call().

00904 {
00905    if (p->calls->set_cadence) {
00906       return p->calls->set_cadence(p->chan_pvt, &p->cidrings, chan);
00907    }
00908 }

static void analog_set_callwaiting ( struct analog_pvt p,
int  callwaiting_enable 
) [static]

Definition at line 895 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::callwaiting, analog_pvt::chan_pvt, and analog_callback::set_callwaiting.

Referenced by __analog_ss_thread(), analog_config_complete(), and analog_hangup().

00896 {
00897    p->callwaiting = callwaiting_enable;
00898    if (p->calls->set_callwaiting) {
00899       p->calls->set_callwaiting(p->chan_pvt, callwaiting_enable);
00900    }
00901 }

static void analog_set_confirmanswer ( struct analog_pvt p,
int  flag 
) [static]

Definition at line 951 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_confirmanswer.

Referenced by analog_handle_dtmf(), and analog_hangup().

00952 {
00953    if (!p->calls->set_confirmanswer) {
00954       return;
00955    }
00956    p->calls->set_confirmanswer(p->chan_pvt, flag);
00957 }

static void analog_set_dialing ( struct analog_pvt p,
int  is_dialing 
) [static]

Definition at line 910 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::dialing, and analog_callback::set_dialing.

Referenced by __analog_handle_event(), analog_answer(), analog_call(), analog_exception(), and analog_hangup().

00911 {
00912    p->dialing = is_dialing;
00913    if (p->calls->set_dialing) {
00914       return p->calls->set_dialing(p->chan_pvt, is_dialing);
00915    }
00916 }

static int analog_set_echocanceller ( struct analog_pvt p,
int  enable 
) [static]

Definition at line 455 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_echocanceller.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_exception(), analog_handle_init_event(), and analog_hangup().

00456 {
00457    if (p->calls->set_echocanceller) {
00458       return p->calls->set_echocanceller(p->chan_pvt, enable);
00459    }
00460    return -1;
00461 }

static void analog_set_inthreeway ( struct analog_pvt p,
enum analog_sub  sub,
int  inthreeway 
) [static]

Definition at line 1002 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_subchannel::inthreeway, analog_callback::set_inthreeway, and analog_pvt::subs.

Referenced by __analog_handle_event(), and analog_hangup().

01003 {
01004    p->subs[sub].inthreeway = inthreeway;
01005    if (p->calls->set_inthreeway) {
01006       p->calls->set_inthreeway(p->chan_pvt, sub, inthreeway);
01007    }
01008 }

static int analog_set_linear_mode ( struct analog_pvt p,
enum analog_sub  sub,
int  linear_mode 
) [static]

Definition at line 993 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_linear_mode.

Referenced by __analog_ss_thread(), and analog_hangup().

00994 {
00995    if (p->calls->set_linear_mode) {
00996       /* Return provides old linear_mode setting or error indication */
00997       return p->calls->set_linear_mode(p->chan_pvt, sub, linear_mode);
00998    }
00999    return -1;
01000 }

static void analog_set_needringing ( struct analog_pvt p,
int  value 
) [static]

Definition at line 600 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_needringing.

Referenced by __analog_handle_event().

00601 {
00602    if (p->calls->set_needringing) {
00603       return p->calls->set_needringing(p->chan_pvt, value);
00604    }
00605 }

static void analog_set_new_owner ( struct analog_pvt p,
struct ast_channel new_owner 
) [static]
static void analog_set_outgoing ( struct analog_pvt p,
int  is_outgoing 
) [static]

Definition at line 519 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::outgoing, and analog_callback::set_outgoing.

Referenced by analog_call(), analog_hangup(), and analog_request().

00520 {
00521    p->outgoing = is_outgoing;
00522    if (p->calls->set_outgoing) {
00523       p->calls->set_outgoing(p->chan_pvt, is_outgoing);
00524    }
00525 }

static void analog_set_pulsedial ( struct analog_pvt p,
int  flag 
) [static]

Definition at line 985 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_pulsedial.

Referenced by __analog_handle_event(), and analog_hangup().

00986 {
00987    if (!p->calls->set_pulsedial) {
00988       return;
00989    }
00990    p->calls->set_pulsedial(p->chan_pvt, flag);
00991 }

static void analog_set_ringtimeout ( struct analog_pvt p,
int  ringt 
) [static]

Definition at line 926 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::ringt, and analog_callback::set_ringtimeout.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_handle_init_event(), and analog_hangup().

00927 {
00928    p->ringt = ringt;
00929    if (!p->calls->set_ringtimeout) {
00930       return;
00931    }
00932    p->calls->set_ringtimeout(p->chan_pvt, ringt);
00933 }

static void analog_set_waitingfordt ( struct analog_pvt p,
struct ast_channel ast 
) [static]

Definition at line 935 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::set_waitingfordt.

Referenced by analog_call().

00936 {
00937    if (p->calls->set_waitingfordt) {
00938       return p->calls->set_waitingfordt(p->chan_pvt, ast);
00939    }
00940 }

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 120 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

00121 {
00122    int i;
00123 
00124    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00125       if (sigtype == sigtypes[i].sigtype) {
00126          return sigtypes[i].name;
00127       }
00128    }
00129 
00130    return "Unknown";
00131 }

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel chan 
)

Definition at line 2651 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02652 {
02653    pthread_t threadid;
02654 
02655    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02656 }

static int analog_start ( struct analog_pvt p  )  [static]

Definition at line 495 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start.

Referenced by analog_call().

00496 {
00497    if (p->calls->start) {
00498       return p->calls->start(p->chan_pvt);
00499    }
00500    return -1;
00501 }

static int analog_start_cid_detect ( struct analog_pvt p,
int  cid_signalling 
) [static]

Definition at line 159 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start_cid_detect.

Referenced by __analog_ss_thread().

00160 {
00161    if (p->calls->start_cid_detect) {
00162       return p->calls->start_cid_detect(p->chan_pvt, cid_signalling);
00163    }
00164    return -1;
00165 }

static void analog_start_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 616 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::start_polarityswitch.

Referenced by __analog_handle_event(), and analog_handle_init_event().

00617 {
00618    if (p->calls->start_polarityswitch) {
00619       return p->calls->start_polarityswitch(p->chan_pvt);
00620    }
00621 }

static int analog_stop_callwait ( struct analog_pvt p  )  [static]

Definition at line 877 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::callwaitcas, analog_pvt::chan_pvt, and analog_callback::stop_callwait.

Referenced by __analog_handle_event(), analog_exception(), and analog_hangup().

00878 {
00879    p->callwaitcas = 0;
00880    if (p->calls->stop_callwait) {
00881       return p->calls->stop_callwait(p->chan_pvt);
00882    }
00883    return 0;
00884 }

static int analog_stop_cid_detect ( struct analog_pvt p  )  [static]

Definition at line 167 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::stop_cid_detect.

Referenced by __analog_ss_thread().

00168 {
00169    if (p->calls->stop_cid_detect) {
00170       return p->calls->stop_cid_detect(p->chan_pvt);
00171    }
00172    return -1;
00173 }

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 216 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

00217 {
00218    if (!strcasecmp(value, "ring")) {
00219       return ANALOG_CID_START_RING;
00220    } else if (!strcasecmp(value, "polarity")) {
00221       return ANALOG_CID_START_POLARITY;
00222    } else if (!strcasecmp(value, "polarity_in")) {
00223       return ANALOG_CID_START_POLARITY_IN;
00224    } else if (!strcasecmp(value, "dtmf")) {
00225       return ANALOG_CID_START_DTMF_NOALERT;
00226    }
00227 
00228    return 0;
00229 }

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 133 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00134 {
00135    int i;
00136 
00137    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00138       if (!strcasecmp(cidtypes[i].name, name)) {
00139          return cidtypes[i].cid_type;
00140       }
00141    }
00142 
00143    return 0;
00144 }

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 107 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

00108 {
00109    int i;
00110 
00111    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00112       if (!strcasecmp(sigtypes[i].name, name)) {
00113          return sigtypes[i].sigtype;
00114       }
00115    }
00116 
00117    return 0;
00118 }

static void analog_swap_subs ( struct analog_pvt p,
enum analog_sub  a,
enum analog_sub  b 
) [static]

Definition at line 330 of file sig_analog.c.

References ast_debug, analog_pvt::calls, analog_pvt::chan_pvt, analog_subchannel::inthreeway, analog_subchannel::owner, analog_pvt::subs, and analog_callback::swap_subs.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_answer(), analog_attempt_transfer(), and analog_hangup().

00331 {
00332    int tinthreeway;
00333    struct ast_channel *towner;
00334 
00335    ast_debug(1, "Swapping %d and %d\n", a, b);
00336 
00337    towner = p->subs[a].owner;
00338    p->subs[a].owner = p->subs[b].owner;
00339    p->subs[b].owner = towner;
00340 
00341    tinthreeway = p->subs[a].inthreeway;
00342    p->subs[a].inthreeway = p->subs[b].inthreeway;
00343    p->subs[b].inthreeway = tinthreeway;
00344 
00345    if (p->calls->swap_subs) {
00346       p->calls->swap_subs(p->chan_pvt, a, p->subs[a].owner, b, p->subs[b].owner);
00347    }
00348 }

static int analog_train_echocanceller ( struct analog_pvt p  )  [static]

Definition at line 463 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::train_echocanceller.

Referenced by __analog_handle_event(), and analog_answer().

00464 {
00465    if (p->calls->train_echocanceller) {
00466       return p->calls->train_echocanceller(p->chan_pvt);
00467    }
00468    return -1;
00469 }

static int analog_unalloc_sub ( struct analog_pvt p,
enum analog_sub  x 
) [static]

Definition at line 363 of file sig_analog.c.

References analog_subchannel::allocd, analog_pvt::calls, analog_pvt::chan_pvt, analog_subchannel::owner, analog_pvt::subs, and analog_callback::unallocate_sub.

Referenced by __analog_handle_event(), __analog_ss_thread(), analog_attempt_transfer(), and analog_hangup().

00364 {
00365    p->subs[x].allocd = 0;
00366    p->subs[x].owner = NULL;
00367    if (p->calls->unallocate_sub) {
00368       return p->calls->unallocate_sub(p->chan_pvt, x);
00369    }
00370    return 0;
00371 }

static void analog_unlock_private ( struct analog_pvt p  )  [static]

Definition at line 542 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::unlock_private.

Referenced by __analog_handle_event(), and analog_exception().

00543 {
00544    if (p->calls->unlock_private) {
00545       p->calls->unlock_private(p->chan_pvt);
00546    }
00547 }

static int analog_update_conf ( struct analog_pvt p  )  [static]

Definition at line 763 of file sig_analog.c.

References analog_subchannel::allocd, ast_debug, analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::channel, analog_callback::complete_conference_update, analog_callback::conf_add, analog_callback::conf_del, analog_subchannel::inthreeway, and analog_pvt::subs.

Referenced by __analog_handle_event(), analog_exception(), analog_fixup(), and analog_hangup().

00764 {
00765    int x;
00766    int needconf = 0;
00767 
00768    /* Start with the obvious, general stuff */
00769    for (x = 0; x < 3; x++) {
00770       /* Look for three way calls */
00771       if ((p->subs[x].allocd) && p->subs[x].inthreeway) {
00772          if (p->calls->conf_add) {
00773             p->calls->conf_add(p->chan_pvt, x);
00774          }
00775          needconf++;
00776       } else {
00777          if (p->calls->conf_del) {
00778             p->calls->conf_del(p->chan_pvt, x);
00779          }
00780       }
00781    }
00782    ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
00783 
00784    if (p->calls->complete_conference_update) {
00785       p->calls->complete_conference_update(p->chan_pvt, needconf);
00786    }
00787    return 0;
00788 }

static int analog_wait_event ( struct analog_pvt p  )  [static]

Definition at line 199 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::wait_event.

Referenced by __analog_ss_thread().

00200 {
00201    if (p->calls->wait_event) {
00202       return p->calls->wait_event(p->chan_pvt);
00203    }
00204    return -1;
00205 }

static int analog_wink ( struct analog_pvt p,
enum analog_sub  index 
) [static]

Definition at line 651 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::wink.

Referenced by __analog_ss_thread().

00652 {
00653    if (p->calls->wink) {
00654       return p->calls->wink(p->chan_pvt, index);
00655    }
00656    return -1;
00657 }


Variable Documentation

char analog_defaultcic[64] = "" [static]

Definition at line 62 of file sig_analog.c.

Referenced by analog_call().

char analog_defaultozz[64] = "" [static]

Definition at line 63 of file sig_analog.c.

Referenced by analog_call().

int analog_firstdigittimeout = 16000 [static]

Definition at line 61 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_gendigittimeout = 8000 [static]

Definition at line 60 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_matchdigittimeout = 3000 [static]

Definition at line 59 of file sig_analog.c.

Referenced by __analog_ss_thread().

unsigned int cid_type

Definition at line 93 of file sig_analog.c.

struct { ... } cidtypes[] [static]
const char const* name

Definition at line 67 of file sig_analog.c.

Definition at line 66 of file sig_analog.c.

struct { ... } sigtypes[] [static]

Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1