Sat Feb 11 06:36:45 2012

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"

Include dependency graph for sig_analog.c:

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, const 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 void analog_deadlock_avoidance_private (struct analog_pvt *p)
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_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 1712 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 100 of file sig_analog.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 54 of file sig_analog.c.

#define POLARITY_IDLE   0

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 52 of file sig_analog.c.

#define POLARITY_REV   1

Definition at line 53 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 2645 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_sub_owner(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_alarm(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_needringing(), analog_set_new_owner(), analog_set_pulsedial(), analog_set_ringtimeout(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_start_polarityswitch(), analog_stop_callwait(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_STUTTER, analog_train_echocanceller(), analog_unalloc_sub(), analog_update_conf(), ast_party_caller::ani, ast_party_caller::ani2, analog_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CAUSE_NO_ANSWER, ast_channel_name(), 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().

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

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

Definition at line 1741 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_channel_language(), ast_channel_name(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_copy_string(), ast_db_put(), ast_debug, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), ast_log(), ast_masq_park_call_exten(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext_valid(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_destroy(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), ASTOBJ_UNREF, analog_pvt::call_forward, ast_channel::caller, callerid_free(), callerid_get_dtmf(), ast_smdi_md_message::calling_st, analog_pvt::callreturn, analog_pvt::callwaiting, analog_pvt::cancallforward, analog_pvt::canpark, analog_pvt::chan_tech, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, analog_pvt::cid_signalling, analog_pvt::cid_start, ast_channel::context, analog_dialoperation::dialstr, analog_pvt::dop, errno, ast_channel::exten, exten, f, callerid_state::flags, ast_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, strsep(), ast_frame::subclass, analog_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, analog_pvt::transfer, ast_smdi_md_message::type, analog_pvt::use_callerid, analog_pvt::use_smdi, and ast_party_number::valid.

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

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

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 386 of file sig_analog.c.

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

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

static void analog_all_subchannels_hungup ( struct analog_pvt p  )  [static]

Definition at line 523 of file sig_analog.c.

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

Referenced by analog_hangup().

00524 {
00525    if (p->calls->all_subchannels_hungup) {
00526       p->calls->all_subchannels_hungup(p->chan_pvt);
00527    }
00528 }

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

Definition at line 346 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().

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

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1488 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_channel_name(), 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().

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

static void analog_answer_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 617 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().

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

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

Definition at line 685 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_linkedid(), ast_channel_name(), 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().

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

int analog_available ( struct analog_pvt p  ) 

Definition at line 808 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().

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

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

Definition at line 1005 of file sig_analog.c.

References ast_channel::_state, analog_callwait(), analog_defaultcic, analog_defaultozz, analog_dial_digits(), ANALOG_DIAL_OP_REPLACE, analog_get_index, analog_get_orig_dialstring(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_set_cadence(), analog_set_dialing(), analog_set_waitingfordt(), ANALOG_SIG_E911, ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATB, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, analog_start(), ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE, analog_pvt::answeronpolarityswitch, AST_CC_CCNR, AST_CC_GENERIC_MONITOR_TYPE, AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_cc_config_params(), ast_channel_name(), 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::outgoing, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, pbx_builtin_getvar_helper(), analog_pvt::polaritydelaytv, analog_pvt::pulse, S_COR, analog_pvt::sig, ast_party_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().

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

static int analog_callwait ( struct analog_pvt p  )  [static]

Definition at line 881 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().

00882 {
00883    p->callwaitcas = p->callwaitingcallerid;
00884    if (p->calls->callwait) {
00885       return p->calls->callwait(p->chan_pvt);
00886    }
00887    return 0;
00888 }

static void analog_cancel_cidspill ( struct analog_pvt p  )  [static]

Definition at line 963 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().

00964 {
00965    if (!p->calls->cancel_cidspill) {
00966       return;
00967    }
00968 
00969    p->calls->cancel_cidspill(p->chan_pvt);
00970 }

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

Definition at line 1714 of file sig_analog.c.

References ast_pickup_ext(), and pickup_ext.

Referenced by __analog_ss_thread().

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

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 639 of file sig_analog.c.

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

Referenced by analog_handle_dtmf().

00640 {
00641    if (p->calls->handle_dtmf) {
00642       p->calls->handle_dtmf(p->chan_pvt, ast, analog_index, dest);
00643    }
00644 }

static int analog_check_confirmanswer ( struct analog_pvt p  )  [static]

Definition at line 954 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().

00955 {
00956    if (p->calls->check_confirmanswer) {
00957       return p->calls->check_confirmanswer(p->chan_pvt);
00958    }
00959 
00960    return 0;
00961 }

static int analog_check_for_conference ( struct analog_pvt p  )  [static]

Definition at line 515 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00516 {
00517    if (p->calls->check_for_conference) {
00518       return p->calls->check_for_conference(p->chan_pvt);
00519    }
00520    return -1;
00521 }

static int analog_check_waitingfordt ( struct analog_pvt p  )  [static]

Definition at line 937 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00938 {
00939    if (p->calls->check_waitingfordt) {
00940       return p->calls->check_waitingfordt(p->chan_pvt);
00941    }
00942 
00943    return 0;
00944 }

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

Definition at line 227 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.

00228 {
00229    switch (cid_start) {
00230    case ANALOG_CID_START_RING:
00231       return "Ring";
00232    case ANALOG_CID_START_POLARITY:
00233       return "Polarity";
00234    case ANALOG_CID_START_POLARITY_IN:
00235       return "Polarity_In";
00236    case ANALOG_CID_START_DTMF_NOALERT:
00237       return "DTMF";
00238    }
00239 
00240    return "Unknown";
00241 }

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 142 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00143 {
00144    int i;
00145 
00146    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00147       if (cid_type == cidtypes[i].cid_type) {
00148          return cidtypes[i].name;
00149       }
00150    }
00151 
00152    return "Unknown";
00153 }

int analog_config_complete ( struct analog_pvt p  ) 

Definition at line 3889 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().

03890 {
03891    /* No call waiting on non FXS channels */
03892    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03893       p->permcallwaiting = 0;
03894    }
03895 
03896    analog_set_callwaiting(p, p->permcallwaiting);
03897 
03898    return 0;
03899 }

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

Definition at line 972 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00973 {
00974    if (p->calls->confmute) {
00975       return p->calls->confmute(p->chan_pvt, mute);
00976    }
00977    return 0;
00978 }

static void analog_deadlock_avoidance_private ( struct analog_pvt p  )  [static]

Definition at line 544 of file sig_analog.c.

References analog_lock_private(), analog_unlock_private(), analog_pvt::calls, analog_pvt::chan_pvt, and analog_callback::deadlock_avoidance_private.

Referenced by analog_lock_sub_owner().

00545 {
00546    if (p->calls->deadlock_avoidance_private) {
00547       p->calls->deadlock_avoidance_private(p->chan_pvt);
00548    } else {
00549       /* Fallback to manual avoidance if callback not present. */
00550       analog_unlock_private(p);
00551       usleep(1);
00552       analog_lock_private(p);
00553    }
00554 }

static int analog_decrease_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1671 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01672 {
01673    if (p->calls->decrease_ss_count) {
01674       p->calls->decrease_ss_count();
01675       return 0;
01676    }
01677    return -1;
01678 }

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 3884 of file sig_analog.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

03885 {
03886    ast_free(doomed);
03887 }

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

Definition at line 499 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().

00500 {
00501    if (p->calls->dial_digits) {
00502       return p->calls->dial_digits(p->chan_pvt, sub, dop);
00503    }
00504    return -1;
00505 }

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

Definition at line 1680 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01681 {
01682    if (p->calls->distinctive_ring) {
01683       return p->calls->distinctive_ring(chan, p->chan_pvt, idx, ringdata);
01684    }
01685    return -1;
01686 
01687 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

Definition at line 3925 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().

03926 {
03927    if (flag == -1) {
03928       return p->dnd;
03929    }
03930 
03931    p->dnd = flag;
03932 
03933    ast_verb(3, "%s DND on channel %d\n",
03934          flag ? "Enabled" : "Disabled",
03935          p->channel);
03936    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03937          "Channel: DAHDI/%d\r\n"
03938          "Status: %s\r\n", p->channel,
03939          flag ? "enabled" : "disabled");
03940 
03941    return 0;
03942 }

static int analog_dsp_reset_and_flush_digits ( struct analog_pvt p  )  [static]

Definition at line 406 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().

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

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

Definition at line 631 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().

00632 {
00633    if (p->calls->dsp_set_digitmode) {
00634       return p->calls->dsp_set_digitmode(p->chan_pvt, mode);
00635    }
00636    return -1;
00637 }

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

Definition at line 243 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().

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

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

Definition at line 3498 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_off_hook(), analog_ring(), analog_set_dialing(), analog_set_echocanceller(), analog_set_new_owner(), analog_stop_callwait(), ANALOG_SUB_REAL, analog_update_conf(), ast_bridged_channel(), ast_channel_name(), AST_CONTROL_ANSWER, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_tv(), ast_verb, analog_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, analog_subchannel::f, f, ast_channel::fds, analog_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::mallocd, 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().

03499 {
03500    int res;
03501    int idx;
03502    struct ast_frame *f;
03503 
03504    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
03505 
03506    idx = analog_get_index(ast, p, 1);
03507    if (idx < 0) {
03508       idx = ANALOG_SUB_REAL;
03509    }
03510 
03511    p->subs[idx].f.frametype = AST_FRAME_NULL;
03512    p->subs[idx].f.datalen = 0;
03513    p->subs[idx].f.samples = 0;
03514    p->subs[idx].f.mallocd = 0;
03515    p->subs[idx].f.offset = 0;
03516    p->subs[idx].f.subclass.integer = 0;
03517    p->subs[idx].f.delivery = ast_tv(0,0);
03518    p->subs[idx].f.src = "dahdi_exception";
03519    p->subs[idx].f.data.ptr = NULL;
03520 
03521    if (!p->owner) {
03522       /* If nobody owns us, absorb the event appropriately, otherwise
03523          we loop indefinitely.  This occurs when, during call waiting, the
03524          other end hangs up our channel so that it no longer exists, but we
03525          have neither FLASH'd nor ONHOOK'd to signify our desire to
03526          change to the other channel. */
03527       res = analog_get_event(p);
03528 
03529       /* Switch to real if there is one and this isn't something really silly... */
03530       if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
03531          (res != ANALOG_EVENT_HOOKCOMPLETE)) {
03532          ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
03533          analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03534          if (p->owner && ast != p->owner) {
03535             /*
03536              * Could this even happen?
03537              * Possible deadlock because we do not have the real-call lock.
03538              */
03539             ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n",
03540                analog_event2str(res), ast_channel_name(ast), ast_channel_name(p->owner));
03541          }
03542          if (p->owner && ast_bridged_channel(p->owner)) {
03543             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03544          }
03545       }
03546       switch (res) {
03547       case ANALOG_EVENT_ONHOOK:
03548          analog_set_echocanceller(p, 0);
03549          if (p->owner) {
03550             ast_verb(3, "Channel %s still has call, ringing phone\n", ast_channel_name(p->owner));
03551             analog_ring(p);
03552             analog_stop_callwait(p);
03553          } else {
03554             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03555                analog_event2str(res));
03556          }
03557          analog_update_conf(p);
03558          break;
03559       case ANALOG_EVENT_RINGOFFHOOK:
03560          analog_set_echocanceller(p, 1);
03561          analog_off_hook(p);
03562          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
03563             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03564             analog_set_dialing(p, 0);
03565          }
03566          break;
03567       case ANALOG_EVENT_HOOKCOMPLETE:
03568       case ANALOG_EVENT_RINGERON:
03569       case ANALOG_EVENT_RINGEROFF:
03570          /* Do nothing */
03571          break;
03572       case ANALOG_EVENT_WINKFLASH:
03573          gettimeofday(&p->flashtime, NULL);
03574          if (p->owner) {
03575             ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, ast_channel_name(p->owner));
03576             if (p->owner->_state != AST_STATE_UP) {
03577                /* Answer if necessary */
03578                ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03579                ast_setstate(p->owner, AST_STATE_UP);
03580             }
03581             analog_stop_callwait(p);
03582             if (ast_bridged_channel(p->owner)) {
03583                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03584             }
03585          } else {
03586             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03587                analog_event2str(res));
03588          }
03589          analog_update_conf(p);
03590          break;
03591       default:
03592          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res));
03593          break;
03594       }
03595       f = &p->subs[idx].f;
03596       return f;
03597    }
03598    ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
03599    /* If it's not us, return NULL immediately */
03600    if (ast != p->owner) {
03601       ast_log(LOG_WARNING, "We're %s, not %s\n", ast_channel_name(ast), ast_channel_name(p->owner));
03602       f = &p->subs[idx].f;
03603       return f;
03604    }
03605    f = __analog_handle_event(p, ast);
03606    return f;
03607 }

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

Definition at line 3907 of file sig_analog.c.

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

Referenced by dahdi_fixup().

03908 {
03909    struct analog_pvt *new_pvt = newp;
03910    int x;
03911    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, ast_channel_name(newchan));
03912    if (new_pvt->owner == oldchan) {
03913       analog_set_new_owner(new_pvt, newchan);
03914    }
03915    for (x = 0; x < 3; x++) {
03916       if (new_pvt->subs[x].owner == oldchan) {
03917          new_pvt->subs[x].owner = newchan;
03918       }
03919    }
03920 
03921    analog_update_conf(new_pvt);
03922    return 0;
03923 }

static int analog_flash ( struct analog_pvt p  )  [static]

Definition at line 483 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00484 {
00485    if (p->calls->flash) {
00486       return p->calls->flash(p->chan_pvt);
00487    }
00488    return -1;
00489 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3901 of file sig_analog.c.

References ast_free.

03902 {
03903    ast_free(p);
03904 }

static void analog_get_and_handle_alarms ( struct analog_pvt p  )  [static]

Definition at line 1689 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().

01690 {
01691    if (p->calls->get_and_handle_alarms) {
01692       return p->calls->get_and_handle_alarms(p->chan_pvt);
01693    }
01694 }

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

Definition at line 1696 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01697 {
01698    if (p->calls->get_sigpvt_bridged_channel) {
01699       return p->calls->get_sigpvt_bridged_channel;
01700    }
01701    return NULL;
01702 }

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

Definition at line 171 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00172 {
00173    if (p->calls->get_callerid) {
00174       return p->calls->get_callerid(p->chan_pvt, name, number, ev, timeout);
00175    }
00176    return -1;
00177 }

static int analog_get_event ( struct analog_pvt p  )  [static]

Definition at line 187 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_exception().

00188 {
00189    if (p->calls->get_event) {
00190       return p->calls->get_event(p->chan_pvt);
00191    }
00192    return -1;
00193 }

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

Definition at line 179 of file sig_analog.c.

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

Referenced by analog_call().

00180 {
00181    if (p->calls->get_orig_dialstring) {
00182       return p->calls->get_orig_dialstring(p->chan_pvt);
00183    }
00184    return "";
00185 }

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

Definition at line 1704 of file sig_analog.c.

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

Referenced by __analog_handle_event().

01705 {
01706    if (p->calls->get_sub_fd) {
01707       return p->calls->get_sub_fd(p->chan_pvt, sub);
01708    }
01709    return -1;
01710 }

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

Definition at line 1591 of file sig_analog.c.

References analog_cb_handle_dtmf(), analog_check_confirmanswer(), analog_handles_digit(), analog_send_callerid(), analog_set_confirmanswer(), ast_channel_name(), 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().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3609 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().

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

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

Definition at line 1653 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().

01654 {
01655    if (p->calls->handle_notify_message) {
01656       p->calls->handle_notify_message(chan, p->chan_pvt, cid_flags, neon_mwievent);
01657       return 0;
01658    }
01659    return -1;
01660 }

static int analog_handles_digit ( struct ast_frame f  )  [static]

Definition at line 1566 of file sig_analog.c.

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

Referenced by analog_handle_dtmf().

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1272 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_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_name(), 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::outgoing, 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().

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

static void analog_hangup_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 624 of file sig_analog.c.

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

Referenced by analog_hangup().

00625 {
00626    if (p->calls->hangup_polarityswitch) {
00627       return p->calls->hangup_polarityswitch(p->chan_pvt);
00628    }
00629 }

static int analog_has_voicemail ( struct analog_pvt p  )  [static]

Definition at line 654 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().

00655 {
00656    if (p->calls->has_voicemail) {
00657       return p->calls->has_voicemail(p->chan_pvt);
00658    }
00659    return -1;
00660 }

static int analog_have_progressdetect ( struct analog_pvt p  )  [static]

Definition at line 203 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00204 {
00205    if (p->calls->have_progressdetect) {
00206       return p->calls->have_progressdetect(p->chan_pvt);
00207    }
00208    /* Don't have progress detection. */
00209    return 0;
00210 }

static int analog_increase_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1662 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01663 {
01664    if (p->calls->increase_ss_count) {
01665       p->calls->increase_ss_count();
01666       return 0;
01667    }
01668    return -1;
01669 }

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

Definition at line 662 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00663 {
00664    if (p->calls->is_dialing) {
00665       return p->calls->is_dialing(p->chan_pvt, index);
00666    }
00667    return -1;
00668 }

static int analog_is_off_hook ( struct analog_pvt p  )  [static]

Definition at line 467 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().

00468 {
00469    if (p->calls->is_off_hook) {
00470       return p->calls->is_off_hook(p->chan_pvt);
00471    }
00472    return -1;
00473 }

static void analog_lock_private ( struct analog_pvt p  )  [static]

Definition at line 537 of file sig_analog.c.

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

Referenced by analog_deadlock_avoidance_private().

00538 {
00539    if (p->calls->lock_private) {
00540       p->calls->lock_private(p->chan_pvt);
00541    }
00542 }

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 analog_deadlock_avoidance_private(), ast_channel_trylock, analog_subchannel::owner, and analog_pvt::subs.

Referenced by __analog_handle_event(), and analog_hangup().

00572 {
00573    for (;;) {
00574       if (!pvt->subs[sub_idx].owner) {
00575          /* No subchannel owner pointer */
00576          break;
00577       }
00578       if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
00579          /* Got subchannel owner lock */
00580          break;
00581       }
00582       /* We must unlock the private to avoid the possibility of a deadlock */
00583       analog_deadlock_avoidance_private(pvt);
00584    }
00585 }

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

Definition at line 1633 of file sig_analog.c.

References ast_waitfordigit().

Referenced by __analog_ss_thread().

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

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

Definition at line 3853 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().

03854 {
03855    struct analog_pvt *p;
03856 
03857    p = ast_calloc(1, sizeof(*p));
03858    if (!p) {
03859       return p;
03860    }
03861 
03862    p->calls = c;
03863    p->outsigmod = ANALOG_SIG_NONE;
03864    p->sig = signallingtype;
03865    p->chan_pvt = private_data;
03866 
03867    /* Some defaults for values */
03868    p->cid_start = ANALOG_CID_START_RING;
03869    p->cid_signalling = CID_SIG_BELL;
03870    /* Sub real is assumed to always be alloc'd */
03871    p->subs[ANALOG_SUB_REAL].allocd = 1;
03872 
03873    return p;
03874 }

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 432 of file sig_analog.c.

References analog_set_new_owner(), 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().

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

static int analog_off_hook ( struct analog_pvt p  )  [static]

Definition at line 587 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().

00588 {
00589    if (p->calls->off_hook) {
00590       return p->calls->off_hook(p->chan_pvt);
00591    }
00592    return -1;
00593 }

static int analog_on_hook ( struct analog_pvt p  )  [static]

Definition at line 507 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().

00508 {
00509    if (p->calls->on_hook) {
00510       return p->calls->on_hook(p->chan_pvt);
00511    }
00512    return -1;
00513 }

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

Definition at line 416 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().

00417 {
00418    if (p->calls->play_tone) {
00419       return p->calls->play_tone(p->chan_pvt, sub, tone);
00420    }
00421    return -1;
00422 }

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

Definition at line 785 of file sig_analog.c.

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

Referenced by dahdi_request().

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

static int analog_ring ( struct analog_pvt p  )  [static]

Definition at line 475 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().

00476 {
00477    if (p->calls->ring) {
00478       return p->calls->ring(p->chan_pvt);
00479    }
00480    return -1;
00481 }

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

Definition at line 369 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().

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

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

Definition at line 913 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().

00914 {
00915    p->inalarm = in_alarm;
00916    if (p->calls->set_alarm) {
00917       return p->calls->set_alarm(p->chan_pvt, in_alarm);
00918    }
00919 }

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

Definition at line 898 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().

00899 {
00900    if (p->calls->set_cadence) {
00901       return p->calls->set_cadence(p->chan_pvt, &p->cidrings, chan);
00902    }
00903 }

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

Definition at line 890 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().

00891 {
00892    p->callwaiting = callwaiting_enable;
00893    if (p->calls->set_callwaiting) {
00894       p->calls->set_callwaiting(p->chan_pvt, callwaiting_enable);
00895    }
00896 }

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

Definition at line 946 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().

00947 {
00948    if (!p->calls->set_confirmanswer) {
00949       return;
00950    }
00951    p->calls->set_confirmanswer(p->chan_pvt, flag);
00952 }

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

Definition at line 905 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().

00906 {
00907    p->dialing = is_dialing;
00908    if (p->calls->set_dialing) {
00909       return p->calls->set_dialing(p->chan_pvt, is_dialing);
00910    }
00911 }

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

Definition at line 451 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().

00452 {
00453    if (p->calls->set_echocanceller) {
00454       return p->calls->set_echocanceller(p->chan_pvt, enable);
00455    }
00456    return -1;
00457 }

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

Definition at line 997 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().

00998 {
00999    p->subs[sub].inthreeway = inthreeway;
01000    if (p->calls->set_inthreeway) {
01001       p->calls->set_inthreeway(p->chan_pvt, sub, inthreeway);
01002    }
01003 }

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

Definition at line 988 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().

00989 {
00990    if (p->calls->set_linear_mode) {
00991       /* Return provides old linear_mode setting or error indication */
00992       return p->calls->set_linear_mode(p->chan_pvt, sub, linear_mode);
00993    }
00994    return -1;
00995 }

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

Definition at line 595 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00596 {
00597    if (p->calls->set_needringing) {
00598       return p->calls->set_needringing(p->chan_pvt, value);
00599    }
00600 }

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

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

Definition at line 980 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().

00981 {
00982    if (!p->calls->set_pulsedial) {
00983       return;
00984    }
00985    p->calls->set_pulsedial(p->chan_pvt, flag);
00986 }

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

Definition at line 921 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().

00922 {
00923    p->ringt = ringt;
00924    if (!p->calls->set_ringtimeout) {
00925       return;
00926    }
00927    p->calls->set_ringtimeout(p->chan_pvt, ringt);
00928 }

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

Definition at line 930 of file sig_analog.c.

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

Referenced by analog_call().

00931 {
00932    if (p->calls->set_waitingfordt) {
00933       return p->calls->set_waitingfordt(p->chan_pvt, ast);
00934    }
00935 }

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 116 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

00117 {
00118    int i;
00119 
00120    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00121       if (sigtype == sigtypes[i].sigtype) {
00122          return sigtypes[i].name;
00123       }
00124    }
00125 
00126    return "Unknown";
00127 }

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel chan 
)

Definition at line 2638 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02639 {
02640    pthread_t threadid;
02641 
02642    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02643 }

static int analog_start ( struct analog_pvt p  )  [static]

Definition at line 491 of file sig_analog.c.

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

Referenced by analog_call().

00492 {
00493    if (p->calls->start) {
00494       return p->calls->start(p->chan_pvt);
00495    }
00496    return -1;
00497 }

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

Definition at line 155 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00156 {
00157    if (p->calls->start_cid_detect) {
00158       return p->calls->start_cid_detect(p->chan_pvt, cid_signalling);
00159    }
00160    return -1;
00161 }

static void analog_start_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 611 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().

00612 {
00613    if (p->calls->start_polarityswitch) {
00614       return p->calls->start_polarityswitch(p->chan_pvt);
00615    }
00616 }

static int analog_stop_callwait ( struct analog_pvt p  )  [static]

Definition at line 872 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().

00873 {
00874    p->callwaitcas = 0;
00875    if (p->calls->stop_callwait) {
00876       return p->calls->stop_callwait(p->chan_pvt);
00877    }
00878    return 0;
00879 }

static int analog_stop_cid_detect ( struct analog_pvt p  )  [static]

Definition at line 163 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00164 {
00165    if (p->calls->stop_cid_detect) {
00166       return p->calls->stop_cid_detect(p->chan_pvt);
00167    }
00168    return -1;
00169 }

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 212 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.

00213 {
00214    if (!strcasecmp(value, "ring")) {
00215       return ANALOG_CID_START_RING;
00216    } else if (!strcasecmp(value, "polarity")) {
00217       return ANALOG_CID_START_POLARITY;
00218    } else if (!strcasecmp(value, "polarity_in")) {
00219       return ANALOG_CID_START_POLARITY_IN;
00220    } else if (!strcasecmp(value, "dtmf")) {
00221       return ANALOG_CID_START_DTMF_NOALERT;
00222    }
00223 
00224    return 0;
00225 }

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 129 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00130 {
00131    int i;
00132 
00133    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00134       if (!strcasecmp(cidtypes[i].name, name)) {
00135          return cidtypes[i].cid_type;
00136       }
00137    }
00138 
00139    return 0;
00140 }

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 103 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

00104 {
00105    int i;
00106 
00107    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00108       if (!strcasecmp(sigtypes[i].name, name)) {
00109          return sigtypes[i].sigtype;
00110       }
00111    }
00112 
00113    return 0;
00114 }

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

Definition at line 326 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().

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

static int analog_train_echocanceller ( struct analog_pvt p  )  [static]

Definition at line 459 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().

00460 {
00461    if (p->calls->train_echocanceller) {
00462       return p->calls->train_echocanceller(p->chan_pvt);
00463    }
00464    return -1;
00465 }

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

Definition at line 359 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().

00360 {
00361    p->subs[x].allocd = 0;
00362    p->subs[x].owner = NULL;
00363    if (p->calls->unallocate_sub) {
00364       return p->calls->unallocate_sub(p->chan_pvt, x);
00365    }
00366    return 0;
00367 }

static void analog_unlock_private ( struct analog_pvt p  )  [static]

Definition at line 530 of file sig_analog.c.

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

Referenced by analog_deadlock_avoidance_private().

00531 {
00532    if (p->calls->unlock_private) {
00533       p->calls->unlock_private(p->chan_pvt);
00534    }
00535 }

static int analog_update_conf ( struct analog_pvt p  )  [static]

Definition at line 758 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().

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

static int analog_wait_event ( struct analog_pvt p  )  [static]

Definition at line 195 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00196 {
00197    if (p->calls->wait_event) {
00198       return p->calls->wait_event(p->chan_pvt);
00199    }
00200    return -1;
00201 }

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

Definition at line 646 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00647 {
00648    if (p->calls->wink) {
00649       return p->calls->wink(p->chan_pvt, index);
00650    }
00651    return -1;
00652 }


Variable Documentation

char analog_defaultcic[64] = "" [static]

Definition at line 58 of file sig_analog.c.

Referenced by analog_call().

char analog_defaultozz[64] = "" [static]

Definition at line 59 of file sig_analog.c.

Referenced by analog_call().

int analog_firstdigittimeout = 16000 [static]

Definition at line 57 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_gendigittimeout = 8000 [static]

Definition at line 56 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_matchdigittimeout = 3000 [static]

Definition at line 55 of file sig_analog.c.

Referenced by __analog_ss_thread().

unsigned int cid_type

Definition at line 89 of file sig_analog.c.

struct { ... } cidtypes[] [static]

const char const* name

Definition at line 63 of file sig_analog.c.

Definition at line 62 of file sig_analog.c.

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


Generated on Sat Feb 11 06:36:45 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6