Wed Aug 7 17:16:13 2019

Asterisk developer's documentation


sig_analog.c File Reference

Analog signaling module. More...

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

Go to the source code of this file.

Defines

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

Functions

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

Variables

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

Detailed Description

Analog signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_analog.c.


Define Documentation

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

Definition at line 1710 of file sig_analog.c.

Referenced by __analog_ss_thread().

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

Definition at line 104 of file sig_analog.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 58 of file sig_analog.c.

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

Definition at line 56 of file sig_analog.c.

#define POLARITY_REV   1

Definition at line 57 of file sig_analog.c.


Function Documentation

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

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

< Channel is down and available

< Channel is down, but reserved

< Channel is off hook

< Line is busy

< Digits (or equivalent) have been dialed while offhook

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

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

Definition at line 2651 of file sig_analog.c.

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

Referenced by analog_exception().

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

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

Definition at line 1739 of file sig_analog.c.

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

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

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

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

Definition at line 390 of file sig_analog.c.

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

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

static void analog_all_subchannels_hungup ( struct analog_pvt p  )  [static]

Definition at line 535 of file sig_analog.c.

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

Referenced by analog_hangup().

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

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

Definition at line 350 of file sig_analog.c.

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

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

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

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1486 of file sig_analog.c.

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

Referenced by dahdi_answer().

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

static void analog_answer_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 622 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_answer().

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

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

Definition at line 688 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

int analog_available ( struct analog_pvt p  ) 

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

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

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

Definition at line 1003 of file sig_analog.c.

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

Referenced by dahdi_call().

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

static int analog_callwait ( struct analog_pvt p  )  [static]

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

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

static void analog_cancel_cidspill ( struct analog_pvt p  )  [static]

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

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

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

Definition at line 1712 of file sig_analog.c.

References ast_pickup_ext(), and pickup_ext.

Referenced by __analog_ss_thread().

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

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

Definition at line 644 of file sig_analog.c.

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

Referenced by analog_handle_dtmf().

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

static int analog_check_confirmanswer ( struct analog_pvt p  )  [static]

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

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

static int analog_check_for_conference ( struct analog_pvt p  )  [static]

Definition at line 527 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_check_waitingfordt ( struct analog_pvt p  )  [static]

Definition at line 935 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

Definition at line 231 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

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

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 146 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

int analog_config_complete ( struct analog_pvt p  ) 

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

03920 {
03921    /* No call waiting on non FXS channels */
03922    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03923       p->permcallwaiting = 0;
03924    }
03925 
03926    analog_set_callwaiting(p, p->permcallwaiting);
03927 
03928    return 0;
03929 }

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

Definition at line 970 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_decrease_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1669 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

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

References ast_free.

Referenced by destroy_dahdi_pvt().

03915 {
03916    ast_free(doomed);
03917 }

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

Definition at line 503 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_call().

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

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

Definition at line 1678 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

int analog_dnd ( struct analog_pvt p,
int  flag 
)

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

03956 {
03957    if (flag == -1) {
03958       return p->dnd;
03959    }
03960 
03961    p->dnd = flag;
03962 
03963    ast_verb(3, "%s DND on channel %d\n",
03964          flag ? "Enabled" : "Disabled",
03965          p->channel);
03966    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03967          "Channel: DAHDI/%d\r\n"
03968          "Status: %s\r\n", p->channel,
03969          flag ? "enabled" : "disabled");
03970 
03971    return 0;
03972 }

static int analog_dsp_reset_and_flush_digits ( struct analog_pvt p  )  [static]

Definition at line 410 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

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

Definition at line 636 of file sig_analog.c.

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

Referenced by __analog_ss_thread(), and analog_hangup().

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

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

Definition at line 247 of file sig_analog.c.

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

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

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

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

Definition at line 3515 of file sig_analog.c.

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

Referenced by dahdi_exception(), and dahdi_read().

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

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

Definition at line 3937 of file sig_analog.c.

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

Referenced by dahdi_fixup().

03938 {
03939    struct analog_pvt *new_pvt = newp;
03940    int x;
03941    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03942    if (new_pvt->owner == oldchan) {
03943       analog_set_new_owner(new_pvt, newchan);
03944    }
03945    for (x = 0; x < 3; x++) {
03946       if (new_pvt->subs[x].owner == oldchan) {
03947          new_pvt->subs[x].owner = newchan;
03948       }
03949    }
03950 
03951    analog_update_conf(new_pvt);
03952    return 0;
03953 }

static int analog_flash ( struct analog_pvt p  )  [static]

Definition at line 487 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

void analog_free ( struct analog_pvt p  ) 

Definition at line 3931 of file sig_analog.c.

References ast_free.

03932 {
03933    ast_free(p);
03934 }

static void analog_get_and_handle_alarms ( struct analog_pvt p  )  [static]

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

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

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

Definition at line 1694 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01695 {
01696    if (p->calls->get_sigpvt_bridged_channel) {
01697       return p->calls->get_sigpvt_bridged_channel(chan);
01698    }
01699    return NULL;
01700 }

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

Definition at line 175 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

static int analog_get_event ( struct analog_pvt p  )  [static]

Definition at line 191 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_exception().

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

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

Definition at line 183 of file sig_analog.c.

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

Referenced by analog_call().

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

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

Definition at line 1702 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

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

Definition at line 1589 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and dahdi_read().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

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

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

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

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

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

static int analog_handles_digit ( struct ast_frame f  )  [static]

Definition at line 1564 of file sig_analog.c.

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

Referenced by analog_handle_dtmf().

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1270 of file sig_analog.c.

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

Referenced by dahdi_hangup().

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

static void analog_hangup_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 629 of file sig_analog.c.

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

Referenced by analog_hangup().

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

static int analog_has_voicemail ( struct analog_pvt p  )  [static]

Definition at line 659 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_init_event().

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

static int analog_have_progressdetect ( struct analog_pvt p  )  [static]

Definition at line 207 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_increase_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1660 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

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

Definition at line 667 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_is_off_hook ( struct analog_pvt p  )  [static]

Definition at line 471 of file sig_analog.c.

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

Referenced by analog_available(), and analog_hangup().

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

static void analog_lock_private ( struct analog_pvt p  )  [static]

Definition at line 549 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_exception().

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

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

Definition at line 571 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_hangup().

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

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

Definition at line 1631 of file sig_analog.c.

References ast_waitfordigit().

Referenced by __analog_ss_thread().

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

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

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

03884 {
03885    struct analog_pvt *p;
03886 
03887    p = ast_calloc(1, sizeof(*p));
03888    if (!p) {
03889       return p;
03890    }
03891 
03892    p->calls = c;
03893    p->outsigmod = ANALOG_SIG_NONE;
03894    p->sig = signallingtype;
03895    p->chan_pvt = private_data;
03896 
03897    /* Some defaults for values */
03898    p->cid_start = ANALOG_CID_START_RING;
03899    p->cid_signalling = CID_SIG_BELL;
03900    /* Sub real is assumed to always be alloc'd */
03901    p->subs[ANALOG_SUB_REAL].allocd = 1;
03902 
03903    return p;
03904 }

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

Definition at line 436 of file sig_analog.c.

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

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

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

static int analog_off_hook ( struct analog_pvt p  )  [static]

Definition at line 592 of file sig_analog.c.

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

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

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

static int analog_on_hook ( struct analog_pvt p  )  [static]

Definition at line 511 of file sig_analog.c.

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

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

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

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

Definition at line 420 of file sig_analog.c.

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

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

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

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

Definition at line 783 of file sig_analog.c.

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

Referenced by dahdi_request().

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

static int analog_ring ( struct analog_pvt p  )  [static]

Definition at line 479 of file sig_analog.c.

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

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

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

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

Definition at line 373 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_dtmf().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 455 of file sig_analog.c.

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

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

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

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

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

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

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

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

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

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

Definition at line 600 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

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

Definition at line 519 of file sig_analog.c.

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

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

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

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

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

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

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

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

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

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

Definition at line 928 of file sig_analog.c.

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

Referenced by analog_call().

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

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 120 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

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

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel chan 
)

Definition at line 2644 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02645 {
02646    pthread_t threadid;
02647 
02648    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02649 }

static int analog_start ( struct analog_pvt p  )  [static]

Definition at line 495 of file sig_analog.c.

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

Referenced by analog_call().

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

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

Definition at line 159 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

static void analog_start_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 616 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_init_event().

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

static int analog_stop_callwait ( struct analog_pvt p  )  [static]

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

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

static int analog_stop_cid_detect ( struct analog_pvt p  )  [static]

Definition at line 167 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 216 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

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

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 133 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 107 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

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

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

Definition at line 330 of file sig_analog.c.

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

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

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

static int analog_train_echocanceller ( struct analog_pvt p  )  [static]

Definition at line 463 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_answer().

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

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

Definition at line 363 of file sig_analog.c.

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

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

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

static void analog_unlock_private ( struct analog_pvt p  )  [static]

Definition at line 542 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_exception().

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

static int analog_update_conf ( struct analog_pvt p  )  [static]

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

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

static int analog_wait_event ( struct analog_pvt p  )  [static]

Definition at line 199 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

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

Definition at line 651 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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


Variable Documentation

char analog_defaultcic[64] = "" [static]

Definition at line 62 of file sig_analog.c.

Referenced by analog_call().

char analog_defaultozz[64] = "" [static]

Definition at line 63 of file sig_analog.c.

Referenced by analog_call().

int analog_firstdigittimeout = 16000 [static]

Definition at line 61 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_gendigittimeout = 8000 [static]

Definition at line 60 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_matchdigittimeout = 3000 [static]

Definition at line 59 of file sig_analog.c.

Referenced by __analog_ss_thread().

unsigned int cid_type

Definition at line 93 of file sig_analog.c.

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

Definition at line 67 of file sig_analog.c.

Definition at line 66 of file sig_analog.c.

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

Generated on 7 Aug 2019 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1