Mon Jun 27 16:51:21 2011

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 void analog_cb_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
static int analog_check_confirmanswer (struct analog_pvt *p)
static int analog_check_for_conference (struct analog_pvt *p)
static int analog_check_waitingfordt (struct analog_pvt *p)
const char * analog_cidstart_to_str (enum analog_cid_start cid_start)
const char * analog_cidtype_to_str (unsigned int cid_type)
int analog_config_complete (struct analog_pvt *p)
static int analog_confmute (struct analog_pvt *p, int mute)
static int analog_decrease_ss_count (struct analog_pvt *p)
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure.
static int analog_dial_digits (struct analog_pvt *p, enum analog_sub sub, struct analog_dialoperation *dop)
static int analog_distinctive_ring (struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata)
int analog_dnd (struct analog_pvt *p, int flag)
static int analog_dsp_reset_and_flush_digits (struct analog_pvt *p)
static int analog_dsp_set_digitmode (struct analog_pvt *p, enum analog_dsp_digitmode mode)
static char * analog_event2str (enum analog_event event)
ast_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_increase_ss_count (struct analog_pvt *p)
static int analog_is_dialing (struct analog_pvt *p, enum analog_sub index)
static int analog_is_off_hook (struct analog_pvt *p)
static void analog_lock_sub_owner (struct analog_pvt *pvt, enum analog_sub sub_idx)
static int analog_my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
analog_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)
ast_channelanalog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
static int analog_ring (struct analog_pvt *p)
static int analog_send_callerid (struct analog_pvt *p, int cwcid, struct ast_party_caller *caller)
static void analog_set_alarm (struct analog_pvt *p, int in_alarm)
static void analog_set_cadence (struct analog_pvt *p, struct ast_channel *chan)
static void analog_set_callwaiting (struct analog_pvt *p, int callwaiting_enable)
static void analog_set_confirmanswer (struct analog_pvt *p, int flag)
static void analog_set_dialing (struct analog_pvt *p, int is_dialing)
static int analog_set_echocanceller (struct analog_pvt *p, int enable)
static void analog_set_inthreeway (struct analog_pvt *p, enum analog_sub sub, int inthreeway)
static int analog_set_linear_mode (struct analog_pvt *p, enum analog_sub sub, int linear_mode)
static void analog_set_needringing (struct analog_pvt *p, int value)
static void analog_set_new_owner (struct analog_pvt *p, struct ast_channel *new_owner)
static void analog_set_pulsedial (struct analog_pvt *p, int flag)
static void analog_set_ringtimeout (struct analog_pvt *p, int ringt)
static void analog_set_waitingfordt (struct analog_pvt *p, struct ast_channel *ast)
const char * analog_sigtype_to_str (enum analog_sigtype sigtype)
int analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *chan)
static int analog_start (struct analog_pvt *p)
static int analog_start_cid_detect (struct analog_pvt *p, int cid_signalling)
static void analog_start_polarityswitch (struct analog_pvt *p)
static int analog_stop_callwait (struct analog_pvt *p)
static int analog_stop_cid_detect (struct analog_pvt *p)
enum analog_cid_start analog_str_to_cidstart (const char *value)
unsigned int analog_str_to_cidtype (const char *name)
enum analog_sigtype analog_str_to_sigtype (const char *name)
static void analog_swap_subs (struct analog_pvt *p, enum analog_sub a, enum analog_sub b)
static int analog_train_echocanceller (struct analog_pvt *p)
static int analog_unalloc_sub (struct analog_pvt *p, enum analog_sub x)
static 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__)

Definition at line 376 of file sig_analog.c.

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

#define ANALOG_NEED_MFDETECT (  )     (((p)->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 1701 of file sig_analog.c.

Referenced by __analog_ss_thread().

#define ISTRUNK (  ) 

Value:

((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \
               (p->sig == ANALOG_SIG_FXSGS))

Definition at line 100 of file sig_analog.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 54 of file sig_analog.c.

#define POLARITY_IDLE   0

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

Definition at line 52 of file sig_analog.c.

#define POLARITY_REV   1

Definition at line 53 of file sig_analog.c.


Function Documentation

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

Definition at line 2602 of file sig_analog.c.

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

Referenced by analog_exception().

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

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

Definition at line 1703 of file sig_analog.c.

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

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

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

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

Definition at line 377 of file sig_analog.c.

References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_log(), analog_pvt::channel, LOG_WARNING, ast_channel::name, and analog_pvt::subs.

00378 {
00379    int res;
00380    if (p->subs[ANALOG_SUB_REAL].owner == ast) {
00381       res = ANALOG_SUB_REAL;
00382    } else if (p->subs[ANALOG_SUB_CALLWAIT].owner == ast) {
00383       res = ANALOG_SUB_CALLWAIT;
00384    } else if (p->subs[ANALOG_SUB_THREEWAY].owner == ast) {
00385       res = ANALOG_SUB_THREEWAY;
00386    } else {
00387       res = -1;
00388       if (!nullok) {
00389          ast_log(LOG_WARNING,
00390             "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
00391             ast ? ast->name : "", p->channel, fname, line);
00392       }
00393    }
00394    return res;
00395 }

static void analog_all_subchannels_hungup ( struct analog_pvt p  )  [static]

Definition at line 514 of file sig_analog.c.

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

Referenced by analog_hangup().

00515 {
00516    if (p->calls->all_subchannels_hungup) {
00517       p->calls->all_subchannels_hungup(p->chan_pvt);
00518    }
00519 }

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

Definition at line 337 of file sig_analog.c.

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

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

00338 {
00339    if (p->calls->allocate_sub) {
00340       int res;
00341       res = p->calls->allocate_sub(p->chan_pvt, x);
00342       if (!res) {
00343          p->subs[x].allocd = 1;
00344       }
00345       return res;
00346    }
00347    return 0;
00348 }

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1477 of file sig_analog.c.

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

Referenced by dahdi_answer().

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

static void analog_answer_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 605 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_answer().

00606 {
00607    if (p->calls->answer_polarityswitch) {
00608       return p->calls->answer_polarityswitch(p->chan_pvt);
00609    }
00610 }

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

Definition at line 673 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

int analog_available ( struct analog_pvt p  ) 

Definition at line 796 of file sig_analog.c.

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

Referenced by available().

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

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

Definition at line 993 of file sig_analog.c.

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

Referenced by dahdi_call().

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

static int analog_callwait ( struct analog_pvt p  )  [static]

Definition at line 869 of file sig_analog.c.

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

Referenced by analog_call().

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

static void analog_cancel_cidspill ( struct analog_pvt p  )  [static]

Definition at line 951 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_init_event().

00952 {
00953    if (!p->calls->cancel_cidspill) {
00954       return;
00955    }
00956 
00957    p->calls->cancel_cidspill(p->chan_pvt);
00958 }

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

Definition at line 627 of file sig_analog.c.

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

Referenced by analog_handle_dtmf().

00628 {
00629    if (p->calls->handle_dtmf) {
00630       p->calls->handle_dtmf(p->chan_pvt, ast, analog_index, dest);
00631    }
00632 }

static int analog_check_confirmanswer ( struct analog_pvt p  )  [static]

Definition at line 942 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_dtmf().

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

static int analog_check_for_conference ( struct analog_pvt p  )  [static]

Definition at line 506 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_check_waitingfordt ( struct analog_pvt p  )  [static]

Definition at line 925 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00926 {
00927    if (p->calls->check_waitingfordt) {
00928       return p->calls->check_waitingfordt(p->chan_pvt);
00929    }
00930 
00931    return 0;
00932 }

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

Definition at line 218 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

00219 {
00220    switch (cid_start) {
00221    case ANALOG_CID_START_RING:
00222       return "Ring";
00223    case ANALOG_CID_START_POLARITY:
00224       return "Polarity";
00225    case ANALOG_CID_START_POLARITY_IN:
00226       return "Polarity_In";
00227    case ANALOG_CID_START_DTMF_NOALERT:
00228       return "DTMF";
00229    }
00230 
00231    return "Unknown";
00232 }

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 142 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

int analog_config_complete ( struct analog_pvt p  ) 

Definition at line 3844 of file sig_analog.c.

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

03845 {
03846    /* No call waiting on non FXS channels */
03847    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03848       p->permcallwaiting = 0;
03849    }
03850 
03851    analog_set_callwaiting(p, p->permcallwaiting);
03852 
03853    return 0;
03854 }

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

Definition at line 960 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00961 {
00962    if (p->calls->confmute) {
00963       return p->calls->confmute(p->chan_pvt, mute);
00964    }
00965    return 0;
00966 }

static int analog_decrease_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1660 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

void analog_delete ( struct analog_pvt doomed  ) 

Delete the analog private structure.

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

Definition at line 3839 of file sig_analog.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

03840 {
03841    ast_free(doomed);
03842 }

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

Definition at line 490 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_call().

00491 {
00492    if (p->calls->dial_digits) {
00493       return p->calls->dial_digits(p->chan_pvt, sub, dop);
00494    }
00495    return -1;
00496 }

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

Definition at line 1669 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01670 {
01671    if (p->calls->distinctive_ring) {
01672       return p->calls->distinctive_ring(chan, p->chan_pvt, idx, ringdata);
01673    }
01674    return -1;
01675 
01676 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

Definition at line 3880 of file sig_analog.c.

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

Referenced by __analog_ss_thread(), and dahdi_dnd().

03881 {
03882    if (flag == -1) {
03883       return p->dnd;
03884    }
03885 
03886    p->dnd = flag;
03887 
03888    ast_verb(3, "%s DND on channel %d\n",
03889          flag ? "Enabled" : "Disabled",
03890          p->channel);
03891    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03892          "Channel: DAHDI/%d\r\n"
03893          "Status: %s\r\n", p->channel,
03894          flag ? "enabled" : "disabled");
03895 
03896    return 0;
03897 }

static int analog_dsp_reset_and_flush_digits ( struct analog_pvt p  )  [static]

Definition at line 397 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00398 {
00399    if (p->calls->dsp_reset_and_flush_digits) {
00400       return p->calls->dsp_reset_and_flush_digits(p->chan_pvt);
00401    }
00402 
00403    /* Return 0 since I think this is unnecessary to do in most cases it is used.  Mostly only for ast_dsp */
00404    return 0;
00405 }

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

Definition at line 619 of file sig_analog.c.

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

Referenced by __analog_ss_thread(), and analog_hangup().

00620 {
00621    if (p->calls->dsp_set_digitmode) {
00622       return p->calls->dsp_set_digitmode(p->chan_pvt, mode);
00623    }
00624    return -1;
00625 }

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

Definition at line 234 of file sig_analog.c.

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

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

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

struct ast_frame* analog_exception ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 3453 of file sig_analog.c.

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

Referenced by dahdi_exception(), and dahdi_read().

03454 {
03455    int res;
03456    int idx;
03457    struct ast_frame *f;
03458 
03459    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
03460 
03461    idx = analog_get_index(ast, p, 1);
03462    if (idx < 0) {
03463       idx = ANALOG_SUB_REAL;
03464    }
03465 
03466    p->subs[idx].f.frametype = AST_FRAME_NULL;
03467    p->subs[idx].f.datalen = 0;
03468    p->subs[idx].f.samples = 0;
03469    p->subs[idx].f.mallocd = 0;
03470    p->subs[idx].f.offset = 0;
03471    p->subs[idx].f.subclass.integer = 0;
03472    p->subs[idx].f.delivery = ast_tv(0,0);
03473    p->subs[idx].f.src = "dahdi_exception";
03474    p->subs[idx].f.data.ptr = NULL;
03475 
03476    if (!p->owner) {
03477       /* If nobody owns us, absorb the event appropriately, otherwise
03478          we loop indefinitely.  This occurs when, during call waiting, the
03479          other end hangs up our channel so that it no longer exists, but we
03480          have neither FLASH'd nor ONHOOK'd to signify our desire to
03481          change to the other channel. */
03482       res = analog_get_event(p);
03483 
03484       /* Switch to real if there is one and this isn't something really silly... */
03485       if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
03486          (res != ANALOG_EVENT_HOOKCOMPLETE)) {
03487          ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
03488          analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03489          if (p->owner && ast != p->owner) {
03490             /*
03491              * Could this even happen?
03492              * Possible deadlock because we do not have the real-call lock.
03493              */
03494             ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n",
03495                analog_event2str(res), ast->name, p->owner->name);
03496          }
03497          if (p->owner && ast_bridged_channel(p->owner)) {
03498             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03499          }
03500       }
03501       switch (res) {
03502       case ANALOG_EVENT_ONHOOK:
03503          analog_set_echocanceller(p, 0);
03504          if (p->owner) {
03505             ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name);
03506             analog_ring(p);
03507             analog_stop_callwait(p);
03508          } else {
03509             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03510                analog_event2str(res));
03511          }
03512          analog_update_conf(p);
03513          break;
03514       case ANALOG_EVENT_RINGOFFHOOK:
03515          analog_set_echocanceller(p, 1);
03516          analog_off_hook(p);
03517          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
03518             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03519             analog_set_dialing(p, 0);
03520          }
03521          break;
03522       case ANALOG_EVENT_HOOKCOMPLETE:
03523       case ANALOG_EVENT_RINGERON:
03524       case ANALOG_EVENT_RINGEROFF:
03525          /* Do nothing */
03526          break;
03527       case ANALOG_EVENT_WINKFLASH:
03528          gettimeofday(&p->flashtime, NULL);
03529          if (p->owner) {
03530             ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
03531             if (p->owner->_state != AST_STATE_UP) {
03532                /* Answer if necessary */
03533                ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03534                ast_setstate(p->owner, AST_STATE_UP);
03535             }
03536             analog_stop_callwait(p);
03537             if (ast_bridged_channel(p->owner)) {
03538                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03539             }
03540          } else {
03541             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03542                analog_event2str(res));
03543          }
03544          analog_update_conf(p);
03545          break;
03546       default:
03547          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res));
03548          break;
03549       }
03550       f = &p->subs[idx].f;
03551       return f;
03552    }
03553    ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
03554    /* If it's not us, return NULL immediately */
03555    if (ast != p->owner) {
03556       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
03557       f = &p->subs[idx].f;
03558       return f;
03559    }
03560    f = __analog_handle_event(p, ast);
03561    return f;
03562 }

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

Definition at line 3862 of file sig_analog.c.

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

03863 {
03864    struct analog_pvt *new_pvt = newp;
03865    int x;
03866    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03867    if (new_pvt->owner == oldchan) {
03868       analog_set_new_owner(new_pvt, newchan);
03869    }
03870    for (x = 0; x < 3; x++) {
03871       if (new_pvt->subs[x].owner == oldchan) {
03872          new_pvt->subs[x].owner = newchan;
03873       }
03874    }
03875 
03876    analog_update_conf(new_pvt);
03877    return 0;
03878 }

static int analog_flash ( struct analog_pvt p  )  [static]

Definition at line 474 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

void analog_free ( struct analog_pvt p  ) 

Definition at line 3856 of file sig_analog.c.

References ast_free.

03857 {
03858    ast_free(p);
03859 }

static void analog_get_and_handle_alarms ( struct analog_pvt p  )  [static]

Definition at line 1678 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_init_event().

01679 {
01680    if (p->calls->get_and_handle_alarms) {
01681       return p->calls->get_and_handle_alarms(p->chan_pvt);
01682    }
01683 }

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

Definition at line 1685 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01686 {
01687    if (p->calls->get_sigpvt_bridged_channel) {
01688       return p->calls->get_sigpvt_bridged_channel;
01689    }
01690    return NULL;
01691 }

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

Definition at line 171 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

static int analog_get_event ( struct analog_pvt p  )  [static]

Definition at line 187 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_exception().

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

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

Definition at line 179 of file sig_analog.c.

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

Referenced by analog_call().

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

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

Definition at line 1693 of file sig_analog.c.

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

Referenced by __analog_handle_event().

01694 {
01695    if (p->calls->get_sub_fd) {
01696       return p->calls->get_sub_fd(p->chan_pvt, sub);
01697    }
01698    return -1;
01699 }

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

Definition at line 1580 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and dahdi_read().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3564 of file sig_analog.c.

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

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

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

Definition at line 1642 of file sig_analog.c.

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

Referenced by __analog_ss_thread(), and analog_handle_init_event().

01643 {
01644    if (p->calls->handle_notify_message) {
01645       p->calls->handle_notify_message(chan, p->chan_pvt, cid_flags, neon_mwievent);
01646       return 0;
01647    }
01648    return -1;
01649 }

static int analog_handles_digit ( struct ast_frame f  )  [static]

Definition at line 1555 of file sig_analog.c.

References f.

Referenced by analog_handle_dtmf().

01556 {
01557    char subclass = toupper(f->subclass.integer);
01558 
01559    switch (subclass) {
01560    case '1':
01561    case '2':
01562    case '3':
01563    case '4':
01564    case '5':
01565    case '6':
01566    case '7':
01567    case '9':
01568    case 'A':
01569    case 'B':
01570    case 'C':
01571    case 'D':
01572    case 'E':
01573    case 'F':
01574       return 1;
01575    default:
01576       return 0;
01577    }
01578 }

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1260 of file sig_analog.c.

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

Referenced by dahdi_hangup().

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

static void analog_hangup_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 612 of file sig_analog.c.

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

Referenced by analog_hangup().

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

static int analog_has_voicemail ( struct analog_pvt p  )  [static]

Definition at line 642 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_init_event().

00643 {
00644    if (p->calls->has_voicemail) {
00645       return p->calls->has_voicemail(p->chan_pvt);
00646    }
00647    return -1;
00648 }

static int analog_increase_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1651 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01652 {
01653    if (p->calls->increase_ss_count) {
01654       p->calls->increase_ss_count();
01655       return 0;
01656    }
01657    return -1;
01658 }

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

Definition at line 650 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_is_off_hook ( struct analog_pvt p  )  [static]

Definition at line 458 of file sig_analog.c.

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

Referenced by analog_available(), and analog_hangup().

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

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

Definition at line 554 of file sig_analog.c.

References ast_channel_trylock, analog_subchannel::owner, and analog_pvt::subs.

Referenced by __analog_handle_event(), and analog_hangup().

00555 {
00556    for (;;) {
00557       if (!pvt->subs[sub_idx].owner) {
00558          /* No subchannel owner pointer */
00559          break;
00560       }
00561       if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
00562          /* Got subchannel owner lock */
00563          break;
00564       }
00565       /* We must unlock the private to avoid the possibility of a deadlock */
00566       if (pvt->calls->deadlock_avoidance_private) {
00567          pvt->calls->deadlock_avoidance_private(pvt->chan_pvt);
00568       } else {
00569          /* Don't use 100% CPU if required callback not present. */
00570          usleep(1);
00571       }
00572    }
00573 }

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

Definition at line 1622 of file sig_analog.c.

References ast_waitfordigit().

Referenced by __analog_ss_thread().

01623 {
01624    char c;
01625 
01626    *str = 0; /* start with empty output buffer */
01627    for (;;) {
01628       /* Wait for the first digit (up to specified ms). */
01629       c = ast_waitfordigit(chan, ms);
01630       /* if timeout, hangup or error, return as such */
01631       if (c < 1) {
01632          return c;
01633       }
01634       *str++ = c;
01635       *str = 0;
01636       if (strchr(term, c)) {
01637          return 1;
01638       }
01639    }
01640 }

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

Definition at line 3808 of file sig_analog.c.

References ANALOG_CID_START_RING, ANALOG_SIG_NONE, ANALOG_SUB_REAL, ast_calloc, and CID_SIG_BELL.

03809 {
03810    struct analog_pvt *p;
03811 
03812    p = ast_calloc(1, sizeof(*p));
03813    if (!p) {
03814       return p;
03815    }
03816 
03817    p->calls = c;
03818    p->outsigmod = ANALOG_SIG_NONE;
03819    p->sig = signallingtype;
03820    p->chan_pvt = private_data;
03821 
03822    /* Some defaults for values */
03823    p->cid_start = ANALOG_CID_START_RING;
03824    p->cid_signalling = CID_SIG_BELL;
03825    /* Sub real is assumed to always be alloc'd */
03826    p->subs[ANALOG_SUB_REAL].allocd = 1;
03827 
03828    return p;
03829 }

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

Definition at line 423 of file sig_analog.c.

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

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

00424 {
00425    struct ast_channel *c;
00426 
00427    if (!p->calls->new_ast_channel) {
00428       return NULL;
00429    }
00430 
00431    c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub, requestor);
00432    if (c) {
00433       ast_string_field_set(c, call_forward, p->call_forward);
00434    }
00435    p->subs[sub].owner = c;
00436    if (!p->owner) {
00437       analog_set_new_owner(p, c);
00438    }
00439    return c;
00440 }

static int analog_off_hook ( struct analog_pvt p  )  [static]

Definition at line 575 of file sig_analog.c.

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

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

00576 {
00577    if (p->calls->off_hook) {
00578       return p->calls->off_hook(p->chan_pvt);
00579    }
00580    return -1;
00581 }

static int analog_on_hook ( struct analog_pvt p  )  [static]

Definition at line 498 of file sig_analog.c.

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

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

00499 {
00500    if (p->calls->on_hook) {
00501       return p->calls->on_hook(p->chan_pvt);
00502    }
00503    return -1;
00504 }

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

Definition at line 407 of file sig_analog.c.

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

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

00408 {
00409    if (p->calls->play_tone) {
00410       return p->calls->play_tone(p->chan_pvt, sub, tone);
00411    }
00412    return -1;
00413 }

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

Definition at line 773 of file sig_analog.c.

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

Referenced by dahdi_request().

00774 {
00775    struct ast_channel *ast;
00776 
00777    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
00778    *callwait = (p->owner != NULL);
00779 
00780    if (p->owner) {
00781       if (analog_alloc_sub(p, ANALOG_SUB_CALLWAIT)) {
00782          ast_log(LOG_ERROR, "Unable to alloc subchannel\n");
00783          return NULL;
00784       }
00785    }
00786 
00787    p->outgoing = 1;
00788    ast = analog_new_ast_channel(p, AST_STATE_RESERVED, 0,
00789       p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor);
00790    if (!ast) {
00791       p->outgoing = 0;
00792    }
00793    return ast;
00794 }

static int analog_ring ( struct analog_pvt p  )  [static]

Definition at line 466 of file sig_analog.c.

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

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

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

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

Definition at line 360 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_dtmf().

00361 {
00362    ast_debug(1, "Sending callerid.  CID_NAME: '%s' CID_NUM: '%s'\n",
00363       caller->id.name.str,
00364       caller->id.number.str);
00365 
00366    if (cwcid) {
00367       p->callwaitcas = 0;
00368    }
00369 
00370    if (p->calls->send_callerid) {
00371       return p->calls->send_callerid(p->chan_pvt, cwcid, caller);
00372    }
00373    return 0;
00374 }

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

Definition at line 901 of file sig_analog.c.

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

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

00902 {
00903    p->inalarm = in_alarm;
00904    if (p->calls->set_alarm) {
00905       return p->calls->set_alarm(p->chan_pvt, in_alarm);
00906    }
00907 }

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

Definition at line 886 of file sig_analog.c.

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

Referenced by analog_call().

00887 {
00888    if (p->calls->set_cadence) {
00889       return p->calls->set_cadence(p->chan_pvt, &p->cidrings, chan);
00890    }
00891 }

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

Definition at line 878 of file sig_analog.c.

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

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

00879 {
00880    p->callwaiting = callwaiting_enable;
00881    if (p->calls->set_callwaiting) {
00882       p->calls->set_callwaiting(p->chan_pvt, callwaiting_enable);
00883    }
00884 }

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

Definition at line 934 of file sig_analog.c.

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

Referenced by analog_handle_dtmf(), and analog_hangup().

00935 {
00936    if (!p->calls->set_confirmanswer) {
00937       return;
00938    }
00939    p->calls->set_confirmanswer(p->chan_pvt, flag);
00940 }

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

Definition at line 893 of file sig_analog.c.

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

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

00894 {
00895    p->dialing = is_dialing;
00896    if (p->calls->set_dialing) {
00897       return p->calls->set_dialing(p->chan_pvt, is_dialing);
00898    }
00899 }

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

Definition at line 442 of file sig_analog.c.

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

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

00443 {
00444    if (p->calls->set_echocanceller) {
00445       return p->calls->set_echocanceller(p->chan_pvt, enable);
00446    }
00447    return -1;
00448 }

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

Definition at line 985 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_hangup().

00986 {
00987    p->subs[sub].inthreeway = inthreeway;
00988    if (p->calls->set_inthreeway) {
00989       p->calls->set_inthreeway(p->chan_pvt, sub, inthreeway);
00990    }
00991 }

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

Definition at line 976 of file sig_analog.c.

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

Referenced by __analog_ss_thread(), and analog_hangup().

00977 {
00978    if (p->calls->set_linear_mode) {
00979       /* Return provides old linear_mode setting or error indication */
00980       return p->calls->set_linear_mode(p->chan_pvt, sub, linear_mode);
00981    }
00982    return -1;
00983 }

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

Definition at line 583 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00584 {
00585    if (p->calls->set_needringing) {
00586       return p->calls->set_needringing(p->chan_pvt, value);
00587    }
00588 }

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

Definition at line 415 of file sig_analog.c.

References analog_pvt::calls, analog_pvt::chan_pvt, analog_pvt::owner, and analog_callback::set_new_owner.

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

00416 {
00417    p->owner = new_owner;
00418    if (p->calls->set_new_owner) {
00419       p->calls->set_new_owner(p->chan_pvt, new_owner);
00420    }
00421 }

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

Definition at line 968 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_hangup().

00969 {
00970    if (!p->calls->set_pulsedial) {
00971       return;
00972    }
00973    p->calls->set_pulsedial(p->chan_pvt, flag);
00974 }

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

Definition at line 909 of file sig_analog.c.

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

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

00910 {
00911    p->ringt = ringt;
00912    if (!p->calls->set_ringtimeout) {
00913       return;
00914    }
00915    p->calls->set_ringtimeout(p->chan_pvt, ringt);
00916 }

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

Definition at line 918 of file sig_analog.c.

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

Referenced by analog_call().

00919 {
00920    if (p->calls->set_waitingfordt) {
00921       return p->calls->set_waitingfordt(p->chan_pvt, ast);
00922    }
00923 }

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 116 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

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

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel chan 
)

Definition at line 2595 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02596 {
02597    pthread_t threadid;
02598 
02599    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02600 }

static int analog_start ( struct analog_pvt p  )  [static]

Definition at line 482 of file sig_analog.c.

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

Referenced by analog_call().

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

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

Definition at line 155 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

static void analog_start_polarityswitch ( struct analog_pvt p  )  [static]

Definition at line 599 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_handle_init_event().

00600 {
00601    if (p->calls->start_polarityswitch) {
00602       return p->calls->start_polarityswitch(p->chan_pvt);
00603    }
00604 }

static int analog_stop_callwait ( struct analog_pvt p  )  [static]

Definition at line 860 of file sig_analog.c.

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

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

00861 {
00862    p->callwaitcas = 0;
00863    if (p->calls->stop_callwait) {
00864       return p->calls->stop_callwait(p->chan_pvt);
00865    }
00866    return 0;
00867 }

static int analog_stop_cid_detect ( struct analog_pvt p  )  [static]

Definition at line 163 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 203 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

00204 {
00205    if (!strcasecmp(value, "ring")) {
00206       return ANALOG_CID_START_RING;
00207    } else if (!strcasecmp(value, "polarity")) {
00208       return ANALOG_CID_START_POLARITY;
00209    } else if (!strcasecmp(value, "polarity_in")) {
00210       return ANALOG_CID_START_POLARITY_IN;
00211    } else if (!strcasecmp(value, "dtmf")) {
00212       return ANALOG_CID_START_DTMF_NOALERT;
00213    }
00214 
00215    return 0;
00216 }

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 129 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 103 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

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

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

Definition at line 317 of file sig_analog.c.

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

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

00318 {
00319    int tinthreeway;
00320    struct ast_channel *towner;
00321 
00322    ast_debug(1, "Swapping %d and %d\n", a, b);
00323 
00324    towner = p->subs[a].owner;
00325    p->subs[a].owner = p->subs[b].owner;
00326    p->subs[b].owner = towner;
00327 
00328    tinthreeway = p->subs[a].inthreeway;
00329    p->subs[a].inthreeway = p->subs[b].inthreeway;
00330    p->subs[b].inthreeway = tinthreeway;
00331 
00332    if (p->calls->swap_subs) {
00333       p->calls->swap_subs(p->chan_pvt, a, p->subs[a].owner, b, p->subs[b].owner);
00334    }
00335 }

static int analog_train_echocanceller ( struct analog_pvt p  )  [static]

Definition at line 450 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and analog_answer().

00451 {
00452    if (p->calls->train_echocanceller) {
00453       return p->calls->train_echocanceller(p->chan_pvt);
00454    }
00455    return -1;
00456 }

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

Definition at line 350 of file sig_analog.c.

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

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

00351 {
00352    p->subs[x].allocd = 0;
00353    p->subs[x].owner = NULL;
00354    if (p->calls->unallocate_sub) {
00355       return p->calls->unallocate_sub(p->chan_pvt, x);
00356    }
00357    return 0;
00358 }

static int analog_update_conf ( struct analog_pvt p  )  [static]

Definition at line 746 of file sig_analog.c.

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

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

00747 {
00748    int x;
00749    int needconf = 0;
00750 
00751    /* Start with the obvious, general stuff */
00752    for (x = 0; x < 3; x++) {
00753       /* Look for three way calls */
00754       if ((p->subs[x].allocd) && p->subs[x].inthreeway) {
00755          if (p->calls->conf_add) {
00756             p->calls->conf_add(p->chan_pvt, x);
00757          }
00758          needconf++;
00759       } else {
00760          if (p->calls->conf_del) {
00761             p->calls->conf_del(p->chan_pvt, x);
00762          }
00763       }
00764    }
00765    ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
00766 
00767    if (p->calls->complete_conference_update) {
00768       p->calls->complete_conference_update(p->chan_pvt, needconf);
00769    }
00770    return 0;
00771 }

static int analog_wait_event ( struct analog_pvt p  )  [static]

Definition at line 195 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

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

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

Definition at line 634 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00635 {
00636    if (p->calls->wink) {
00637       return p->calls->wink(p->chan_pvt, index);
00638    }
00639    return -1;
00640 }


Variable Documentation

char analog_defaultcic[64] = "" [static]

Definition at line 58 of file sig_analog.c.

Referenced by analog_call().

char analog_defaultozz[64] = "" [static]

Definition at line 59 of file sig_analog.c.

Referenced by analog_call().

int analog_firstdigittimeout = 16000 [static]

Definition at line 57 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_gendigittimeout = 8000 [static]

Definition at line 56 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_matchdigittimeout = 3000 [static]

Definition at line 55 of file sig_analog.c.

Referenced by __analog_ss_thread().

unsigned int cid_type

Definition at line 89 of file sig_analog.c.

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

Referenced by analog_cidtype_to_str(), and analog_str_to_cidtype().

const char const* name

Definition at line 90 of file sig_analog.c.

const char const* name

Definition at line 63 of file sig_analog.c.

enum analog_sigtype sigtype

Definition at line 62 of file sig_analog.c.

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

Referenced by analog_sigtype_to_str(), and analog_str_to_sigtype().


Generated on Mon Jun 27 16:51:21 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7