Wed Oct 28 13:33:39 2009

Asterisk developer's documentation


sig_analog.c File Reference

Analog signaling module. More...

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

Include dependency graph for sig_analog.c:

Go to the source code of this file.

Defines

#define ANALOG_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 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 int analog_attempt_transfer (struct analog_pvt *p)
int analog_available (struct analog_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
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_dtmfup (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
static int analog_check_confirmanswer (struct analog_pvt *p)
static int analog_check_for_conference (struct analog_pvt *p)
static int analog_check_waitingfordt (struct analog_pvt *p)
const char * analog_cidstart_to_str (enum analog_cid_start cid_start)
const char * analog_cidtype_to_str (unsigned int cid_type)
int analog_config_complete (struct analog_pvt *p)
static int analog_confmute (struct analog_pvt *p, int mute)
static int analog_decrease_ss_count (struct analog_pvt *p)
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure.
static int analog_dial_digits (struct analog_pvt *p, enum analog_sub sub, struct analog_dialoperation *dop)
static int analog_distinctive_ring (struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata)
int analog_dnd (struct analog_pvt *p, int flag)
static int analog_dsp_reset_and_flush_digits (struct analog_pvt *p)
static int analog_dsp_set_digitmode (struct analog_pvt *p, enum analog_dsp_digitmode mode)
static char * analog_event2str (enum analog_event event)
struct ast_frameanalog_exception (struct analog_pvt *p, struct ast_channel *ast)
int analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
static int analog_flash (struct analog_pvt *p)
void analog_free (struct analog_pvt *p)
static void analog_get_and_handle_alarms (struct analog_pvt *p)
static void * analog_get_bridged_channel (struct analog_pvt *p, struct ast_channel *chan)
static int analog_get_callerid (struct analog_pvt *p, char *name, char *number, enum analog_event *ev, size_t timeout)
static int analog_get_event (struct analog_pvt *p)
static int analog_get_index (struct ast_channel *ast, struct analog_pvt *p, int nullok)
static int analog_get_sub_fd (struct analog_pvt *p, enum analog_sub sub)
void analog_handle_dtmfup (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, 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 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_private (struct analog_pvt *p)
static int analog_my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
struct analog_pvtanalog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data)
static struct ast_channelanalog_new_ast_channel (struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
static int analog_off_hook (struct analog_pvt *p)
static int analog_on_hook (struct analog_pvt *p)
static int analog_play_tone (struct analog_pvt *p, enum analog_sub sub, enum analog_tone tone)
struct ast_channelanalog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
static int analog_ring (struct analog_pvt *p)
static int analog_send_callerid (struct analog_pvt *p, int cwcid, struct ast_callerid *cid)
static void analog_set_cadence (struct analog_pvt *p, struct ast_channel *chan)
static void analog_set_confirmanswer (struct analog_pvt *p, int flag)
static void analog_set_dialing (struct analog_pvt *p, int flag)
static int analog_set_echocanceller (struct analog_pvt *p, int enable)
static int analog_set_linear_mode (struct analog_pvt *p, int index, int linear_mode)
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 int analog_stop_callwait (struct analog_pvt *p)
static int analog_stop_cid_detect (struct analog_pvt *p)
enum analog_cid_start analog_str_to_cidstart (const char *value)
unsigned int analog_str_to_cidtype (const char *name)
enum analog_sigtype analog_str_to_sigtype (const char *name)
static void analog_swap_subs (struct analog_pvt *p, enum analog_sub a, enum analog_sub b)
static int analog_train_echocanceller (struct analog_pvt *p)
static int analog_unalloc_sub (struct analog_pvt *p, enum analog_sub x)
static void analog_unlock_private (struct analog_pvt *p)
static int analog_update_conf (struct analog_pvt *p)
static int analog_wait_event (struct analog_pvt *p)
static int analog_wink (struct analog_pvt *p, enum analog_sub index)

Variables

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


Detailed Description

Analog signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_analog.c.


Define Documentation

#define ANALOG_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 1467 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 93 of file sig_analog.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 47 of file sig_analog.c.

#define POLARITY_IDLE   0

Definition at line 45 of file sig_analog.c.

#define POLARITY_REV   1

Definition at line 46 of file sig_analog.c.


Function Documentation

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

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

< Channel is down and available

< Channel is down, but reserved

< Channel is off hook

< Line is busy

< Digits (or equivalent) have been dialed while offhook

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

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

Definition at line 2339 of file sig_analog.c.

References __analog_ss_thread(), ast_channel::_state, analog_alloc_sub(), 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_dtmfup(), analog_has_voicemail(), analog_is_dialing(), analog_lock_private(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_dialing(), analog_set_echocanceller(), 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_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_RINGTONE, ANALOG_TONE_STUTTER, analog_train_echocanceller(), analog_unalloc_sub(), analog_unlock_private(), analog_update_conf(), analog_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CAUSE_NO_ANSWER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_trylock, 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_pthread_create, 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, analog_pvt::callwaitcas, ast_channel::cdr, chan, analog_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::cid, analog_pvt::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, analog_pvt::cid_name, ast_callerid::cid_name, cid_name, analog_pvt::cid_num, ast_callerid::cid_num, cid_num, analog_pvt::cidrings, analog_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, analog_pvt::dialdest, analog_pvt::dialednone, analog_pvt::dialing, analog_dialoperation::dialstr, analog_pvt::dop, analog_pvt::echobreak, analog_pvt::echorest, analog_pvt::echotraining, errno, EVENT_FLAG_SYSTEM, analog_subchannel::f, f, analog_pvt::finaldial, analog_pvt::flashtime, ast_frame::frametype, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, analog_pvt::inalarm, analog_subchannel::inthreeway, ast_channel::linkedid, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event, MIN_MS_SINCE_FLASH, analog_pvt::mohsuggest, analog_pvt::msgstate, ast_channel::name, ast_frame::offset, analog_pvt::onhooktime, analog_dialoperation::op, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::outgoing, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, ast_channel::pbx, analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, analog_pvt::polaritydelaytv, analog_pvt::polarityonanswerdelay, ast_frame::ptr, ast_channel::rings, analog_pvt::ringt_base, S_OR, ast_frame::samples, analog_pvt::sig, ast_frame::src, analog_pvt::ss_astchan, ast_frame::subclass, analog_pvt::subs, analog_pvt::threewaycalling, analog_pvt::transfer, analog_pvt::transfertobusy, analog_pvt::unknown_alarm, and analog_pvt::whichwink.

Referenced by analog_exception().

02340 {
02341    int res, x;
02342    int mysig;
02343    enum analog_sub index;
02344    char *c;
02345    pthread_t threadid;
02346    pthread_attr_t attr;
02347    struct ast_channel *chan;
02348    struct ast_frame *f;
02349    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
02350 
02351    index = analog_get_index(ast, p, 0);
02352    mysig = p->sig;
02353    if (p->outsigmod > -1) {
02354       mysig = p->outsigmod;
02355    }
02356    p->subs[index].f.frametype = AST_FRAME_NULL;
02357    p->subs[index].f.subclass = 0;
02358    p->subs[index].f.datalen = 0;
02359    p->subs[index].f.samples = 0;
02360    p->subs[index].f.mallocd = 0;
02361    p->subs[index].f.offset = 0;
02362    p->subs[index].f.src = "dahdi_handle_event";
02363    p->subs[index].f.data.ptr = NULL;
02364    f = &p->subs[index].f;
02365 
02366    if (index < 0) {
02367       return &p->subs[index].f;
02368    }
02369 
02370    if (index != ANALOG_SUB_REAL) {
02371       ast_log(LOG_ERROR, "We got an event on a non real sub.  Fix it!\n");
02372    }
02373 
02374    res = analog_get_event(p);
02375 
02376    ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, index);
02377 
02378    if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) {
02379       analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT));
02380       ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
02381       analog_confmute(p, 0);
02382       p->subs[index].f.frametype = AST_FRAME_DTMF_END;
02383       p->subs[index].f.subclass = res & 0xff;
02384       analog_handle_dtmfup(p, ast, index, &f);
02385       return f;
02386    }
02387 
02388    if (res & ANALOG_EVENT_DTMFDOWN) {
02389       ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
02390       /* Mute conference */
02391       analog_confmute(p, 1);
02392       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
02393       p->subs[index].f.subclass = res & 0xff;
02394       return f;
02395    }
02396 
02397    switch (res) {
02398    case ANALOG_EVENT_EC_DISABLED:
02399       ast_verb(3, "Channel %d echo canceler disabled due to CED detection\n", p->channel);
02400       analog_set_echocanceller(p, 0);
02401       break;
02402 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
02403    case ANALOG_EVENT_TX_CED_DETECTED:
02404       ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel);
02405       break;
02406    case ANALOG_EVENT_RX_CED_DETECTED:
02407       ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel);
02408       break;
02409    case ANALOG_EVENT_EC_NLP_DISABLED:
02410       ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel);
02411       break;
02412    case ANALOG_EVENT_EC_NLP_ENABLED:
02413       ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel);
02414       break;
02415 #endif
02416    case ANALOG_EVENT_PULSE_START:
02417       /* Stop tone if there's a pulse start and the PBX isn't started */
02418       if (!ast->pbx)
02419          analog_play_tone(p, ANALOG_SUB_REAL, -1);
02420       break;
02421    case ANALOG_EVENT_DIALCOMPLETE:
02422       if (p->inalarm) {
02423          break;
02424       }
02425       x = analog_is_dialing(p, index);
02426       if (!x) { /* if not still dialing in driver */
02427          analog_set_echocanceller(p, 1);
02428          if (p->echobreak) {
02429             analog_train_echocanceller(p);
02430             ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
02431             p->dop.op = ANALOG_DIAL_OP_REPLACE;
02432             analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
02433             p->echobreak = 0;
02434          } else {
02435             analog_set_dialing(p, 0);
02436             if ((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) {
02437                /* if thru with dialing after offhook */
02438                if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
02439                   ast_setstate(ast, AST_STATE_UP);
02440                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
02441                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
02442                   break;
02443                } else { /* if to state wait for offhook to dial rest */
02444                   /* we now wait for off hook */
02445                   ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
02446                }
02447             }
02448             if (ast->_state == AST_STATE_DIALING) {
02449                if (analog_check_confirmanswer(p) || (!p->dialednone && ((mysig == ANALOG_SIG_EM) || (mysig == ANALOG_SIG_EM_E1) ||  (mysig == ANALOG_SIG_EMWINK) || (mysig == ANALOG_SIG_FEATD) || (mysig == ANALOG_SIG_FEATDMF_TA) || (mysig == ANALOG_SIG_FEATDMF) || (mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF) || (mysig == ANALOG_SIG_FEATB) || (mysig == ANALOG_SIG_SF) || (mysig == ANALOG_SIG_SFWINK) || (mysig == ANALOG_SIG_SF_FEATD) || (mysig == ANALOG_SIG_SF_FEATDMF) || (mysig == ANALOG_SIG_SF_FEATB)))) {
02450                   ast_setstate(ast, AST_STATE_RINGING);
02451                } else if (!p->answeronpolarityswitch) {
02452                   ast_setstate(ast, AST_STATE_UP);
02453                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
02454                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
02455                   /* If aops=0 and hops=1, this is necessary */
02456                   p->polarity = POLARITY_REV;
02457                } else {
02458                   /* Start clean, so we can catch the change to REV polarity when party answers */
02459                   p->polarity = POLARITY_IDLE;
02460                }
02461             }
02462          }
02463       }
02464       break;
02465    case ANALOG_EVENT_ALARM:
02466       p->inalarm = 1;
02467       analog_get_and_handle_alarms(p);
02468 
02469    case ANALOG_EVENT_ONHOOK:
02470       switch (p->sig) {
02471       case ANALOG_SIG_FXOLS:
02472       case ANALOG_SIG_FXOGS:
02473       case ANALOG_SIG_FXOKS:
02474          p->fxsoffhookstate = 0;
02475          p->onhooktime = time(NULL);
02476          p->msgstate = -1;
02477          /* Check for some special conditions regarding call waiting */
02478          if (index == ANALOG_SUB_REAL) {
02479             /* The normal line was hung up */
02480             if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
02481                /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
02482                analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
02483                ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
02484                analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
02485                analog_stop_callwait(p);
02486                p->owner = NULL;
02487                /* Don't start streaming audio yet if the incoming call isn't up yet */
02488                if (p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) {
02489                   analog_set_dialing(p, 1);
02490                }
02491                analog_ring(p);
02492             } else if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02493                unsigned int mssinceflash;
02494                /* Here we have to retain the lock on both the main channel, the 3-way channel, and
02495                   the private structure -- not especially easy or clean */
02496                while (p->subs[ANALOG_SUB_THREEWAY].owner && ast_channel_trylock(p->subs[ANALOG_SUB_THREEWAY].owner)) {
02497                   /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
02498                   analog_unlock_private(p);
02499                   CHANNEL_DEADLOCK_AVOIDANCE(ast);
02500                   /* We can grab ast and p in that order, without worry.  We should make sure
02501                      nothing seriously bad has happened though like some sort of bizarre double
02502                      masquerade! */
02503                   analog_lock_private(p);
02504                   if (p->owner != ast) {
02505                      ast_log(LOG_WARNING, "This isn't good...\n");
02506                      return NULL;
02507                   }
02508                }
02509                if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
02510                   ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
02511                   return NULL;
02512                }
02513                mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
02514                ast_debug(1, "Last flash was %d ms ago\n", mssinceflash);
02515                if (mssinceflash < MIN_MS_SINCE_FLASH) {
02516                   /* It hasn't been long enough since the last flashook.  This is probably a bounce on
02517                      hanging up.  Hangup both channels now */
02518                   if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02519                      ast_queue_hangup_with_cause(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER);
02520                   }
02521                   ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02522                   ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
02523                   ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02524                } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
02525                   if (p->transfer) {
02526                      /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
02527                      if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
02528                         ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02529                         /* Swap subs and dis-own channel */
02530                         analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02531                         p->owner = NULL;
02532                         /* Ring the phone */
02533                         analog_ring(p);
02534                      } else {
02535                         if ((res = analog_attempt_transfer(p)) < 0) {
02536                            ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02537                            if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02538                               ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02539                            }
02540                         } else if (res) {
02541                            /* this isn't a threeway call anymore */
02542                            p->subs[ANALOG_SUB_REAL].inthreeway = 0;
02543                            p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
02544 
02545                            /* Don't actually hang up at this point */
02546                            if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02547                               ast_channel_unlock(&p->subs[ANALOG_SUB_THREEWAY].owner);
02548                            }
02549                            break;
02550                         }
02551                      }
02552                      /* this isn't a threeway call anymore */
02553                      p->subs[ANALOG_SUB_REAL].inthreeway = 0;
02554                      p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
02555                   } else {
02556                      ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02557                      if (p->subs[ANALOG_SUB_THREEWAY].owner) {
02558                         ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02559                      }
02560                   }
02561                } else {
02562                   ast_cel_report_event(ast, AST_CEL_BLINDTRANSFER, NULL, ast->linkedid, NULL);
02563                   ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
02564                   /* Swap subs and dis-own channel */
02565                   analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02566                   p->owner = NULL;
02567                   /* Ring the phone */
02568                   analog_ring(p);
02569                }
02570             }
02571          } else {
02572             ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
02573          }
02574          /* Fall through */
02575       default:
02576          analog_set_echocanceller(p, 0);
02577          return NULL;
02578       }
02579       break;
02580    case ANALOG_EVENT_RINGOFFHOOK:
02581       if (p->inalarm) {
02582          break;
02583       }
02584       /* for E911, its supposed to wait for offhook then dial
02585          the second half of the dial string */
02586       if (((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
02587          c = strchr(p->dialdest, '/');
02588          if (c) {
02589             c++;
02590          } else {
02591             c = p->dialdest;
02592          }
02593          if (*c) {
02594             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
02595          } else {
02596             ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
02597          }
02598          if (strlen(p->dop.dialstr) > 4) {
02599             memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02600             strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02601             p->echorest[sizeof(p->echorest) - 1] = '\0';
02602             p->echobreak = 1;
02603             p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02604          } else {
02605             p->echobreak = 0;
02606          }
02607          if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) {
02608             int saveerr = errno;
02609             analog_on_hook(p);
02610             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
02611             return NULL;
02612          }
02613          analog_set_dialing(p, 1);
02614          return &p->subs[index].f;
02615       }
02616       switch (p->sig) {
02617       case ANALOG_SIG_FXOLS:
02618       case ANALOG_SIG_FXOGS:
02619       case ANALOG_SIG_FXOKS:
02620          p->fxsoffhookstate = 1;
02621          switch (ast->_state) {
02622          case AST_STATE_RINGING:
02623             analog_set_echocanceller(p, 1);
02624             analog_train_echocanceller(p);
02625             p->subs[index].f.frametype = AST_FRAME_CONTROL;
02626             p->subs[index].f.subclass = AST_CONTROL_ANSWER;
02627             /* Make sure it stops ringing */
02628             analog_off_hook(p);
02629             ast_debug(1, "channel %d answered\n", p->channel);
02630             analog_cancel_cidspill(p);
02631             analog_set_dialing(p, 0);
02632             p->callwaitcas = 0;
02633             if (analog_check_confirmanswer(p)) {
02634                /* Ignore answer if "confirm answer" is enabled */
02635                p->subs[index].f.frametype = AST_FRAME_NULL;
02636                p->subs[index].f.subclass = 0;
02637             } else if (!ast_strlen_zero(p->dop.dialstr)) {
02638                /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
02639                res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
02640                if (res < 0) {
02641                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
02642                   p->dop.dialstr[0] = '\0';
02643                   return NULL;
02644                } else {
02645                   ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
02646                   p->subs[index].f.frametype = AST_FRAME_NULL;
02647                   p->subs[index].f.subclass = 0;
02648                   analog_set_dialing(p, 1);
02649                }
02650                p->dop.dialstr[0] = '\0';
02651                ast_setstate(ast, AST_STATE_DIALING);
02652             } else {
02653                ast_setstate(ast, AST_STATE_UP);
02654             }
02655             return &p->subs[index].f;
02656          case AST_STATE_DOWN:
02657             ast_setstate(ast, AST_STATE_RING);
02658             ast->rings = 1;
02659             p->subs[index].f.frametype = AST_FRAME_CONTROL;
02660             p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
02661             ast_debug(1, "channel %d picked up\n", p->channel);
02662             return &p->subs[index].f;
02663          case AST_STATE_UP:
02664             /* Make sure it stops ringing */
02665             analog_off_hook(p);
02666             /* Okay -- probably call waiting*/
02667             if (ast_bridged_channel(p->owner)) {
02668                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
02669             }
02670             break;
02671          case AST_STATE_RESERVED:
02672             /* Start up dialtone */
02673             if (analog_has_voicemail(p)) {
02674                res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER);
02675             } else {
02676                res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE);
02677             }
02678             break;
02679          default:
02680             ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
02681          }
02682          break;
02683       case ANALOG_SIG_FXSLS:
02684       case ANALOG_SIG_FXSGS:
02685       case ANALOG_SIG_FXSKS:
02686          if (ast->_state == AST_STATE_RING) {
02687             analog_set_ringtimeout(p, p->ringt_base);
02688          }
02689 
02690          /* Fall through */
02691       case ANALOG_SIG_EM:
02692       case ANALOG_SIG_EM_E1:
02693       case ANALOG_SIG_EMWINK:
02694       case ANALOG_SIG_FEATD:
02695       case ANALOG_SIG_FEATDMF:
02696       case ANALOG_SIG_FEATDMF_TA:
02697       case ANALOG_SIG_E911:
02698       case ANALOG_SIG_FGC_CAMA:
02699       case ANALOG_SIG_FGC_CAMAMF:
02700       case ANALOG_SIG_FEATB:
02701       case ANALOG_SIG_SF:
02702       case ANALOG_SIG_SFWINK:
02703       case ANALOG_SIG_SF_FEATD:
02704       case ANALOG_SIG_SF_FEATDMF:
02705       case ANALOG_SIG_SF_FEATB:
02706          if (ast->_state == AST_STATE_PRERING) {
02707             ast_setstate(ast, AST_STATE_RING);
02708          }
02709          if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
02710             ast_debug(1, "Ring detected\n");
02711             p->subs[index].f.frametype = AST_FRAME_CONTROL;
02712             p->subs[index].f.subclass = AST_CONTROL_RING;
02713          } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
02714             ast_debug(1, "Line answered\n");
02715             if (analog_check_confirmanswer(p)) {
02716                p->subs[index].f.frametype = AST_FRAME_NULL;
02717                p->subs[index].f.subclass = 0;
02718             } else {
02719                p->subs[index].f.frametype = AST_FRAME_CONTROL;
02720                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
02721                ast_setstate(ast, AST_STATE_UP);
02722             }
02723          } else if (ast->_state != AST_STATE_RING) {
02724             ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
02725          }
02726          break;
02727       default:
02728          ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
02729       }
02730       break;
02731 #ifdef ANALOG_EVENT_RINGBEGIN
02732    case ANALOG_EVENT_RINGBEGIN:
02733       switch (p->sig) {
02734       case ANALOG_SIG_FXSLS:
02735       case ANALOG_SIG_FXSGS:
02736       case ANALOG_SIG_FXSKS:
02737          if (ast->_state == AST_STATE_RING) {
02738             analog_set_ringtimeout(p, p->ringt_base);
02739          }
02740          break;
02741       }
02742       break;
02743 #endif
02744    case ANALOG_EVENT_RINGEROFF:
02745       if (p->inalarm) break;
02746       ast->rings++;
02747       if (ast->rings == p->cidrings) {
02748          analog_send_callerid(p, 0, &p->cid);
02749       }
02750 
02751       if (ast->rings > p->cidrings) {
02752          analog_cancel_cidspill(p);
02753          p->callwaitcas = 0;
02754       }
02755       p->subs[index].f.frametype = AST_FRAME_CONTROL;
02756       p->subs[index].f.subclass = AST_CONTROL_RINGING;
02757       break;
02758    case ANALOG_EVENT_RINGERON:
02759       break;
02760    case ANALOG_EVENT_NOALARM:
02761       p->inalarm = 0;
02762       if (!p->unknown_alarm) {
02763          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
02764          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
02765             "Channel: %d\r\n", p->channel);
02766       } else {
02767          p->unknown_alarm = 0;
02768       }
02769       break;
02770    case ANALOG_EVENT_WINKFLASH:
02771       if (p->inalarm) {
02772          break;
02773       }
02774       /* Remember last time we got a flash-hook */
02775       gettimeofday(&p->flashtime, NULL);
02776       switch (mysig) {
02777       case ANALOG_SIG_FXOLS:
02778       case ANALOG_SIG_FXOGS:
02779       case ANALOG_SIG_FXOKS:
02780          ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
02781             index, analog_get_sub_fd(p, ANALOG_SUB_REAL), analog_get_sub_fd(p, ANALOG_SUB_CALLWAIT), analog_get_sub_fd(p, ANALOG_SUB_THREEWAY));
02782 
02783          p->callwaitcas = 0;
02784 
02785          if (index != ANALOG_SUB_REAL) {
02786             ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
02787             goto winkflashdone;
02788          }
02789 
02790          if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
02791             /* Swap to call-wait */
02792             int previous_state = p->subs[ANALOG_SUB_CALLWAIT].owner->_state;
02793             if (p->subs[ANALOG_SUB_CALLWAIT].owner->_state == AST_STATE_RINGING) {
02794                ast_setstate(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_STATE_UP);
02795             }
02796             analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT);
02797             analog_play_tone(p, ANALOG_SUB_REAL, -1);
02798             p->owner = p->subs[ANALOG_SUB_REAL].owner;
02799             ast_debug(1, "Making %s the new owner\n", p->owner->name);
02800             if (previous_state == AST_STATE_RINGING) {
02801                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
02802             }
02803             analog_stop_callwait(p);
02804             /* Start music on hold if appropriate */
02805             if (!p->subs[ANALOG_SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) {
02806                ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
02807                   S_OR(p->mohsuggest, NULL),
02808                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02809             }
02810             ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
02811             if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
02812                ast_queue_control_data(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_HOLD,
02813                   S_OR(p->mohsuggest, NULL),
02814                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02815             }
02816             ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
02817          } else if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
02818             char cid_num[256];
02819             char cid_name[256];
02820 
02821             if (!p->threewaycalling) {
02822                /* Just send a flash if no 3-way calling */
02823                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_FLASH);
02824                goto winkflashdone;
02825             } else if (!analog_check_for_conference(p)) {
02826                if (p->dahditrcallerid && p->owner) {
02827                   if (p->owner->cid.cid_num) {
02828                      ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
02829                   }
02830                   if (p->owner->cid.cid_name) {
02831                      ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
02832                   }
02833                }
02834                /* XXX This section needs much more error checking!!! XXX */
02835                /* Start a 3-way call if feasible */
02836                if (!((ast->pbx) ||
02837                      (ast->_state == AST_STATE_UP) ||
02838                      (ast->_state == AST_STATE_RING))) {
02839                   ast_debug(1, "Flash when call not up or ringing\n");
02840                      goto winkflashdone;
02841                }
02842                if (analog_alloc_sub(p, ANALOG_SUB_THREEWAY)) {
02843                   ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
02844                   goto winkflashdone;
02845                }
02846                /* Make new channel */
02847                chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY, NULL);
02848                if (p->dahditrcallerid) {
02849                   if (!p->origcid_num) {
02850                      p->origcid_num = ast_strdup(p->cid_num);
02851                   }
02852                   if (!p->origcid_name) {
02853                      p->origcid_name = ast_strdup(p->cid_name);
02854                   }
02855                   ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
02856                   ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
02857                }
02858                /* Swap things around between the three-way and real call */
02859                analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02860                /* Disable echo canceller for better dialing */
02861                analog_set_echocanceller(p, 0);
02862                res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALRECALL);
02863                if (res) {
02864                   ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
02865                }
02866                p->ss_astchan = p->owner = chan;
02867                pthread_attr_init(&attr);
02868                pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02869                if (!chan) {
02870                   ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
02871                } else if (ast_pthread_create(&threadid, &attr, __analog_ss_thread, p)) {
02872                   ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
02873                   res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
02874                   analog_set_echocanceller(p, 1);
02875                   ast_hangup(chan);
02876                } else {
02877                   struct ast_channel *other = ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner);
02878                   int way3bridge = 0, cdr3way = 0;
02879 
02880                   if (!other) {
02881                      other = ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner);
02882                   } else {
02883                      way3bridge = 1;
02884                   }
02885 
02886                   if (p->subs[ANALOG_SUB_THREEWAY].owner->cdr) {
02887                      cdr3way = 1;
02888                   }
02889 
02890                   ast_verb(3, "Started three way call on channel %d\n", p->channel);
02891                   /* Start music on hold if appropriate */
02892                   if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
02893                      ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD,
02894                         S_OR(p->mohsuggest, NULL),
02895                         !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02896                   }
02897                }
02898                pthread_attr_destroy(&attr);
02899             }
02900          } else {
02901             /* Already have a 3 way call */
02902             if (p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
02903                /* Call is already up, drop the last person */
02904                ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
02905                /* If the primary call isn't answered yet, use it */
02906                if ((p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) &&
02907                   (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
02908                   /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
02909                   analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02910                   p->owner = p->subs[ANALOG_SUB_REAL].owner;
02911                }
02912                /* Drop the last call and stop the conference */
02913                ast_verb(3, "Dropping three-way call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name);
02914                ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02915                p->subs[ANALOG_SUB_REAL].inthreeway = 0;
02916                p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
02917             } else {
02918                /* Lets see what we're up to */
02919                if (((ast->pbx) || (ast->_state == AST_STATE_UP)) &&
02920                   (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
02921                   int otherindex = ANALOG_SUB_THREEWAY;
02922                   struct ast_channel *other = ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner);
02923                   int way3bridge = 0, cdr3way = 0;
02924 
02925                   if (!other) {
02926                      other = ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner);
02927                   } else {
02928                      way3bridge = 1;
02929                   }
02930 
02931                   if (p->subs[ANALOG_SUB_THREEWAY].owner->cdr) {
02932                      cdr3way = 1;
02933                   }
02934 
02935                   ast_verb(3, "Building conference on call on %s and %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name, p->subs[ANALOG_SUB_REAL].owner->name);
02936                   /* Put them in the threeway, and flip */
02937                   p->subs[ANALOG_SUB_THREEWAY].inthreeway = 1;
02938                   p->subs[ANALOG_SUB_REAL].inthreeway = 1;
02939                   if (ast->_state == AST_STATE_UP) {
02940                      analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02941                      otherindex = ANALOG_SUB_REAL;
02942                   }
02943                   if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) {
02944                      ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
02945                   }
02946                   p->owner = p->subs[ANALOG_SUB_REAL].owner;
02947                   if (ast->_state == AST_STATE_RINGING) {
02948                      ast_debug(1, "Enabling ringtone on real and threeway\n");
02949                      analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE);
02950                      analog_play_tone(p, ANALOG_SUB_THREEWAY, ANALOG_TONE_RINGTONE);
02951                   }
02952                } else {
02953                   ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name);
02954                   analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
02955                   ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
02956                   p->owner = p->subs[ANALOG_SUB_REAL].owner;
02957                   if (p->subs[ANALOG_SUB_REAL].owner && ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
02958                      ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
02959                   }
02960                   analog_set_echocanceller(p, 1);
02961                }
02962             }
02963          }
02964       winkflashdone:
02965          analog_update_conf(p);
02966          break;
02967       case ANALOG_SIG_EM:
02968       case ANALOG_SIG_EM_E1:
02969       case ANALOG_SIG_FEATD:
02970       case ANALOG_SIG_SF:
02971       case ANALOG_SIG_SFWINK:
02972       case ANALOG_SIG_SF_FEATD:
02973       case ANALOG_SIG_FXSLS:
02974       case ANALOG_SIG_FXSGS:
02975          if (p->dialing) {
02976             ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
02977          } else {
02978             ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
02979          }
02980          break;
02981       case ANALOG_SIG_FEATDMF_TA:
02982          switch (p->whichwink) {
02983          case 0:
02984             ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
02985             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
02986             break;
02987          case 1:
02988             ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
02989             break;
02990          case 2:
02991             ast_log(LOG_WARNING, "Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA\n");
02992             return NULL;
02993          }
02994          p->whichwink++;
02995          /* Fall through */
02996       case ANALOG_SIG_FEATDMF:
02997       case ANALOG_SIG_E911:
02998       case ANALOG_SIG_FGC_CAMAMF:
02999       case ANALOG_SIG_FGC_CAMA:
03000       case ANALOG_SIG_FEATB:
03001       case ANALOG_SIG_SF_FEATDMF:
03002       case ANALOG_SIG_SF_FEATB:
03003       case ANALOG_SIG_EMWINK:
03004          /* FGD MF and EMWINK *Must* wait for wink */
03005          if (!ast_strlen_zero(p->dop.dialstr)) {
03006             res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
03007             if (res < 0) {
03008                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
03009                p->dop.dialstr[0] = '\0';
03010                return NULL;
03011             } else {
03012                ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
03013             }
03014          }
03015          p->dop.dialstr[0] = '\0';
03016          break;
03017       default:
03018          ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
03019       }
03020       break;
03021    case ANALOG_EVENT_HOOKCOMPLETE:
03022       if (p->inalarm) break;
03023       if (analog_check_waitingfordt(p)) break;
03024       switch (mysig) {
03025       case ANALOG_SIG_FXSLS:  /* only interesting for FXS */
03026       case ANALOG_SIG_FXSGS:
03027       case ANALOG_SIG_FXSKS:
03028       case ANALOG_SIG_EM:
03029       case ANALOG_SIG_EM_E1:
03030       case ANALOG_SIG_EMWINK:
03031       case ANALOG_SIG_FEATD:
03032       case ANALOG_SIG_SF:
03033       case ANALOG_SIG_SFWINK:
03034       case ANALOG_SIG_SF_FEATD:
03035          if (!ast_strlen_zero(p->dop.dialstr)) {
03036             res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
03037             if (res < 0) {
03038                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
03039                p->dop.dialstr[0] = '\0';
03040                return NULL;
03041             } else {
03042                ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
03043             }
03044          }
03045          p->dop.dialstr[0] = '\0';
03046          p->dop.op = ANALOG_DIAL_OP_REPLACE;
03047          break;
03048       case ANALOG_SIG_FEATDMF:
03049       case ANALOG_SIG_FEATDMF_TA:
03050       case ANALOG_SIG_E911:
03051       case ANALOG_SIG_FGC_CAMA:
03052       case ANALOG_SIG_FGC_CAMAMF:
03053       case ANALOG_SIG_FEATB:
03054       case ANALOG_SIG_SF_FEATDMF:
03055       case ANALOG_SIG_SF_FEATB:
03056          ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
03057          break;
03058       default:
03059          break;
03060       }
03061       break;
03062    case ANALOG_EVENT_POLARITY:
03063       /*
03064        * If we get a Polarity Switch event, this could be
03065        * due to line seizure, remote end connect or remote end disconnect.
03066        *
03067        * Check to see if we should change the polarity state and
03068        * mark the channel as UP or if this is an indication
03069        * of remote end disconnect.
03070        */
03071 
03072       if (p->polarityonanswerdelay > 0) {
03073          /* check if event is not too soon after OffHook or Answer */
03074 
03075          if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
03076             switch (ast->_state) {
03077             case AST_STATE_DIALING:       /*!< Digits (or equivalent) have been dialed */
03078             case AST_STATE_RINGING:       /*!< Remote end is ringing */
03079                if (p->answeronpolarityswitch) {
03080                   ast_debug(1, "Answering on polarity switch! channel %d\n", p->channel);
03081                   ast_setstate(p->owner, AST_STATE_UP);
03082                   p->polarity = POLARITY_REV;
03083                   if (p->hanguponpolarityswitch) {
03084                      p->polaritydelaytv = ast_tvnow();
03085                   }
03086                } else {
03087                   ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel);
03088                }
03089                break;
03090             case AST_STATE_UP:            /*!< Line is up */
03091             case AST_STATE_RING:       /*!< Line is ringing */
03092                if (p->hanguponpolarityswitch) {
03093                   ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel);
03094                   ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
03095                   p->polarity = POLARITY_IDLE;
03096                } else {
03097                   ast_debug(1, "Ignore Hangup on polarity switch, channel %d\n", p->channel);
03098                }
03099                break;
03100 
03101             case AST_STATE_DOWN:          /*!< Channel is down and available */
03102             case AST_STATE_RESERVED:         /*!< Channel is down, but reserved */
03103             case AST_STATE_OFFHOOK:          /*!< Channel is off hook */
03104             case AST_STATE_BUSY:          /*!< Line is busy */
03105             case AST_STATE_DIALING_OFFHOOK:     /*!< Digits (or equivalent) have been dialed while offhook */
03106             case AST_STATE_PRERING:          /*!< Channel has detected an incoming call and is waiting for ring */
03107             default:
03108                if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
03109                   ast_debug(1, "Ignoring Polarity switch on channel %d, state %d\n", p->channel, ast->_state);
03110                }
03111             }
03112 
03113          } else {
03114             /* event is too soon after OffHook or Answer */
03115             switch (ast->_state) {
03116             case AST_STATE_DIALING:    /*!< Digits (or equivalent) have been dialed */
03117             case AST_STATE_RINGING:    /*!< Remote end is ringing */
03118                if (p->answeronpolarityswitch) {
03119                   ast_debug(1, "Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %d\n", p->channel, ast->_state);
03120                }
03121                break;
03122 
03123             case AST_STATE_UP:         /*!< Line is up */
03124             case AST_STATE_RING:    /*!< Line is ringing */
03125                if (p->hanguponpolarityswitch) {
03126                   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);
03127                }
03128                break;
03129 
03130             default:
03131                if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
03132                   ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %d\n", p->channel, ast->_state);
03133                }
03134             }
03135          }
03136       }
03137 
03138       /* Added more log_debug information below to provide a better indication of what is going on */
03139       ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
03140       break;
03141    default:
03142       ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
03143    }
03144    return &p->subs[index].f;
03145 }

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

Definition at line 1469 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_dsp_reset_and_flush_digits(), analog_dsp_set_digitmode(), 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_echocanceller(), analog_set_linear_mode(), 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_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_CONTROL_UNHOLD, ast_copy_string(), ast_db_put(), ast_debug, ast_exists_extension(), 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(), 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_setstate(), ast_shrink_phone_number(), 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(), analog_pvt::call_forward, callerid_free(), callerid_get_dtmf(), analog_pvt::callreturn, analog_pvt::callwaiting, analog_pvt::cancallforward, analog_pvt::canpark, chan, analog_pvt::chan_tech, analog_pvt::channel, ast_channel::cid, ast_callerid::cid_name, analog_pvt::cid_name, ast_callerid::cid_num, analog_pvt::cid_num, CID_SIG_DTMF, CID_SIG_V23, CID_SIG_V23_JP, analog_pvt::cid_signalling, analog_pvt::cid_start, ast_channel::context, analog_dialoperation::dialstr, analog_pvt::dnd, analog_pvt::dop, errno, EVENT_FLAG_SYSTEM, ast_channel::exten, exten, f, callerid_state::flags, ast_frame::frametype, free, analog_pvt::hanguponpolarityswitch, analog_pvt::hidecallerid, analog_pvt::immediate, ISTRUNK, ast_channel::language, analog_pvt::lastcid_num, len(), LOG_DEBUG, LOG_WARNING, manager_event, ast_channel::name, name, analog_pvt::owner, analog_subchannel::owner, analog_pvt::polarity, POLARITY_IDLE, POLARITY_REV, quit, ast_channel::rings, analog_pvt::ringt, analog_pvt::ringt_base, analog_pvt::sig, analog_pvt::ss_astchan, strsep(), ast_frame::subclass, analog_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, analog_pvt::transfer, and analog_pvt::use_callerid.

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

01470 {
01471    struct analog_pvt *p = data;
01472    struct ast_channel *chan = p->ss_astchan;
01473    char exten[AST_MAX_EXTENSION] = "";
01474    char exten2[AST_MAX_EXTENSION] = "";
01475    char dtmfcid[300];
01476    char dtmfbuf[300];
01477    char namebuf[ANALOG_MAX_CID];
01478    char numbuf[ANALOG_MAX_CID];
01479    struct callerid_state *cs = NULL;
01480    char *name = NULL, *number = NULL;
01481    int flags = 0;
01482    int timeout;
01483    int getforward = 0;
01484    char *s1, *s2;
01485    int len = 0;
01486    int res;
01487    int index;
01488 
01489    analog_increase_ss_count(p);
01490 
01491    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
01492 
01493    if (!chan) {
01494       /* What happened to the channel? */
01495       goto quit;
01496    }
01497    /* in the bizarre case where the channel has become a zombie before we
01498       even get started here, abort safely
01499    */
01500    if (!chan->tech_pvt) {
01501       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
01502       ast_hangup(chan);
01503       goto quit;
01504    }
01505 
01506    ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
01507    index = analog_get_index(chan, p, 1);
01508    if (index < 0) {
01509       ast_log(LOG_WARNING, "Huh?\n");
01510       ast_hangup(chan);
01511       goto quit;
01512    }
01513    analog_dsp_reset_and_flush_digits(p);
01514    switch (p->sig) {
01515    case ANALOG_SIG_FEATD:
01516    case ANALOG_SIG_FEATDMF:
01517    case ANALOG_SIG_FEATDMF_TA:
01518    case ANALOG_SIG_E911:
01519    case ANALOG_SIG_FGC_CAMAMF:
01520    case ANALOG_SIG_FEATB:
01521    case ANALOG_SIG_EMWINK:
01522    case ANALOG_SIG_SF_FEATD:
01523    case ANALOG_SIG_SF_FEATDMF:
01524    case ANALOG_SIG_SF_FEATB:
01525    case ANALOG_SIG_SFWINK:
01526       if (analog_wink(p, index))
01527          goto quit;
01528       /* Fall through */
01529    case ANALOG_SIG_EM:
01530    case ANALOG_SIG_EM_E1:
01531    case ANALOG_SIG_SF:
01532    case ANALOG_SIG_FGC_CAMA:
01533       res = analog_play_tone(p, index, -1);
01534 
01535       analog_dsp_reset_and_flush_digits(p);
01536 
01537       if (ANALOG_NEED_MFDETECT(p)) {
01538          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);
01539       } else {
01540          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01541       }
01542 
01543       memset(dtmfbuf, 0, sizeof(dtmfbuf));
01544       /* Wait for the first digit only if immediate=no */
01545       if (!p->immediate) {
01546          /* Wait for the first digit (up to 5 seconds). */
01547          res = ast_waitfordigit(chan, 5000);
01548       } else {
01549          res = 0;
01550       }
01551       if (res > 0) {
01552          /* save first char */
01553          dtmfbuf[0] = res;
01554          switch (p->sig) {
01555          case ANALOG_SIG_FEATD:
01556          case ANALOG_SIG_SF_FEATD:
01557             res = analog_my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
01558             if (res > 0) {
01559                res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
01560             }
01561             if (res < 1) {
01562                analog_dsp_reset_and_flush_digits(p);
01563             }
01564             break;
01565          case ANALOG_SIG_FEATDMF_TA:
01566             res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01567             if (res < 1) {
01568                analog_dsp_reset_and_flush_digits(p);
01569             }
01570             if (analog_wink(p, index)) {
01571                goto quit;
01572             }
01573             dtmfbuf[0] = 0;
01574             /* Wait for the first digit (up to 5 seconds). */
01575             res = ast_waitfordigit(chan, 5000);
01576             if (res <= 0) {
01577                break;
01578             }
01579             dtmfbuf[0] = res;
01580             /* fall through intentionally */
01581          case ANALOG_SIG_FEATDMF:
01582          case ANALOG_SIG_E911:
01583          case ANALOG_SIG_FGC_CAMAMF:
01584          case ANALOG_SIG_SF_FEATDMF:
01585             res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01586             /* if international caca, do it again to get real ANO */
01587             if ((p->sig == ANALOG_SIG_FEATDMF) && (dtmfbuf[1] != '0') 
01588                && (strlen(dtmfbuf) != 14)) {
01589                if (analog_wink(p, index)) {
01590                   goto quit;
01591                }
01592                dtmfbuf[0] = 0;
01593                /* Wait for the first digit (up to 5 seconds). */
01594                res = ast_waitfordigit(chan, 5000);
01595                if (res <= 0) {
01596                   break;
01597                }
01598                dtmfbuf[0] = res;
01599                res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01600             }
01601             if (res > 0) {
01602                /* if E911, take off hook */
01603                if (p->sig == ANALOG_SIG_E911) {
01604                   analog_off_hook(p);
01605                }
01606                res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
01607             }
01608             if (res < 1) {
01609                analog_dsp_reset_and_flush_digits(p);
01610             }
01611             break;
01612          case ANALOG_SIG_FEATB:
01613          case ANALOG_SIG_SF_FEATB:
01614             res = analog_my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
01615             if (res < 1) {
01616                analog_dsp_reset_and_flush_digits(p);
01617             }
01618             break;
01619          case ANALOG_SIG_EMWINK:
01620             /* if we received a '*', we are actually receiving Feature Group D
01621                dial syntax, so use that mode; otherwise, fall through to normal
01622                mode
01623             */
01624             if (res == '*') {
01625                res = analog_my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
01626                if (res > 0) {
01627                   res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
01628                }
01629                if (res < 1) {
01630                   analog_dsp_reset_and_flush_digits(p);
01631                }
01632                break;
01633             }
01634          default:
01635             /* If we got the first digit, get the rest */
01636             len = 1;
01637             dtmfbuf[len] = '\0';
01638             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
01639                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
01640                   timeout = analog_matchdigittimeout;
01641                } else {
01642                   timeout = analog_gendigittimeout;
01643                }
01644                res = ast_waitfordigit(chan, timeout);
01645                if (res < 0) {
01646                   ast_debug(1, "waitfordigit returned < 0...\n");
01647                   ast_hangup(chan);
01648                   goto quit;
01649                } else if (res) {
01650                   dtmfbuf[len++] = res;
01651                   dtmfbuf[len] = '\0';
01652                } else {
01653                   break;
01654                }
01655             }
01656             break;
01657          }
01658       }
01659       if (res == -1) {
01660          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
01661          ast_hangup(chan);
01662          goto quit;
01663       } else if (res < 0) {
01664          ast_debug(1, "Got hung up before digits finished\n");
01665          ast_hangup(chan);
01666          goto quit;
01667       }
01668 
01669       if (p->sig == ANALOG_SIG_FGC_CAMA) {
01670          char anibuf[100];
01671 
01672          if (ast_safe_sleep(chan,1000) == -1) {
01673                            ast_hangup(chan);
01674                            goto quit;
01675          }
01676          analog_off_hook(p);
01677          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);
01678                         res = analog_my_getsigstr(chan, anibuf, "#", 10000);
01679                         if ((res > 0) && (strlen(anibuf) > 2)) {
01680             if (anibuf[strlen(anibuf) - 1] == '#') {
01681                anibuf[strlen(anibuf) - 1] = 0;
01682             }
01683             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
01684          }
01685          analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01686       }
01687 
01688       ast_copy_string(exten, dtmfbuf, sizeof(exten));
01689       if (ast_strlen_zero(exten)) {
01690          ast_copy_string(exten, "s", sizeof(exten));
01691       }
01692       if (p->sig == ANALOG_SIG_FEATD || p->sig == ANALOG_SIG_EMWINK) {
01693          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
01694          if (exten[0] == '*') {
01695             char *stringp=NULL;
01696             ast_copy_string(exten2, exten, sizeof(exten2));
01697             /* Parse out extension and callerid */
01698             stringp=exten2 +1;
01699             s1 = strsep(&stringp, "*");
01700             s2 = strsep(&stringp, "*");
01701             if (s2) {
01702                if (!ast_strlen_zero(p->cid_num)) {
01703                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
01704                } else {
01705                   ast_set_callerid(chan, s1, NULL, s1);
01706                }
01707                ast_copy_string(exten, s2, sizeof(exten));
01708             } else {
01709                ast_copy_string(exten, s1, sizeof(exten));
01710             }
01711          } else if (p->sig == ANALOG_SIG_FEATD) {
01712             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
01713          }
01714       }
01715       if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {
01716          if (exten[0] == '*') {
01717             char *stringp=NULL;
01718             ast_copy_string(exten2, exten, sizeof(exten2));
01719             /* Parse out extension and callerid */
01720             stringp=exten2 +1;
01721             s1 = strsep(&stringp, "#");
01722             s2 = strsep(&stringp, "#");
01723             if (s2) {
01724                if (!ast_strlen_zero(p->cid_num)) {
01725                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
01726                } else {
01727                   if (*(s1 + 2)) {
01728                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
01729                   }
01730                }
01731                ast_copy_string(exten, s2 + 1, sizeof(exten));
01732             } else {
01733                ast_copy_string(exten, s1 + 2, sizeof(exten));
01734             }
01735          } else {
01736             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
01737          }
01738       }
01739       if ((p->sig == ANALOG_SIG_E911) || (p->sig == ANALOG_SIG_FGC_CAMAMF)) {
01740          if (exten[0] == '*') {
01741             char *stringp=NULL;
01742             ast_copy_string(exten2, exten, sizeof(exten2));
01743             /* Parse out extension and callerid */
01744             stringp=exten2 +1;
01745             s1 = strsep(&stringp, "#");
01746             s2 = strsep(&stringp, "#");
01747             if (s2 && (*(s2 + 1) == '0')) {
01748                if (*(s2 + 2)) {
01749                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
01750                }
01751             }
01752             if (s1) {
01753                ast_copy_string(exten, s1, sizeof(exten));
01754             } else {
01755                ast_copy_string(exten, "911", sizeof(exten));
01756             }
01757          } else {
01758             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
01759          }
01760       }
01761       if (p->sig == ANALOG_SIG_FEATB) {
01762          if (exten[0] == '*') {
01763             char *stringp=NULL;
01764             ast_copy_string(exten2, exten, sizeof(exten2));
01765             /* Parse out extension and callerid */
01766             stringp=exten2 +1;
01767             s1 = strsep(&stringp, "#");
01768             ast_copy_string(exten, exten2 + 1, sizeof(exten));
01769          } else {
01770             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
01771          }
01772       }
01773       if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {
01774          analog_wink(p, index);
01775          /* some switches require a minimum guard time between
01776          the last FGD wink and something that answers
01777          immediately. This ensures it */
01778          if (ast_safe_sleep(chan,100)) {
01779             goto quit;
01780          }
01781       }
01782       analog_set_echocanceller(p, 1);
01783 
01784       analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01785 
01786       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
01787          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
01788          analog_dsp_reset_and_flush_digits(p);
01789          res = ast_pbx_run(chan);
01790          if (res) {
01791             ast_log(LOG_WARNING, "PBX exited non-zero\n");
01792             res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
01793          }
01794          goto quit;
01795       } else {
01796          ast_verb(3, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
01797          sleep(2);
01798          res = analog_play_tone(p, index, ANALOG_TONE_INFO);
01799          if (res < 0) {
01800             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
01801          } else {
01802             sleep(1);
01803          }
01804          res = ast_streamfile(chan, "ss-noservice", chan->language);
01805          if (res >= 0) {
01806             ast_waitstream(chan, "");
01807          }
01808          res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
01809          ast_hangup(chan);
01810          goto quit;
01811       }
01812       break;
01813    case ANALOG_SIG_FXOLS:
01814    case ANALOG_SIG_FXOGS:
01815    case ANALOG_SIG_FXOKS:
01816       /* Read the first digit */
01817       timeout = analog_firstdigittimeout;
01818       /* If starting a threeway call, never timeout on the first digit so someone
01819          can use flash-hook as a "hold" feature */
01820       if (p->subs[ANALOG_SUB_THREEWAY].owner) {
01821          timeout = 999999;
01822       }
01823       while (len < AST_MAX_EXTENSION-1) {
01824          /* Read digit unless it's supposed to be immediate, in which case the
01825             only answer is 's' */
01826          if (p->immediate) {
01827             res = 's';
01828          } else {
01829             res = ast_waitfordigit(chan, timeout);
01830          }
01831          timeout = 0;
01832          if (res < 0) {
01833             ast_debug(1, "waitfordigit returned < 0...\n");
01834             res = analog_play_tone(p, index, -1);
01835             ast_hangup(chan);
01836             goto quit;
01837          } else if (res) {
01838             exten[len++]=res;
01839             exten[len] = '\0';
01840          }
01841          if (!ast_ignore_pattern(chan->context, exten)) {
01842             analog_play_tone(p, index, -1);
01843          } else {
01844             analog_play_tone(p, index, ANALOG_TONE_DIALTONE);
01845          }
01846          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
01847             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
01848                if (getforward) {
01849                   /* Record this as the forwarding extension */
01850                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
01851                   ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
01852                   res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01853                   if (res) {
01854                      break;
01855                   }
01856                   usleep(500000);
01857                   res = analog_play_tone(p, index, -1);
01858                   sleep(1);
01859                   memset(exten, 0, sizeof(exten));
01860                   res = analog_play_tone(p, index, ANALOG_TONE_DIALTONE);
01861                   len = 0;
01862                   getforward = 0;
01863                } else {
01864                   res = analog_play_tone(p, index, -1);
01865                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
01866                   if (!ast_strlen_zero(p->cid_num)) {
01867                      if (!p->hidecallerid) {
01868                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
01869                      } else {
01870                         ast_set_callerid(chan, NULL, NULL, p->cid_num);
01871                      }
01872                   }
01873                   if (!ast_strlen_zero(p->cid_name)) {
01874                      if (!p->hidecallerid) {
01875                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
01876                      }
01877                   }
01878                   ast_setstate(chan, AST_STATE_RING);
01879                   analog_set_echocanceller(p, 1);
01880                   res = ast_pbx_run(chan);
01881                   if (res) {
01882                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
01883                      res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
01884                   }
01885                   goto quit;
01886                }
01887             } else {
01888                /* It's a match, but they just typed a digit, and there is an ambiguous match,
01889                   so just set the timeout to analog_matchdigittimeout and wait some more */
01890                timeout = analog_matchdigittimeout;
01891             }
01892          } else if (res == 0) {
01893             ast_debug(1, "not enough digits (and no ambiguous match)...\n");
01894             res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
01895             analog_wait_event(p);
01896             ast_hangup(chan);
01897             goto quit;
01898          } else if (p->callwaiting && !strcmp(exten, "*70")) {
01899             ast_verb(3, "Disabling call waiting on %s\n", chan->name);
01900             /* Disable call waiting if enabled */
01901             p->callwaiting = 0;
01902             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01903             if (res) {
01904                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
01905                   chan->name, strerror(errno));
01906             }
01907             len = 0;
01908             memset(exten, 0, sizeof(exten));
01909             timeout = analog_firstdigittimeout;
01910 
01911          } else if (!strcmp(exten,ast_pickup_ext())) {
01912             /* Scan all channels and see if there are any
01913              * ringing channels that have call groups
01914              * that equal this channels pickup group
01915              */
01916             if (index == ANALOG_SUB_REAL) {
01917                /* Switch us from Third call to Call Wait */
01918                if (p->subs[ANALOG_SUB_THREEWAY].owner) {
01919                   /* If you make a threeway call and the *8# a call, it should actually
01920                      look like a callwait */
01921                   analog_alloc_sub(p, ANALOG_SUB_CALLWAIT);
01922                   analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY);
01923                   analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01924                }
01925                analog_set_echocanceller(p, 1);
01926                if (ast_pickup_call(chan)) {
01927                   ast_debug(1, "No call pickup possible...\n");
01928                   res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
01929                   analog_wait_event(p);
01930                }
01931                ast_hangup(chan);
01932                goto quit;
01933             } else {
01934                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
01935                ast_hangup(chan);
01936                goto quit;
01937             }
01938          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
01939             ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
01940             /* Disable Caller*ID if enabled */
01941             p->hidecallerid = 1;
01942             if (chan->cid.cid_num) {
01943                free(chan->cid.cid_num);
01944             }
01945             chan->cid.cid_num = NULL;
01946             if (chan->cid.cid_name) {
01947                free(chan->cid.cid_name);
01948             }
01949             chan->cid.cid_name = NULL;
01950             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01951             if (res) {
01952                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
01953                   chan->name, strerror(errno));
01954             }
01955             len = 0;
01956             memset(exten, 0, sizeof(exten));
01957             timeout = analog_firstdigittimeout;
01958          } else if (p->callreturn && !strcmp(exten, "*69")) {
01959             res = 0;
01960             if (!ast_strlen_zero(p->lastcid_num)) {
01961                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
01962             }
01963             if (!res) {
01964                res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01965             }
01966             break;
01967          } else if (!strcmp(exten, "*78")) {
01968             /* Do not disturb */
01969             ast_verb(3, "Enabled DND on channel %d\n", p->channel);
01970             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
01971                      "Channel: DAHDI/%d\r\n"
01972                      "Status: enabled\r\n", p->channel);
01973             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01974             p->dnd = 1;
01975             getforward = 0;
01976             memset(exten, 0, sizeof(exten));
01977             len = 0;
01978          } else if (!strcmp(exten, "*79")) {
01979             /* Do not disturb */
01980             ast_verb(3, "Disabled DND on channel %d\n", p->channel);
01981             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
01982                      "Channel: DAHDI/%d\r\n"
01983                      "Status: disabled\r\n", p->channel);
01984             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01985             p->dnd = 0;
01986             getforward = 0;
01987             memset(exten, 0, sizeof(exten));
01988             len = 0;
01989          } else if (p->cancallforward && !strcmp(exten, "*72")) {
01990             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01991             getforward = 1;
01992             memset(exten, 0, sizeof(exten));
01993             len = 0;
01994          } else if (p->cancallforward && !strcmp(exten, "*73")) {
01995             ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
01996             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
01997             memset(p->call_forward, 0, sizeof(p->call_forward));
01998             getforward = 0;
01999             memset(exten, 0, sizeof(exten));
02000             len = 0;
02001          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) &&
02002                   p->subs[ANALOG_SUB_THREEWAY].owner &&
02003                   ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
02004             /* This is a three way call, the main call being a real channel,
02005                and we're parking the first call. */
02006             ast_masq_park_call(ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner), chan, 0, NULL);
02007             ast_verb(3, "Parking call to '%s'\n", chan->name);
02008             break;
02009          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
02010             ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);
02011             res = ast_db_put("blacklist", p->lastcid_num, "1");
02012             if (!res) {
02013                res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
02014                memset(exten, 0, sizeof(exten));
02015                len = 0;
02016             }
02017          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
02018             ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
02019             /* Enable Caller*ID if enabled */
02020             p->hidecallerid = 0;
02021             if (chan->cid.cid_num) {
02022                free(chan->cid.cid_num);
02023             }
02024             chan->cid.cid_num = NULL;
02025             if (chan->cid.cid_name) {
02026                free(chan->cid.cid_name);
02027             }
02028             chan->cid.cid_name = NULL;
02029             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
02030             res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
02031             if (res) {
02032                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
02033                   chan->name, strerror(errno));
02034             }
02035             len = 0;
02036             memset(exten, 0, sizeof(exten));
02037             timeout = analog_firstdigittimeout;
02038          } else if (!strcmp(exten, "*0")) {
02039             struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;
02040             struct analog_pvt *pbridge = NULL;
02041               /* set up the private struct of the bridged one, if any */
02042             if (nbridge && ast_bridged_channel(nbridge)) {
02043                pbridge = analog_get_bridged_channel(p, nbridge);
02044             }
02045             if (nbridge && pbridge &&
02046                 (nbridge->tech == p->chan_tech) &&
02047                 (ast_bridged_channel(nbridge)->tech == p->chan_tech) &&
02048                 ISTRUNK(pbridge)) {
02049                /* Clear out the dial buffer */
02050                p->dop.dialstr[0] = '\0';
02051                /* flash hookswitch */
02052                if ((analog_flash(p) == -1) && (errno != EINPROGRESS)) {
02053                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
02054                      nbridge->name, strerror(errno));
02055                }
02056                analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
02057                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
02058                p->owner = p->subs[ANALOG_SUB_REAL].owner;
02059                if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
02060                   ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
02061                }
02062                ast_hangup(chan);
02063                goto quit;
02064             } else {
02065                analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
02066                analog_wait_event(p);
02067                analog_play_tone(p, index, -1);
02068                analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
02069                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
02070                p->owner = p->subs[ANALOG_SUB_REAL].owner;
02071                ast_hangup(chan);
02072                goto quit;
02073             }
02074          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
02075                      ((exten[0] != '*') || (strlen(exten) > 2))) {
02076             ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
02077             break;
02078          }
02079          if (!timeout) {
02080             timeout = analog_gendigittimeout;
02081          }
02082          if (len && !ast_ignore_pattern(chan->context, exten)) {
02083             analog_play_tone(p, index, -1);
02084          }
02085       }
02086       break;
02087    case ANALOG_SIG_FXSLS:
02088    case ANALOG_SIG_FXSGS:
02089    case ANALOG_SIG_FXSKS:
02090 
02091       /* If we want caller id, we're in a prering state due to a polarity reversal
02092        * and we're set to use a polarity reversal to trigger the start of caller id,
02093        * grab the caller id and wait for ringing to start... */
02094       if (p->use_callerid && (chan->_state == AST_STATE_PRERING &&
02095               (p->cid_start == ANALOG_CID_START_POLARITY || p->cid_start == ANALOG_CID_START_POLARITY_IN || p->cid_start == ANALOG_CID_START_DTMF_NOALERT))) {
02096          /* If set to use DTMF CID signalling, listen for DTMF */
02097          if (p->cid_signalling == CID_SIG_DTMF) {
02098             int i = 0;
02099             int oldlinearity; 
02100             cs = NULL;
02101             ast_debug(1, "Receiving DTMF cid on "
02102                "channel %s\n", chan->name);
02103 
02104             oldlinearity = analog_set_linear_mode(p, index, 0);
02105 
02106             res = 2000;
02107             for (;;) {
02108                struct ast_frame *f;
02109                res = ast_waitfor(chan, res);
02110                if (res <= 0) {
02111                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
02112                      "Exiting simple switch\n");
02113                   ast_hangup(chan);
02114                   goto quit;
02115                }
02116                if (!(f = ast_read(chan))) {
02117                   break;
02118                }
02119                if (f->frametype == AST_FRAME_DTMF) {
02120                   dtmfbuf[i++] = f->subclass;
02121                   ast_debug(1, "CID got digit '%c'\n", f->subclass);
02122                   res = 2000;
02123                }
02124                ast_frfree(f);
02125                if (chan->_state == AST_STATE_RING || chan->_state == AST_STATE_RINGING) {
02126                   break; /* Got ring */
02127                }
02128             }
02129             dtmfbuf[i] = '\0';
02130 
02131             analog_set_linear_mode(p, index, oldlinearity);
02132 
02133             /* Got cid and ring. */
02134             ast_debug(1, "CID got string '%s'\n", dtmfbuf);
02135             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
02136             ast_debug(1, "CID is '%s', flags %d\n",
02137                dtmfcid, flags);
02138             /* If first byte is NULL, we have no cid */
02139             if (!ast_strlen_zero(dtmfcid)) {
02140                number = dtmfcid;
02141             } else {
02142                number = NULL;
02143             }
02144 
02145          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
02146          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
02147             int timeout = 10000;  /* Ten seconds */
02148             struct timeval start = ast_tvnow();
02149             enum analog_event ev;
02150 
02151             namebuf[0] = 0;
02152             numbuf[0] = 0;
02153 
02154             if (!analog_start_cid_detect(p, p->cid_signalling)) {
02155                while (1) {
02156                   res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start));
02157 
02158                   if (res == 0) {
02159                      break;
02160                   }
02161 
02162                   if (res == 1) {
02163                      if (p->cid_signalling == CID_SIG_V23_JP) {
02164                         if (ev == ANALOG_EVENT_RINGBEGIN) {
02165                            analog_off_hook(p);
02166                            usleep(1);
02167                         }
02168                      } else {
02169                         ev = ANALOG_EVENT_NONE;
02170                         break;
02171                      }
02172                   }
02173 
02174                   if (ast_tvdiff_ms(ast_tvnow(), start) > timeout)
02175                      break;
02176 
02177                }
02178                name = namebuf;
02179                number = numbuf;
02180 
02181                analog_stop_cid_detect(p);
02182 
02183                if (p->cid_signalling == CID_SIG_V23_JP) {
02184                   res = analog_on_hook(p);
02185                   usleep(1);
02186                   res = 4000;
02187                } else {
02188                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
02189                   res = 2000;
02190                }
02191 
02192                for (;;) {
02193                   struct ast_frame *f;
02194                   res = ast_waitfor(chan, res);
02195                   if (res <= 0) {
02196                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
02197                         "Exiting simple switch\n");
02198                      ast_hangup(chan);
02199                      goto quit;
02200                   }
02201                   if (!(f = ast_read(chan))) {
02202                      ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
02203                      ast_hangup(chan);
02204                      goto quit;
02205                   }
02206                   ast_frfree(f);
02207                   if (chan->_state == AST_STATE_RING ||
02208                      chan->_state == AST_STATE_RINGING)
02209                      break; /* Got ring */
02210                }
02211 
02212                if (analog_distinctive_ring(chan, p, index, NULL)) {
02213                   goto quit;
02214                }
02215 
02216                if (res < 0) {
02217                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
02218                }
02219             } else {
02220                ast_log(LOG_WARNING, "Unable to get caller ID space\n");
02221             }
02222 
02223          } else {
02224             ast_log(LOG_WARNING, "Channel %s in prering "
02225                "state, but I have nothing to do. "
02226                "Terminating simple switch, should be "
02227                "restarted by the actual ring.\n",
02228                chan->name);
02229             ast_hangup(chan);
02230             goto quit;
02231          }
02232       } else if (p->use_callerid && p->cid_start == ANALOG_CID_START_RING) {
02233          int timeout = 10000;  /* Ten seconds */
02234          struct timeval start = ast_tvnow();
02235          enum analog_event ev;
02236          int curRingData[3] = { 0 };
02237          int receivedRingT = 0;
02238 
02239          namebuf[0] = 0;
02240          numbuf[0] = 0;
02241 
02242          if (!analog_start_cid_detect(p, p->cid_signalling)) {
02243             while (1) {
02244                res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start));
02245 
02246                if (res == 0) {
02247                   break;
02248                }
02249 
02250                if (res == 1 || res == 2) {
02251                   if (ev == ANALOG_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
02252                      ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
02253                      p->polarity = POLARITY_IDLE;
02254                      ast_hangup(chan);
02255                      goto quit;
02256                   } else if (ev != ANALOG_EVENT_NONE && ev != ANALOG_EVENT_RINGBEGIN && ev != ANALOG_EVENT_RINGOFFHOOK) {
02257                      break;
02258                   }
02259                   if (res != 2) {
02260                      /* Let us detect callerid when the telco uses distinctive ring */
02261                      curRingData[receivedRingT] = p->ringt;
02262 
02263                      if (p->ringt < p->ringt_base/2) {
02264                         break;
02265                      }
02266                      /* Increment the ringT counter so we can match it against
02267                         values in chan_dahdi.conf for distinctive ring */
02268                      if (++receivedRingT == ARRAY_LEN(curRingData)) {
02269                         break;
02270                      }
02271                   }
02272                }
02273 
02274                if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) {
02275                   break;
02276                }
02277 
02278             }
02279             name = namebuf;
02280             number = numbuf;
02281 
02282             analog_stop_cid_detect(p);
02283 
02284             if (analog_distinctive_ring(chan, p, index, curRingData)) {
02285                goto quit;
02286             }
02287 
02288             if (res < 0) {
02289                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
02290             }
02291          } else {
02292             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
02293          }
02294       } else {
02295          cs = NULL;
02296       }
02297 
02298       if (number) {
02299          ast_shrink_phone_number(number);
02300       }
02301       ast_set_callerid(chan, number, name, number);
02302 
02303       if (cs) {
02304          callerid_free(cs);
02305       }
02306 
02307       analog_handle_notify_message(chan, p, flags, -1);
02308 
02309       ast_setstate(chan, AST_STATE_RING);
02310       chan->rings = 1;
02311       analog_set_ringtimeout(p, p->ringt_base);
02312       res = ast_pbx_run(chan);
02313       if (res) {
02314          ast_hangup(chan);
02315          ast_log(LOG_WARNING, "PBX exited non-zero\n");
02316       }
02317       goto quit;
02318    default:
02319       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);
02320       break;
02321    }
02322    res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
02323    if (res < 0) {
02324       ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
02325    }
02326    ast_hangup(chan);
02327 quit:
02328    analog_decrease_ss_count(p);
02329    return NULL;
02330 }

static void analog_all_subchannels_hungup ( struct analog_pvt p  )  [static]

Definition at line 484 of file sig_analog.c.

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

Referenced by analog_hangup().

00485 {
00486    if (p->calls->all_subchannels_hungup) {
00487       p->calls->all_subchannels_hungup(p->chan_pvt);
00488    }
00489 }

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

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

00324 {
00325    if (p->calls->allocate_sub) {
00326       int res;
00327       res = p->calls->allocate_sub(p->chan_pvt, x);
00328       if (!res) {
00329          p->subs[x].allocd = 1;
00330       }
00331       return res;
00332    }
00333    return 0;
00334 }

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1268 of file sig_analog.c.

References ast_channel::_state, analog_get_index(), analog_off_hook(), analog_play_tone(), analog_set_dialing(), 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_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), analog_train_echocanceller(), ast_debug, ast_log(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, analog_pvt::channel, analog_pvt::hanguponpolarityswitch, analog_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, ast_channel::name, analog_subchannel::owner, analog_pvt::owner, analog_pvt::polaritydelaytv, analog_pvt::sig, and analog_pvt::subs.

Referenced by dahdi_answer().

01269 {
01270    int res = 0;
01271    int index;
01272    int oldstate = ast->_state;
01273    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
01274    ast_setstate(ast, AST_STATE_UP);
01275    index = analog_get_index(ast, p, 1);
01276    if (index < 0) {
01277       index = ANALOG_SUB_REAL;
01278    }
01279    switch (p->sig) {
01280    case ANALOG_SIG_FXSLS:
01281    case ANALOG_SIG_FXSGS:
01282    case ANALOG_SIG_FXSKS:
01283       analog_set_ringtimeout(p, 0);
01284       /* Fall through */
01285    case ANALOG_SIG_EM:
01286    case ANALOG_SIG_EM_E1:
01287    case ANALOG_SIG_EMWINK:
01288    case ANALOG_SIG_FEATD:
01289    case ANALOG_SIG_FEATDMF:
01290    case ANALOG_SIG_FEATDMF_TA:
01291    case ANALOG_SIG_E911:
01292    case ANALOG_SIG_FGC_CAMA:
01293    case ANALOG_SIG_FGC_CAMAMF:
01294    case ANALOG_SIG_FEATB:
01295    case ANALOG_SIG_SF:
01296    case ANALOG_SIG_SFWINK:
01297    case ANALOG_SIG_SF_FEATD:
01298    case ANALOG_SIG_SF_FEATDMF:
01299    case ANALOG_SIG_SF_FEATB:
01300    case ANALOG_SIG_FXOLS:
01301    case ANALOG_SIG_FXOGS:
01302    case ANALOG_SIG_FXOKS:
01303       /* Pick up the line */
01304       ast_debug(1, "Took %s off hook\n", ast->name);
01305       if (p->hanguponpolarityswitch) {
01306          gettimeofday(&p->polaritydelaytv, NULL);
01307       }
01308       res = analog_off_hook(p);
01309       analog_play_tone(p, index, -1);
01310       analog_set_dialing(p, 0);
01311       if ((index == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
01312          if (oldstate == AST_STATE_RINGING) {
01313             ast_debug(1, "Finally swapping real and threeway\n");
01314             analog_play_tone(p, ANALOG_SUB_THREEWAY, -1);
01315             analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01316             p->owner = p->subs[ANALOG_SUB_REAL].owner;
01317          }
01318       }
01319       if ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || (p->sig == ANALOG_SIG_FXSGS)) {
01320          analog_set_echocanceller(p, 1);
01321          analog_train_echocanceller(p);
01322       }
01323       break;
01324    default:
01325       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
01326       res = -1;
01327    }
01328    ast_setstate(ast, AST_STATE_UP);
01329    return res;
01330 }

static int analog_attempt_transfer ( struct analog_pvt p  )  [static]

Definition at line 552 of file sig_analog.c.

References ast_channel::_state, analog_play_tone(), ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, analog_swap_subs(), ANALOG_TONE_RINGTONE, analog_unalloc_sub(), ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_masquerade(), ast_channel_unlock, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), ast_log(), ast_queue_control(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, analog_subchannel::inthreeway, ast_channel::linkedid, LOG_WARNING, ast_channel::name, analog_subchannel::owner, and analog_pvt::subs.

Referenced by __analog_handle_event().

00553 {
00554    /* In order to transfer, we need at least one of the channels to
00555       actually be in a call bridge.  We can't conference two applications
00556       together (but then, why would we want to?) */
00557    if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
00558       /* The three-way person we're about to transfer to could still be in MOH, so
00559          stop if now if appropriate */
00560       if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
00561          ast_queue_control(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
00562       }
00563       if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RINGING) {
00564          ast_indicate(ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner), AST_CONTROL_RINGING);
00565       }
00566       if (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_RING) {
00567          analog_play_tone(p, ANALOG_SUB_THREEWAY, ANALOG_TONE_RINGTONE);
00568       }
00569       if (!p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
00570          ast_cel_report_event(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CEL_ATTENDEDTRANSFER, NULL, p->subs[ANALOG_SUB_THREEWAY].owner->linkedid, NULL);
00571       }
00572       if (ast_channel_masquerade(p->subs[ANALOG_SUB_THREEWAY].owner, ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner))) {
00573          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
00574                ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)->name, p->subs[ANALOG_SUB_THREEWAY].owner->name);
00575          return -1;
00576       }
00577       /* Orphan the channel after releasing the lock */
00578       ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
00579       analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
00580    } else if (ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
00581       ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
00582       if (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
00583          ast_indicate(ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner), AST_CONTROL_RINGING);
00584       }
00585       if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RING) {
00586          analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE);
00587       }
00588       ast_cel_report_event(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CEL_BLINDTRANSFER, NULL, p->subs[ANALOG_SUB_THREEWAY].owner->linkedid, NULL);
00589       if (ast_channel_masquerade(p->subs[ANALOG_SUB_REAL].owner, ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner))) {
00590          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
00591                ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)->name, p->subs[ANALOG_SUB_REAL].owner->name);
00592          return -1;
00593       }
00594       /* Three-way is now the REAL */
00595       analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
00596       ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner); /* unlock REAL because THREEWAY has become REAL */
00597       analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
00598       /* Tell the caller not to hangup */
00599       return 1;
00600    } else {
00601       ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
00602                p->subs[ANALOG_SUB_REAL].owner->name, p->subs[ANALOG_SUB_THREEWAY].owner->name);
00603       ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
00604       return -1;
00605    }
00606    return 0;
00607 }

int analog_available ( struct analog_pvt p,
int  channelmatch,
ast_group_t  groupmatch,
int *  busy,
int *  channelmatched,
int *  groupmatched 
)

Definition at line 651 of file sig_analog.c.

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

Referenced by available().

00652 {
00653    int offhook;
00654 
00655    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
00656    /* We're at least busy at this point */
00657    if (busy) {
00658       if ((p->sig == ANALOG_SIG_FXOKS) || (p->sig == ANALOG_SIG_FXOLS) || (p->sig == ANALOG_SIG_FXOGS)) {
00659          *busy = 1;
00660       }
00661    }
00662    /* If do not disturb, definitely not */
00663    if (p->dnd) {
00664       return 0;
00665    }
00666    /* If guard time, definitely not */
00667    if (p->guardtime && (time(NULL) < p->guardtime)) {
00668       return 0;
00669    }
00670 
00671    /* If no owner definitely available */
00672    if (!p->owner) {
00673       if (p->sig == ANALOG_SIG_FXSLS) {
00674          return 1;
00675       }
00676 
00677       offhook = analog_is_off_hook(p);
00678 
00679       if ((p->sig == ANALOG_SIG_FXSKS) || (p->sig == ANALOG_SIG_FXSGS)) {
00680          /* When "onhook" that means no battery on the line, and thus
00681            it is out of service..., if it's on a TDM card... If it's a channel
00682            bank, there is no telling... */
00683          if (offhook) {
00684             return 1;
00685          }
00686          return 0;
00687       } else if (offhook) {
00688          ast_debug(1, "Channel %d off hook, can't use\n", p->channel);
00689          /* Not available when the other end is off hook */
00690          return 0;
00691       }
00692       return 1;
00693    }
00694 
00695    /* If it's not an FXO, forget about call wait */
00696    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
00697       return 0;
00698    }
00699 
00700    if (!p->callwaiting) {
00701       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
00702       return 0;
00703    }
00704 
00705    if (p->subs[ANALOG_SUB_CALLWAIT].allocd) {
00706       /* If there is already a call waiting call, then we can't take a second one */
00707       return 0;
00708    }
00709 
00710    if ((p->owner->_state != AST_STATE_UP) &&
00711        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
00712       /* If the current call is not up, then don't allow the call */
00713       return 0;
00714    }
00715    if ((p->subs[ANALOG_SUB_THREEWAY].owner) && (!p->subs[ANALOG_SUB_THREEWAY].inthreeway)) {
00716       /* Can't take a call wait when the three way calling hasn't been merged yet. */
00717       return 0;
00718    }
00719    /* We're cool */
00720    return 1;
00721 }

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

Definition at line 837 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_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_CONTROL_BUSY, AST_CONTROL_RINGING, ast_copy_string(), ast_debug, ast_log(), 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::callwait_name, analog_pvt::callwait_num, analog_pvt::callwaitcas, analog_pvt::channel, analog_pvt::cid, ast_callerid::cid_name, ast_callerid::cid_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, analog_pvt::lastcid_name, analog_pvt::lastcid_num, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_party_id::name, ast_party_id::number, analog_dialoperation::op, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, pbx_builtin_getvar_helper(), analog_pvt::polaritydelaytv, analog_pvt::pulse, analog_pvt::sig, analog_pvt::stripmsd, analog_pvt::subs, analog_pvt::use_callerid, and analog_pvt::whichwink.

Referenced by dahdi_call().

00838 {
00839    int res, index,mysig;
00840    char *c, *n, *l;
00841    char dest[256]; /* must be same length as p->dialdest */
00842 
00843    ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n", ast->connected.id.name, ast->connected.id.number);
00844 
00845    ast_copy_string(dest, rdest, sizeof(dest));
00846    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
00847 
00848    if ((ast->_state == AST_STATE_BUSY)) {
00849       ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_BUSY);
00850       return 0;
00851    }
00852 
00853    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
00854       ast_log(LOG_WARNING, "analog_call called on %s, neither down nor reserved\n", ast->name);
00855       return -1;
00856    }
00857 
00858    p->dialednone = 0;
00859 
00860    mysig = p->sig;
00861    if (p->outsigmod > -1) {
00862       mysig = p->outsigmod;
00863    }
00864 
00865    switch (mysig) {
00866    case ANALOG_SIG_FXOLS:
00867    case ANALOG_SIG_FXOGS:
00868    case ANALOG_SIG_FXOKS:
00869       if (p->owner == ast) {
00870          /* Normal ring, on hook */
00871 
00872          /* Don't send audio while on hook, until the call is answered */
00873          analog_set_dialing(p, 1);
00874          analog_set_cadence(p, ast); /* and set p->cidrings */
00875 
00876          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
00877          c = strchr(dest, '/');
00878          if (c) {
00879             c++;
00880          }
00881          if (c && (strlen(c) < p->stripmsd)) {
00882             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
00883             c = NULL;
00884          }
00885          if (c) {
00886             p->dop.op = ANALOG_DIAL_OP_REPLACE;
00887             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
00888             ast_debug(1, "FXO: setup deferred dialstring: %s\n", c);
00889          } else {
00890             p->dop.dialstr[0] = '\0';
00891          }
00892 
00893          if (analog_ring(p)) {
00894             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
00895             return -1;
00896          }
00897          analog_set_dialing(p, 1);
00898       } else {
00899          if (ast->connected.id.number) {
00900             ast_copy_string(p->callwait_num, ast->connected.id.number, sizeof(p->callwait_num));
00901          } else {
00902             p->callwait_num[0] = '\0';
00903          }
00904          if (ast->connected.id.name) {
00905             ast_copy_string(p->callwait_name, ast->connected.id.name, sizeof(p->callwait_name));
00906          } else {
00907             p->callwait_name[0] = '\0';
00908          }
00909 
00910          /* Call waiting tone instead */
00911          if (analog_callwait(p)) {
00912             return -1;
00913          }
00914          /* Make ring-back */
00915          if (analog_play_tone(p, ANALOG_SUB_CALLWAIT, ANALOG_TONE_RINGTONE)) {
00916             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
00917          }
00918 
00919       }
00920       n = ast->connected.id.name;
00921       l = ast->connected.id.number;
00922       if (l) {
00923          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
00924       } else {
00925          p->lastcid_num[0] = '\0';
00926       }
00927       if (n) {
00928          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
00929       } else {
00930          p->lastcid_name[0] = '\0';
00931       }
00932 
00933       if (p->use_callerid) {
00934          p->callwaitcas = 0;
00935          p->cid.cid_name = p->lastcid_name;
00936          p->cid.cid_num = p->lastcid_num;
00937       }
00938 
00939       ast_setstate(ast, AST_STATE_RINGING);
00940       index = analog_get_index(ast, p, 0);
00941       if (index > -1) {
00942          ast_queue_control(p->subs[index].owner, AST_CONTROL_RINGING);
00943       }
00944       break;
00945    case ANALOG_SIG_FXSLS:
00946    case ANALOG_SIG_FXSGS:
00947    case ANALOG_SIG_FXSKS:
00948       if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
00949          ast_debug(1, "Ignore possible polarity reversal on line seizure\n");
00950          p->polaritydelaytv = ast_tvnow();
00951       }
00952       /* fall through */
00953    case ANALOG_SIG_EMWINK:
00954    case ANALOG_SIG_EM:
00955    case ANALOG_SIG_EM_E1:
00956    case ANALOG_SIG_FEATD:
00957    case ANALOG_SIG_FEATDMF:
00958    case ANALOG_SIG_E911:
00959    case ANALOG_SIG_FGC_CAMA:
00960    case ANALOG_SIG_FGC_CAMAMF:
00961    case ANALOG_SIG_FEATB:
00962    case ANALOG_SIG_SFWINK:
00963    case ANALOG_SIG_SF:
00964    case ANALOG_SIG_SF_FEATD:
00965    case ANALOG_SIG_SF_FEATDMF:
00966    case ANALOG_SIG_FEATDMF_TA:
00967    case ANALOG_SIG_SF_FEATB:
00968       c = strchr(dest, '/');
00969       if (c) {
00970          c++;
00971       } else {
00972          c = "";
00973       }
00974       if (strlen(c) < p->stripmsd) {
00975          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
00976          return -1;
00977       }
00978       res = analog_start(p);
00979       if (res < 0) {
00980          if (errno != EINPROGRESS) {
00981             return -1;
00982          }
00983       }
00984       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
00985       p->dop.op = ANALOG_DIAL_OP_REPLACE;
00986 
00987       c += p->stripmsd;
00988 
00989       switch (mysig) {
00990       case ANALOG_SIG_FEATD:
00991          l = ast->connected.id.number;
00992          if (l) {
00993             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
00994          } else {
00995             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
00996          }
00997          break;
00998       case ANALOG_SIG_FEATDMF:
00999          l = ast->connected.id.number;
01000          if (l) {
01001             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01002          } else {
01003             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01004          }
01005          break;
01006       case ANALOG_SIG_FEATDMF_TA:
01007       {
01008          const char *cic = "", *ozz = "";
01009 
01010          /* If you have to go through a Tandem Access point you need to use this */
01011 #ifndef STANDALONE
01012          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01013          if (!ozz) {
01014             ozz = analog_defaultozz;
01015          }
01016          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01017          if (!cic) {
01018             cic = analog_defaultcic;
01019          }
01020 #endif
01021          if (!ozz || !cic) {
01022             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01023             return -1;
01024          }
01025          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01026          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01027          p->whichwink = 0;
01028       }
01029          break;
01030       case ANALOG_SIG_E911:
01031          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01032          break;
01033       case ANALOG_SIG_FGC_CAMA:
01034          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
01035          break;
01036       case ANALOG_SIG_FGC_CAMAMF:
01037       case ANALOG_SIG_FEATB:
01038          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
01039          break;
01040       default:
01041          if (p->pulse) {
01042             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
01043          } else {
01044             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
01045          }
01046          break;
01047       }
01048 
01049       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
01050          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
01051          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
01052          p->echorest[sizeof(p->echorest) - 1] = '\0';
01053          p->echobreak = 1;
01054          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
01055       } else {
01056          p->echobreak = 0;
01057       }
01058       analog_set_waitingfordt(p, ast);
01059       if (!res) {
01060          if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) {
01061             int saveerr = errno;
01062 
01063             analog_on_hook(p);
01064             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
01065             return -1;
01066          }
01067       } else {
01068          ast_debug(1, "Deferring dialing...\n");
01069       }
01070       analog_set_dialing(p, 1);
01071       if (ast_strlen_zero(c)) {
01072          p->dialednone = 1;
01073       }
01074       ast_setstate(ast, AST_STATE_DIALING);
01075       break;
01076    default:
01077       ast_debug(1, "not yet implemented\n");
01078       return -1;
01079    }
01080    return 0;
01081 }

static int analog_callwait ( struct analog_pvt p  )  [static]

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

00736 {
00737    if (p->callwaitingcallerid) {
00738       p->callwaitcas = 1;
00739    }
00740    if (p->calls->callwait) {
00741       return p->calls->callwait(p->chan_pvt);
00742    }
00743    return 0;
00744 }

static void analog_cancel_cidspill ( struct analog_pvt p  )  [static]

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

00804 {
00805    if (!p->calls->cancel_cidspill) {
00806       return;
00807    }
00808 
00809    p->calls->cancel_cidspill(p->chan_pvt);
00810 }

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

Definition at line 521 of file sig_analog.c.

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

Referenced by analog_handle_dtmfup().

00522 {
00523    if (p->calls->handle_dtmfup) {
00524       p->calls->handle_dtmfup(p->chan_pvt, ast, analog_index, dest);
00525    }
00526 }

static int analog_check_confirmanswer ( struct analog_pvt p  )  [static]

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

00795 {
00796    if (p->calls->check_confirmanswer) {
00797       return p->calls->check_confirmanswer(p->chan_pvt);
00798    }
00799 
00800    return 0;
00801 }

static int analog_check_for_conference ( struct analog_pvt p  )  [static]

Definition at line 476 of file sig_analog.c.

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

Referenced by __analog_handle_event().

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

static int analog_check_waitingfordt ( struct analog_pvt p  )  [static]

Definition at line 777 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00778 {
00779    if (p->calls->check_waitingfordt) {
00780       return p->calls->check_waitingfordt(p->chan_pvt);
00781    }
00782 
00783    return 0;
00784 }

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

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    switch (cid_start) {
00206    case ANALOG_CID_START_RING:
00207       return "Ring";
00208    case ANALOG_CID_START_POLARITY:
00209       return "Polarity";
00210    case ANALOG_CID_START_POLARITY_IN:
00211       return "Polarity_In";
00212    case ANALOG_CID_START_DTMF_NOALERT:
00213       return "DTMF";
00214    }
00215 
00216    return "Unknown";
00217 }

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 135 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00136 {
00137    int i;
00138 
00139    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00140       if (cid_type == cidtypes[i].cid_type) {
00141          return cidtypes[i].name;
00142       }
00143    }
00144 
00145    return "Unknown";
00146 }

int analog_config_complete ( struct analog_pvt p  ) 

Definition at line 3525 of file sig_analog.c.

References ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, analog_pvt::callwaiting, analog_pvt::permcallwaiting, and analog_pvt::sig.

Referenced by mkintf().

03526 {
03527    /* No call waiting on non FXS channels */
03528    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03529       p->permcallwaiting = 0;
03530    }
03531 
03532    p->callwaiting = p->permcallwaiting;
03533 
03534    return 0;
03535 }

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

Definition at line 812 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00813 {
00814    if (p->calls->confmute) {
00815       return p->calls->confmute(p->chan_pvt, mute);
00816    }
00817    return 0;
00818 }

static int analog_decrease_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1426 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01427 {
01428    if (p->calls->decrease_ss_count) {
01429       p->calls->decrease_ss_count();
01430       return 0;
01431    }
01432    return -1;
01433 }

void analog_delete ( struct analog_pvt doomed  ) 

Delete the analog private structure.

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

Definition at line 3520 of file sig_analog.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

03521 {
03522    ast_free(doomed);
03523 }

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

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

00461 {
00462    if (p->calls->dial_digits) {
00463       return p->calls->dial_digits(p->chan_pvt, sub, dop);
00464    }
00465    return -1;
00466 }

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

Definition at line 1435 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01436 {
01437    if (p->calls->distinctive_ring) {
01438       return p->calls->distinctive_ring(chan, p->chan_pvt, idx, ringdata);
01439    }
01440    return -1;
01441 
01442 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

Definition at line 3561 of file sig_analog.c.

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

Referenced by dahdi_dnd().

03562 {
03563    if (flag == -1) {
03564       return p->dnd;
03565    }
03566 
03567    p->dnd = flag;
03568 
03569    ast_verb(3, "%s DND on channel %d\n",
03570          flag? "Enabled" : "Disabled",
03571          p->channel);
03572    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03573          "Channel: DAHDI/%d\r\n"
03574          "Status: %s\r\n", p->channel,
03575          flag? "enabled" : "disabled");
03576 
03577    return 0;
03578 }

static int analog_dsp_reset_and_flush_digits ( struct analog_pvt p  )  [static]

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

00379 {
00380    if (p->calls->dsp_reset_and_flush_digits) {
00381       return p->calls->dsp_reset_and_flush_digits(p->chan_pvt);
00382    }
00383 
00384    /* Return 0 since I think this is unnecessary to do in most cases it is used.  Mostly only for ast_dsp */
00385    return 0;
00386 }

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

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

00514 {
00515    if (p->calls->dsp_set_digitmode) {
00516       return p->calls->dsp_set_digitmode(p->chan_pvt, mode);
00517    }
00518    return -1;
00519 }

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

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

00220 {
00221    char *res;
00222    switch (event) {
00223    case ANALOG_EVENT_ONHOOK:
00224       res = "ANALOG_EVENT_ONHOOK";
00225       break;
00226    case ANALOG_EVENT_RINGOFFHOOK:
00227       res = "ANALOG_EVENT_RINGOFFHOOK";
00228       break;
00229    case ANALOG_EVENT_WINKFLASH:
00230       res = "ANALOG_EVENT_WINKFLASH";
00231       break;
00232    case ANALOG_EVENT_ALARM:
00233       res = "ANALOG_EVENT_ALARM";
00234       break;
00235    case ANALOG_EVENT_NOALARM:
00236       res = "ANALOG_EVENT_NOALARM";
00237       break;
00238    case ANALOG_EVENT_DIALCOMPLETE:
00239       res = "ANALOG_EVENT_DIALCOMPLETE";
00240       break;
00241    case ANALOG_EVENT_HOOKCOMPLETE:
00242       res = "ANALOG_EVENT_HOOKCOMPLETE";
00243       break;
00244    case ANALOG_EVENT_PULSE_START:
00245       res = "ANALOG_EVENT_PULSE_START";
00246       break;
00247    case ANALOG_EVENT_POLARITY:
00248       res = "ANALOG_EVENT_POLARITY";
00249       break;
00250    case ANALOG_EVENT_RINGBEGIN:
00251       res = "ANALOG_EVENT_RINGBEGIN";
00252       break;
00253    case ANALOG_EVENT_EC_DISABLED:
00254       res = "ANALOG_EVENT_EC_DISABLED";
00255       break;
00256    case ANALOG_EVENT_RINGERON:
00257       res = "ANALOG_EVENT_RINGERON";
00258       break;
00259    case ANALOG_EVENT_RINGEROFF:
00260       res = "ANALOG_EVENT_RINGEROFF";
00261       break;
00262    case ANALOG_EVENT_REMOVED:
00263       res = "ANALOG_EVENT_REMOVED";
00264       break;
00265    case ANALOG_EVENT_NEONMWI_ACTIVE:
00266       res = "ANALOG_EVENT_NEONMWI_ACTIVE";
00267       break;
00268    case ANALOG_EVENT_NEONMWI_INACTIVE:
00269       res = "ANALOG_EVENT_NEONMWI_INACTIVE";
00270       break;
00271 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
00272    case ANALOG_EVENT_TX_CED_DETECTED:
00273       res = "ANALOG_EVENT_TX_CED_DETECTED";
00274       break;
00275    case ANALOG_EVENT_RX_CED_DETECTED:
00276       res = "ANALOG_EVENT_RX_CED_DETECTED";
00277       break;
00278    case ANALOG_EVENT_EC_NLP_DISABLED:
00279       res = "ANALOG_EVENT_EC_NLP_DISABLED";
00280       break;
00281    case ANALOG_EVENT_EC_NLP_ENABLED:
00282       res = "ANALOG_EVENT_EC_NLP_ENABLED";
00283       break;
00284 #endif
00285    case ANALOG_EVENT_PULSEDIGIT:
00286       res = "ANALOG_EVENT_PULSEDIGIT";
00287       break;
00288    case ANALOG_EVENT_DTMFDOWN:
00289       res = "ANALOG_EVENT_DTMFDOWN";
00290       break;
00291    case ANALOG_EVENT_DTMFUP:
00292       res = "ANALOG_EVENT_DTMFUP";
00293       break;
00294    default:
00295       res = "UNKNOWN/OTHER";
00296       break;
00297    }
00298 
00299    return res;
00300 }

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

Definition at line 3147 of file sig_analog.c.

References __analog_handle_event(), ast_channel::_state, analog_event2str(), ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_event(), analog_get_index(), analog_off_hook(), analog_ring(), analog_set_dialing(), analog_set_echocanceller(), analog_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, analog_subchannel::f, f, ast_channel::fds, analog_pvt::flashtime, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, ast_channel::name, ast_frame::offset, analog_subchannel::owner, analog_pvt::owner, ast_frame::ptr, ast_frame::samples, ast_frame::src, ast_frame::subclass, and analog_pvt::subs.

Referenced by dahdi_exception(), and dahdi_read().

03148 {
03149    int res;
03150    int usedindex=-1;
03151    int index;
03152    struct ast_frame *f;
03153 
03154    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
03155 
03156    index = analog_get_index(ast, p, 1);
03157 
03158    p->subs[index].f.frametype = AST_FRAME_NULL;
03159    p->subs[index].f.datalen = 0;
03160    p->subs[index].f.samples = 0;
03161    p->subs[index].f.mallocd = 0;
03162    p->subs[index].f.offset = 0;
03163    p->subs[index].f.subclass = 0;
03164    p->subs[index].f.delivery = ast_tv(0,0);
03165    p->subs[index].f.src = "dahdi_exception";
03166    p->subs[index].f.data.ptr = NULL;
03167 
03168 
03169    if (!p->owner) {
03170       /* If nobody owns us, absorb the event appropriately, otherwise
03171          we loop indefinitely.  This occurs when, during call waiting, the
03172          other end hangs up our channel so that it no longer exists, but we
03173          have neither FLASH'd nor ONHOOK'd to signify our desire to
03174          change to the other channel. */
03175       res = analog_get_event(p);
03176 
03177       /* Switch to real if there is one and this isn't something really silly... */
03178       if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
03179          (res != ANALOG_EVENT_HOOKCOMPLETE)) {
03180          ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
03181          p->owner = p->subs[ANALOG_SUB_REAL].owner;
03182          if (p->owner && ast_bridged_channel(p->owner)) {
03183             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03184          }
03185       }
03186       switch (res) {
03187       case ANALOG_EVENT_ONHOOK:
03188          analog_set_echocanceller(p, 0);
03189          if (p->owner) {
03190             ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name);
03191             analog_ring(p);
03192             analog_stop_callwait(p);
03193          } else {
03194             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
03195          }
03196          analog_update_conf(p);
03197          break;
03198       case ANALOG_EVENT_RINGOFFHOOK:
03199          analog_set_echocanceller(p, 1);
03200          analog_off_hook(p);
03201          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
03202             ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
03203             analog_set_dialing(p, 0);
03204          }
03205          break;
03206       case ANALOG_EVENT_HOOKCOMPLETE:
03207       case ANALOG_EVENT_RINGERON:
03208       case ANALOG_EVENT_RINGEROFF:
03209          /* Do nothing */
03210          break;
03211       case ANALOG_EVENT_WINKFLASH:
03212          gettimeofday(&p->flashtime, NULL);
03213          if (p->owner) {
03214             ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
03215             if (p->owner->_state != AST_STATE_UP) {
03216                /* Answer if necessary */
03217                usedindex = analog_get_index(p->owner, p, 0);
03218                if (usedindex > -1) {
03219                   ast_queue_control(p->subs[usedindex].owner, AST_CONTROL_ANSWER);
03220                }
03221                ast_setstate(p->owner, AST_STATE_UP);
03222             }
03223             analog_stop_callwait(p);
03224             if (ast_bridged_channel(p->owner)) {
03225                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03226             }
03227          } else {
03228             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
03229          }
03230          analog_update_conf(p);
03231          break;
03232       default:
03233          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res));
03234       }
03235       f = &p->subs[index].f;
03236       return f;
03237    }
03238    ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
03239    /* If it's not us, return NULL immediately */
03240    if (ast != p->owner) {
03241       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
03242       f = &p->subs[index].f;
03243       return f;
03244    }
03245    f = __analog_handle_event(p, ast);
03246    return f;
03247 }

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

Definition at line 3543 of file sig_analog.c.

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

Referenced by dahdi_fixup().

03544 {
03545    struct analog_pvt *new_pvt = newp;
03546    int x;
03547    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03548    if (new_pvt->owner == oldchan) {
03549       new_pvt->owner = newchan;
03550    }
03551    for (x = 0; x < 3; x++) {
03552       if (new_pvt->subs[x].owner == oldchan) {
03553          new_pvt->subs[x].owner = newchan;
03554       }
03555    }
03556 
03557    analog_update_conf(new_pvt);
03558    return 0;
03559 }

static int analog_flash ( struct analog_pvt p  )  [static]

Definition at line 444 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00445 {
00446    if (p->calls->flash) {
00447       return p->calls->flash(p->chan_pvt);
00448    }
00449    return -1;
00450 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3537 of file sig_analog.c.

References free.

03538 {
03539    free(p);
03540 }

static void analog_get_and_handle_alarms ( struct analog_pvt p  )  [static]

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

01445 {
01446    if (p->calls->get_and_handle_alarms) {
01447       return p->calls->get_and_handle_alarms(p->chan_pvt);
01448    }
01449 }

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

Definition at line 1451 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01452 {
01453    if (p->calls->get_sigpvt_bridged_channel) {
01454       return p->calls->get_sigpvt_bridged_channel;
01455    }
01456    return NULL;
01457 }

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

Definition at line 164 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00165 {
00166    if (p->calls->get_callerid) {
00167       return p->calls->get_callerid(p->chan_pvt, name, number, ev, timeout);
00168    }
00169    return -1;
00170 }

static int analog_get_event ( struct analog_pvt p  )  [static]

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

00173 {
00174    if (p->calls->get_event) {
00175       return p->calls->get_event(p->chan_pvt);
00176    }
00177    return -1;
00178 }

static int analog_get_index ( struct ast_channel ast,
struct analog_pvt p,
int  nullok 
) [static]

Definition at line 360 of file sig_analog.c.

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

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

00361 {
00362    int res;
00363    if (p->subs[ANALOG_SUB_REAL].owner == ast) {
00364       res = ANALOG_SUB_REAL;
00365    } else if (p->subs[ANALOG_SUB_CALLWAIT].owner == ast) {
00366       res = ANALOG_SUB_CALLWAIT;
00367    } else if (p->subs[ANALOG_SUB_THREEWAY].owner == ast) {
00368       res = ANALOG_SUB_THREEWAY;
00369    } else {
00370       res = -1;
00371       if (!nullok) {
00372          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00373       }
00374    }
00375    return res;
00376 }

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

Definition at line 1459 of file sig_analog.c.

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

Referenced by __analog_handle_event().

01460 {
01461    if (p->calls->get_sub_fd) {
01462       return p->calls->get_sub_fd(p->chan_pvt, sub);
01463    }
01464    return -1;
01465 }

void analog_handle_dtmfup ( struct analog_pvt p,
struct ast_channel ast,
enum analog_sub  index,
struct ast_frame **  dest 
)

Definition at line 1357 of file sig_analog.c.

References analog_cb_handle_dtmfup(), analog_check_confirmanswer(), analog_handles_digit(), analog_send_callerid(), analog_set_confirmanswer(), AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), analog_pvt::callwait_name, analog_pvt::callwait_num, analog_pvt::callwaitcas, analog_pvt::cid, ast_callerid::cid_name, ast_callerid::cid_num, analog_subchannel::f, f, ast_frame::frametype, LOG_ERROR, ast_channel::name, ast_frame::subclass, and analog_pvt::subs.

Referenced by __analog_handle_event(), and dahdi_read().

01358 {
01359    struct ast_frame *f = *dest;
01360 
01361    if (analog_check_confirmanswer(p)) {
01362       ast_debug(1, "Confirm answer on %s!\n", ast->name);
01363       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
01364       of a DTMF digit */
01365       p->subs[index].f.frametype = AST_FRAME_CONTROL;
01366       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
01367       *dest = &p->subs[index].f;
01368       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
01369       analog_set_confirmanswer(p, 0);
01370    }
01371    if (p->callwaitcas) {
01372       if ((f->subclass == 'A') || (f->subclass == 'D')) {
01373          ast_log(LOG_ERROR, "Got some DTMF, but it's for the CAS\n");
01374          p->cid.cid_name = p->callwait_name;
01375          p->cid.cid_num = p->callwait_num;
01376          analog_send_callerid(p, 1, &p->cid);
01377       }
01378       if (analog_handles_digit(f))
01379          p->callwaitcas = 0;
01380       p->subs[index].f.frametype = AST_FRAME_NULL;
01381       p->subs[index].f.subclass = 0;
01382       *dest = &p->subs[index].f;
01383    } else {
01384       analog_cb_handle_dtmfup(p, ast, index, dest);
01385    }
01386 }

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3249 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_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_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_verbose, chan, 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, analog_pvt::ss_astchan, analog_pvt::unknown_alarm, and VERBOSE_PREFIX_2.

Referenced by do_monitor().

03250 {
03251    int res;
03252    pthread_t threadid;
03253    struct ast_channel *chan;
03254 
03255    ast_debug(1, "channel (%d) - signaling (%d) - event (%s)\n",
03256             i->channel, i->sig, analog_event2str(event));
03257 
03258    /* Handle an event on a given channel for the monitor thread. */
03259    switch (event) {
03260    case ANALOG_EVENT_WINKFLASH:
03261    case ANALOG_EVENT_RINGOFFHOOK:
03262       if (i->inalarm) {
03263          break;
03264       }
03265       /* Got a ring/answer.  What kind of channel are we? */
03266       switch (i->sig) {
03267       case ANALOG_SIG_FXOLS:
03268       case ANALOG_SIG_FXOGS:
03269       case ANALOG_SIG_FXOKS:
03270          res = analog_off_hook(i);
03271          i->fxsoffhookstate = 1;
03272          if (res && (errno == EBUSY)) {
03273             break;
03274          }
03275          analog_cancel_cidspill(i);
03276          if (i->immediate) {
03277             analog_set_echocanceller(i, 1);
03278             /* The channel is immediately up.  Start right away */
03279             res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE);
03280             chan = analog_new_ast_channel(i, AST_STATE_RING, 1, ANALOG_SUB_REAL, NULL);
03281             if (!chan) {
03282                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
03283                res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03284                if (res < 0) {
03285                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03286                }
03287             }
03288          } else {
03289             /* Check for callerid, digits, etc */
03290             chan = analog_new_ast_channel(i, AST_STATE_RESERVED, 0, ANALOG_SUB_REAL, NULL);
03291             i->ss_astchan = chan;
03292             if (chan) {
03293                if (analog_has_voicemail(i)) {
03294                   res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER);
03295                } else {
03296                   res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE);
03297                }
03298                if (res < 0)
03299                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
03300 
03301                if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03302                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03303                   res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03304                   if (res < 0) {
03305                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03306                   }
03307                   ast_hangup(chan);
03308                }
03309             } else
03310                ast_log(LOG_WARNING, "Unable to create channel\n");
03311          }
03312          break;
03313       case ANALOG_SIG_FXSLS:
03314       case ANALOG_SIG_FXSGS:
03315       case ANALOG_SIG_FXSKS:
03316          analog_set_ringtimeout(i, i->ringt_base);
03317          /* Fall through */
03318       case ANALOG_SIG_EMWINK:
03319       case ANALOG_SIG_FEATD:
03320       case ANALOG_SIG_FEATDMF:
03321       case ANALOG_SIG_FEATDMF_TA:
03322       case ANALOG_SIG_E911:
03323       case ANALOG_SIG_FGC_CAMA:
03324       case ANALOG_SIG_FGC_CAMAMF:
03325       case ANALOG_SIG_FEATB:
03326       case ANALOG_SIG_EM:
03327       case ANALOG_SIG_EM_E1:
03328       case ANALOG_SIG_SFWINK:
03329       case ANALOG_SIG_SF_FEATD:
03330       case ANALOG_SIG_SF_FEATDMF:
03331       case ANALOG_SIG_SF_FEATB:
03332       case ANALOG_SIG_SF:
03333          /* Check for callerid, digits, etc */
03334          if (i->cid_start == ANALOG_CID_START_POLARITY_IN || i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
03335             chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
03336          } else {
03337             chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL);
03338          }
03339          i->ss_astchan = chan;
03340          if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03341             ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03342             res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03343             if (res < 0) {
03344                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03345             }
03346             ast_hangup(chan);
03347          } else if (!chan) {
03348             ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
03349          }
03350          break;
03351       default:
03352          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);
03353          res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
03354          if (res < 0) {
03355             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
03356          }
03357          return NULL;
03358       }
03359       break;
03360    case ANALOG_EVENT_NOALARM:
03361       i->inalarm = 0;
03362       if (!i->unknown_alarm) {
03363          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
03364          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
03365                   "Channel: %d\r\n", i->channel);
03366       } else {
03367          i->unknown_alarm = 0;
03368       }
03369       break;
03370    case ANALOG_EVENT_ALARM:
03371       i->inalarm = 1;
03372       analog_get_and_handle_alarms(i);
03373 
03374       /* fall thru intentionally */
03375    case ANALOG_EVENT_ONHOOK:
03376       /* Back on hook.  Hang up. */
03377       switch (i->sig) {
03378       case ANALOG_SIG_FXOLS:
03379       case ANALOG_SIG_FXOGS:
03380          i->fxsoffhookstate = 0;
03381       case ANALOG_SIG_FEATD:
03382       case ANALOG_SIG_FEATDMF:
03383       case ANALOG_SIG_FEATDMF_TA:
03384       case ANALOG_SIG_E911:
03385       case ANALOG_SIG_FGC_CAMA:
03386       case ANALOG_SIG_FGC_CAMAMF:
03387       case ANALOG_SIG_FEATB:
03388       case ANALOG_SIG_EM:
03389       case ANALOG_SIG_EM_E1:
03390       case ANALOG_SIG_EMWINK:
03391       case ANALOG_SIG_SF_FEATD:
03392       case ANALOG_SIG_SF_FEATDMF:
03393       case ANALOG_SIG_SF_FEATB:
03394       case ANALOG_SIG_SF:
03395       case ANALOG_SIG_SFWINK:
03396       case ANALOG_SIG_FXSLS:
03397       case ANALOG_SIG_FXSGS:
03398       case ANALOG_SIG_FXSKS:
03399          analog_set_echocanceller(i, 0);
03400          res = analog_play_tone(i, ANALOG_SUB_REAL, -1);
03401          analog_on_hook(i);
03402          break;
03403       case ANALOG_SIG_FXOKS:
03404          i->fxsoffhookstate = 0;
03405          analog_set_echocanceller(i, 0);
03406          /* Diddle the battery for the zhone */
03407 #ifdef ZHONE_HACK
03408          analog_off_hook(i);
03409          usleep(1);
03410 #endif
03411          res = analog_play_tone(i, ANALOG_SUB_REAL, -1);
03412          analog_on_hook(i);
03413          break;
03414       default:
03415          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);
03416          res = analog_play_tone(i, ANALOG_SUB_REAL, -1);
03417          return NULL;
03418       }
03419       break;
03420    case ANALOG_EVENT_POLARITY:
03421       switch (i->sig) {
03422       case ANALOG_SIG_FXSLS:
03423       case ANALOG_SIG_FXSKS:
03424       case ANALOG_SIG_FXSGS:
03425          /* We have already got a PR before the channel was
03426             created, but it wasn't handled. We need polarity
03427             to be REV for remote hangup detection to work.
03428             At least in Spain */
03429          if (i->hanguponpolarityswitch) {
03430             i->polarity = POLARITY_REV;
03431          }
03432 
03433          if (i->cid_start == ANALOG_CID_START_POLARITY || i->cid_start == ANALOG_CID_START_POLARITY_IN) {
03434             i->polarity = POLARITY_REV;
03435             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
03436                    "CID detection on channel %d\n",
03437                    i->channel);
03438             chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
03439             i->ss_astchan = chan;
03440             if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03441                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03442             }
03443          }
03444          break;
03445       default:
03446          ast_log(LOG_WARNING, "handle_init_event detected "
03447             "polarity reversal on non-FXO (ANALOG_SIG_FXS) "
03448             "interface %d\n", i->channel);
03449       }
03450       break;
03451    case ANALOG_EVENT_DTMFCID:
03452       switch (i->sig) {
03453          case ANALOG_SIG_FXSLS:
03454          case ANALOG_SIG_FXSKS:
03455          case ANALOG_SIG_FXSGS:
03456             if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
03457                ast_verbose(VERBOSE_PREFIX_2 "Starting DTMF CID detection on channel %d\n",
03458                         i->channel);
03459                chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
03460                i->ss_astchan = chan;
03461                if (chan && ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, i)) {
03462                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
03463                }
03464             }
03465             break;
03466          default:
03467             ast_log(LOG_WARNING, "handle_init_event detected "
03468                   "dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) "
03469                         "interface %d\n", i->channel);
03470       }
03471       break;
03472    case ANALOG_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
03473         ast_log(LOG_NOTICE,
03474                 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
03475                 i->channel);
03476         return i->chan_pvt;
03477         break;
03478    case ANALOG_EVENT_NEONMWI_ACTIVE:
03479       analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_ACTIVE);
03480       break;
03481    case ANALOG_EVENT_NEONMWI_INACTIVE:
03482       analog_handle_notify_message(NULL, i, -1, ANALOG_EVENT_NEONMWI_INACTIVE);
03483       break;
03484    }
03485    return NULL;
03486 }

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

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

01409 {
01410    if (p->calls->handle_notify_message) {
01411       p->calls->handle_notify_message(chan, p->chan_pvt, cid_flags, neon_mwievent);
01412       return 0;
01413    }
01414    return -1;
01415 }

static int analog_handles_digit ( struct ast_frame f  )  [static]

Definition at line 1332 of file sig_analog.c.

References ast_frame::subclass.

Referenced by analog_handle_dtmfup().

01333 {
01334    char subclass = toupper(f->subclass);
01335 
01336    switch (subclass) {
01337    case '1':
01338    case '2':
01339    case '3':
01340    case '4':
01341    case '5':
01342    case '6':
01343    case '7':
01344    case '9':
01345    case 'A':
01346    case 'B':
01347    case 'C':
01348    case 'D':
01349    case 'E':
01350    case 'F':
01351       return 1;
01352    default:
01353       return 0;
01354    }
01355 }

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1083 of file sig_analog.c.

References ast_channel::_state, analog_subchannel::allocd, analog_all_subchannels_hungup(), ANALOG_DIGITMODE_DTMF, analog_dsp_set_digitmode(), analog_get_index(), analog_is_off_hook(), analog_on_hook(), analog_play_tone(), analog_set_confirmanswer(), analog_set_dialing(), analog_set_echocanceller(), analog_set_linear_mode(), 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_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_log(), AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), ast_verb, analog_pvt::callwaitcas, analog_pvt::callwaiting, analog_pvt::channel, analog_pvt::cid_name, analog_pvt::cid_num, analog_pvt::cidrings, free, analog_pvt::guardtime, analog_pvt::hidecallerid, analog_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, analog_pvt::mohsuggest, ast_channel::name, analog_pvt::onhooktime, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::outgoing, analog_pvt::owner, analog_subchannel::owner, analog_pvt::permcallwaiting, analog_pvt::permhidecallerid, analog_pvt::polarity, POLARITY_IDLE, S_OR, analog_pvt::sig, analog_pvt::subs, and ast_channel::tech_pvt.

Referenced by dahdi_hangup().

01084 {
01085    int res;
01086    int index, x;
01087 
01088    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
01089    if (!ast->tech_pvt) {
01090       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
01091       return 0;
01092    }
01093 
01094    index = analog_get_index(ast, p, 1);
01095 
01096    x = 0;
01097    if (p->origcid_num) {
01098       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
01099       free(p->origcid_num);
01100       p->origcid_num = NULL;
01101    }
01102    if (p->origcid_name) {
01103       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
01104       free(p->origcid_name);
01105       p->origcid_name = NULL;
01106    }
01107 
01108    analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
01109 
01110    ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
01111       p->channel, index, p->subs[ANALOG_SUB_REAL].allocd, p->subs[ANALOG_SUB_CALLWAIT].allocd, p->subs[ANALOG_SUB_THREEWAY].allocd);
01112    if (index > -1) {
01113       /* Real channel, do some fixup */
01114       p->subs[index].owner = NULL;
01115       p->polarity = POLARITY_IDLE;
01116       analog_set_linear_mode(p, index, 0);
01117       if (index == ANALOG_SUB_REAL) {
01118          if (p->subs[ANALOG_SUB_CALLWAIT].allocd && p->subs[ANALOG_SUB_THREEWAY].allocd) {
01119             ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
01120             if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
01121                /* We had flipped over to answer a callwait and now it's gone */
01122                ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
01123                /* Move to the call-wait, but un-own us until they flip back. */
01124                analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
01125                analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
01126                p->owner = NULL;
01127             } else {
01128                /* The three way hung up, but we still have a call wait */
01129                ast_debug(1, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
01130                analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01131                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01132                if (p->subs[ANALOG_SUB_REAL].inthreeway) {
01133                   /* This was part of a three way call.  Immediately make way for
01134                      another call */
01135                   ast_debug(1, "Call was complete, setting owner to former third call\n");
01136                   p->owner = p->subs[ANALOG_SUB_REAL].owner;
01137                } else {
01138                   /* This call hasn't been completed yet...  Set owner to NULL */
01139                   ast_debug(1, "Call was incomplete, setting owner to NULL\n");
01140                   p->owner = NULL;
01141                }
01142                p->subs[ANALOG_SUB_REAL].inthreeway = 0;
01143             }
01144          } else if (p->subs[ANALOG_SUB_CALLWAIT].allocd) {
01145             /* Move to the call-wait and switch back to them. */
01146             analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
01147             analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
01148             p->owner = p->subs[ANALOG_SUB_REAL].owner;
01149             if (p->owner->_state != AST_STATE_UP) {
01150                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
01151             }
01152             if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
01153                ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
01154             }
01155          } else if (p->subs[ANALOG_SUB_THREEWAY].allocd) {
01156             analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01157             analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01158             if (p->subs[ANALOG_SUB_REAL].inthreeway) {
01159                /* This was part of a three way call.  Immediately make way for
01160                   another call */
01161                ast_debug(1, "Call was complete, setting owner to former third call\n");
01162                p->owner = p->subs[ANALOG_SUB_REAL].owner;
01163             } else {
01164                /* This call hasn't been completed yet...  Set owner to NULL */
01165                ast_debug(1, "Call was incomplete, setting owner to NULL\n");
01166                p->owner = NULL;
01167             }
01168             p->subs[ANALOG_SUB_REAL].inthreeway = 0;
01169          }
01170       } else if (index == ANALOG_SUB_CALLWAIT) {
01171          /* Ditch the holding callwait call, and immediately make it availabe */
01172          if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
01173             /* This is actually part of a three way, placed on hold.  Place the third part
01174                on music on hold now */
01175             if (p->subs[ANALOG_SUB_THREEWAY].owner && ast_bridged_channel(p->subs[ANALOG_SUB_THREEWAY].owner)) {
01176                ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD,
01177                   S_OR(p->mohsuggest, NULL),
01178                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
01179             }
01180             p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
01181             /* Make it the call wait now */
01182             analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY);
01183             analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01184          } else {
01185             analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
01186          }
01187       } else if (index == ANALOG_SUB_THREEWAY) {
01188          if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
01189             /* The other party of the three way call is currently in a call-wait state.
01190                Start music on hold for them, and take the main guy out of the third call */
01191             if (p->subs[ANALOG_SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) {
01192                ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
01193                   S_OR(p->mohsuggest, NULL),
01194                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
01195             }
01196             p->subs[ANALOG_SUB_CALLWAIT].inthreeway = 0;
01197          }
01198          p->subs[ANALOG_SUB_REAL].inthreeway = 0;
01199          /* If this was part of a three way call index, let us make
01200             another three way call */
01201          analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
01202       } else {
01203          /* This wasn't any sort of call, but how are we an index? */
01204          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
01205       }
01206    }
01207 
01208    if (!p->subs[ANALOG_SUB_REAL].owner && !p->subs[ANALOG_SUB_CALLWAIT].owner && !p->subs[ANALOG_SUB_THREEWAY].owner) {
01209       p->owner = NULL;
01210       analog_set_ringtimeout(p, 0);
01211       analog_set_confirmanswer(p, 0);
01212       analog_set_pulsedial(p, 0);
01213       p->outgoing = 0;
01214       p->onhooktime = time(NULL);
01215       p->cidrings = 1;
01216 
01217       /* Perform low level hangup if no owner left */
01218       res = analog_on_hook(p);
01219       if (res < 0) {
01220          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
01221       }
01222       switch (p->sig) {
01223       case ANALOG_SIG_FXOGS:
01224       case ANALOG_SIG_FXOLS:
01225       case ANALOG_SIG_FXOKS:
01226          /* If they're off hook, try playing congestion */
01227          if (analog_is_off_hook(p)) {
01228             analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
01229          } else {
01230             analog_play_tone(p, ANALOG_SUB_REAL, -1);
01231          }
01232          break;
01233       case ANALOG_SIG_FXSGS:
01234       case ANALOG_SIG_FXSLS:
01235       case ANALOG_SIG_FXSKS:
01236          /* Make sure we're not made available for at least two seconds assuming
01237             we were actually used for an inbound or outbound call. */
01238          if (ast->_state != AST_STATE_RESERVED) {
01239             time(&p->guardtime);
01240             p->guardtime += 2;
01241          }
01242          break;
01243       default:
01244          analog_play_tone(p, ANALOG_SUB_REAL, -1);
01245       }
01246 
01247       analog_set_echocanceller(p, 0);
01248 
01249       x = 0;
01250       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
01251       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
01252       p->callwaitcas = 0;
01253       p->callwaiting = p->permcallwaiting;
01254       p->hidecallerid = p->permhidecallerid;
01255       analog_set_dialing(p, 0);
01256       analog_update_conf(p);
01257       analog_all_subchannels_hungup(p);
01258    }
01259 
01260    analog_stop_callwait(p);
01261    ast->tech_pvt = NULL;
01262 
01263    ast_verb(3, "Hanging up on '%s'\n", ast->name);
01264 
01265    return 0;
01266 }

static int analog_has_voicemail ( struct analog_pvt p  )  [static]

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

00537 {
00538    if (p->calls->has_voicemail) {
00539       return p->calls->has_voicemail(p->chan_pvt);
00540    }
00541    return -1;
00542 }

static int analog_increase_ss_count ( struct analog_pvt p  )  [static]

Definition at line 1417 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

01418 {
01419    if (p->calls->increase_ss_count) {
01420       p->calls->increase_ss_count();
01421       return 0;
01422    }
01423    return -1;
01424 }

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

Definition at line 544 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00545 {
00546    if (p->calls->is_dialing) {
00547       return p->calls->is_dialing(p->chan_pvt, index);
00548    }
00549    return -1;
00550 }

static int analog_is_off_hook ( struct analog_pvt p  )  [static]

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

00429 {
00430    if (p->calls->is_off_hook) {
00431       return p->calls->is_off_hook(p->chan_pvt);
00432    }
00433    return -1;
00434 }

static void analog_lock_private ( 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::lock_private.

Referenced by __analog_handle_event().

00499 {
00500    if (p->calls->lock_private) {
00501       p->calls->lock_private(p->chan_pvt);
00502    }
00503 }

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

Definition at line 1388 of file sig_analog.c.

References ast_waitfordigit().

Referenced by __analog_ss_thread().

01389 {
01390    char c;
01391 
01392    *str = 0; /* start with empty output buffer */
01393    for (;;) {
01394       /* Wait for the first digit (up to specified ms). */
01395       c = ast_waitfordigit(chan, ms);
01396       /* if timeout, hangup or error, return as such */
01397       if (c < 1) {
01398          return c;
01399       }
01400       *str++ = c;
01401       *str = 0;
01402       if (strchr(term, c)) {
01403          return 1;
01404       }
01405    }
01406 }

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

Definition at line 3489 of file sig_analog.c.

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

Referenced by mkintf().

03490 {
03491    struct analog_pvt *p;
03492 
03493    p = ast_calloc(1, sizeof(*p));
03494    if (!p) {
03495       return p;
03496    }
03497 
03498    p->calls = c;
03499    p->outsigmod = ANALOG_SIG_NONE;
03500    p->sig = signallingtype;
03501    p->chan_pvt = private_data;
03502 
03503    /* Some defaults for values */
03504    p->cid_start = ANALOG_CID_START_RING;
03505    p->cid_signalling = CID_SIG_BELL;
03506    /* Sub real is assumed to always be alloc'd */
03507    p->subs[ANALOG_SUB_REAL].allocd = 1;
03508 
03509    return p;
03510 }

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

Definition at line 396 of file sig_analog.c.

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

00397 {
00398    struct ast_channel *c;
00399 
00400    if (!p->calls->new_ast_channel) {
00401       return NULL;
00402    }
00403 
00404    c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub, requestor);
00405    p->subs[sub].owner = c;
00406    if (!p->owner) {
00407       p->owner = c;
00408    }
00409    return c;
00410 }

static int analog_off_hook ( struct analog_pvt p  )  [static]

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

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

static int analog_on_hook ( struct analog_pvt p  )  [static]

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

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

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

Definition at line 388 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_attempt_transfer(), analog_call(), analog_handle_init_event(), and analog_hangup().

00389 {
00390    if (p->calls->play_tone) {
00391       return p->calls->play_tone(p->chan_pvt, sub, tone);
00392    }
00393    return -1;
00394 }

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

Definition at line 636 of file sig_analog.c.

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

Referenced by dahdi_request().

00637 {
00638    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
00639    *callwait = (p->owner != NULL);
00640 
00641    if (p->owner) {
00642       if (analog_alloc_sub(p, ANALOG_SUB_CALLWAIT)) {
00643          ast_log(LOG_ERROR, "Unable to alloc subchannel\n");
00644          return NULL;
00645       }
00646    }
00647 
00648    return analog_new_ast_channel(p, AST_STATE_RESERVED, 0, p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor);
00649 }

static int analog_ring ( struct analog_pvt p  )  [static]

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

00437 {
00438    if (p->calls->ring) {
00439       return p->calls->ring(p->chan_pvt);
00440    }
00441    return -1;
00442 }

static int analog_send_callerid ( struct analog_pvt p,
int  cwcid,
struct ast_callerid cid 
) [static]

Definition at line 346 of file sig_analog.c.

References ast_debug, analog_pvt::calls, analog_pvt::callwaitcas, analog_pvt::chan_pvt, ast_callerid::cid_name, ast_callerid::cid_num, and analog_callback::send_callerid.

Referenced by __analog_handle_event(), and analog_handle_dtmfup().

00347 {
00348    ast_debug(1, "Sending callerid.  CID_NAME: '%s' CID_NUM: '%s'\n", cid->cid_name, cid->cid_num);
00349 
00350    if (cwcid) {
00351       p->callwaitcas = 0;
00352    }
00353 
00354    if (p->calls->send_callerid) {
00355       return p->calls->send_callerid(p->chan_pvt, cwcid, cid);
00356    }
00357    return 0;
00358 }

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

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

00747 {
00748    if (p->calls->set_cadence) {
00749       return p->calls->set_cadence(p->chan_pvt, &p->cidrings, chan);
00750    }
00751 }

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

Definition at line 786 of file sig_analog.c.

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

Referenced by analog_handle_dtmfup(), and analog_hangup().

00787 {
00788    if (!p->calls->set_confirmanswer) {
00789       return;
00790    }
00791    p->calls->set_confirmanswer(p->chan_pvt, flag);
00792 }

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

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

00754 {
00755    p->dialing = flag;
00756    if (p->calls->set_dialing) {
00757       return p->calls->set_dialing(p->chan_pvt, flag);
00758    }
00759 }

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

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

00413 {
00414    if (p->calls->set_echocanceller) {
00415       return p->calls->set_echocanceller(p->chan_pvt, enable);
00416    }
00417    return -1;
00418 }

static int analog_set_linear_mode ( struct analog_pvt p,
int  index,
int  linear_mode 
) [static]

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

00829 {
00830    if (p->calls->set_linear_mode) {
00831       /* Return provides old linear_mode setting or error indication */
00832       return p->calls->set_linear_mode(p->chan_pvt, index, linear_mode);
00833    }
00834    return -1;
00835 }

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

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

00821 {
00822    if (!p->calls->set_pulsedial) {
00823       return;
00824    }
00825    p->calls->set_pulsedial(p->chan_pvt, flag);
00826 }

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

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

00762 {
00763    p->ringt = ringt;
00764    if (!p->calls->set_ringtimeout) {
00765       return;
00766    }
00767    p->calls->set_ringtimeout(p->chan_pvt, ringt);
00768 }

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

Definition at line 770 of file sig_analog.c.

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

Referenced by analog_call().

00771 {
00772    if (p->calls->set_waitingfordt) {
00773       return p->calls->set_waitingfordt(p->chan_pvt, ast);
00774    }
00775 }

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 109 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

00110 {
00111    int i;
00112 
00113    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00114       if (sigtype == sigtypes[i].sigtype) {
00115          return sigtypes[i].name;
00116       }
00117    }
00118 
00119    return "Unknown";
00120 }

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel chan 
)

Definition at line 2332 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02333 {
02334    pthread_t threadid;
02335 
02336    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02337 }

static int analog_start ( struct analog_pvt p  )  [static]

Definition at line 452 of file sig_analog.c.

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

Referenced by analog_call().

00453 {
00454    if (p->calls->start) {
00455       return p->calls->start(p->chan_pvt);
00456    }
00457    return -1;
00458 }

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

Definition at line 148 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00149 {
00150    if (p->calls->start_cid_detect) {
00151       return p->calls->start_cid_detect(p->chan_pvt, cid_signalling);
00152    }
00153    return -1;
00154 }

static int analog_stop_callwait ( struct analog_pvt p  )  [static]

Definition at line 723 of file sig_analog.c.

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

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

00724 {
00725    if (p->callwaitingcallerid) {
00726       p->callwaitcas = 0;
00727    }
00728 
00729    if (p->calls->stop_callwait) {
00730       return p->calls->stop_callwait(p->chan_pvt);
00731    }
00732    return 0;
00733 }

static int analog_stop_cid_detect ( struct analog_pvt p  )  [static]

Definition at line 156 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00157 {
00158    if (p->calls->stop_cid_detect) {
00159       return p->calls->stop_cid_detect(p->chan_pvt);
00160    }
00161    return -1;
00162 }

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

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

00189 {
00190    if (!strcasecmp(value, "ring")) {
00191       return ANALOG_CID_START_RING;
00192    } else if (!strcasecmp(value, "polarity")) {
00193       return ANALOG_CID_START_POLARITY;
00194    } else if (!strcasecmp(value, "polarity_in")) {
00195       return ANALOG_CID_START_POLARITY_IN;
00196    } else if (!strcasecmp(value, "dtmf")) {
00197       return ANALOG_CID_START_DTMF_NOALERT;
00198    }
00199 
00200    return 0;
00201 }

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 122 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00123 {
00124    int i;
00125 
00126    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00127       if (!strcasecmp(cidtypes[i].name, name)) {
00128          return cidtypes[i].cid_type;
00129       }
00130    }
00131 
00132    return 0;
00133 }

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 96 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

00097 {
00098    int i;
00099 
00100    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00101       if (!strcasecmp(sigtypes[i].name, name)) {
00102          return sigtypes[i].sigtype;
00103       }
00104    }
00105 
00106    return 0;
00107 }

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

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

00303 {
00304    int tinthreeway;
00305    struct ast_channel *towner;
00306 
00307    ast_debug(1, "Swapping %d and %d\n", a, b);
00308 
00309    towner = p->subs[a].owner;
00310    tinthreeway = p->subs[a].inthreeway;
00311 
00312    p->subs[a].owner = p->subs[b].owner;
00313    p->subs[a].inthreeway = p->subs[b].inthreeway;
00314 
00315    p->subs[b].owner = towner;
00316    p->subs[b].inthreeway = tinthreeway;
00317 
00318    if (p->calls->swap_subs) {
00319       p->calls->swap_subs(p->chan_pvt, a, p->subs[a].owner, b, p->subs[b].owner);
00320    }
00321 }

static int analog_train_echocanceller ( struct analog_pvt p  )  [static]

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

00421 {
00422    if (p->calls->train_echocanceller) {
00423       return p->calls->train_echocanceller(p->chan_pvt);
00424    }
00425    return -1;
00426 }

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

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

00337 {
00338    p->subs[x].allocd = 0;
00339    p->subs[x].owner = NULL;
00340    if (p->calls->unallocate_sub) {
00341       return p->calls->unallocate_sub(p->chan_pvt, x);
00342    }
00343    return 0;
00344 }

static void analog_unlock_private ( struct analog_pvt p  )  [static]

Definition at line 491 of file sig_analog.c.

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

Referenced by __analog_handle_event().

00492 {
00493    if (p->calls->unlock_private) {
00494       p->calls->unlock_private(p->chan_pvt);
00495    }
00496 }

static int analog_update_conf ( struct analog_pvt p  )  [static]

Definition at line 609 of file sig_analog.c.

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

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

00610 {
00611    int x;
00612    int needconf = 0;
00613 
00614    /* Start with the obvious, general stuff */
00615    for (x = 0; x < 3; x++) {
00616       /* Look for three way calls */
00617       if ((p->subs[x].allocd) && p->subs[x].inthreeway) {
00618          if (p->calls->conf_add) {
00619             p->calls->conf_add(p->chan_pvt, x);
00620          }
00621          needconf++;
00622       } else {
00623          if (p->calls->conf_del) {
00624             p->calls->conf_del(p->chan_pvt, x);
00625          }
00626       }
00627    }
00628    ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
00629 
00630    if (p->calls->complete_conference_update) {
00631       p->calls->complete_conference_update(p->chan_pvt, needconf);
00632    }
00633    return 0;
00634 }

static int analog_wait_event ( struct analog_pvt p  )  [static]

Definition at line 180 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00181 {
00182    if (p->calls->wait_event) {
00183       return p->calls->wait_event(p->chan_pvt);
00184    }
00185    return -1;
00186 }

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

Definition at line 528 of file sig_analog.c.

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

Referenced by __analog_ss_thread().

00529 {
00530    if (p->calls->wink) {
00531       return p->calls->wink(p->chan_pvt, index);
00532    }
00533    return -1;
00534 }


Variable Documentation

char analog_defaultcic[64] = "" [static]

Definition at line 51 of file sig_analog.c.

Referenced by analog_call().

char analog_defaultozz[64] = "" [static]

Definition at line 52 of file sig_analog.c.

Referenced by analog_call().

int analog_firstdigittimeout = 16000 [static]

Definition at line 50 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_gendigittimeout = 8000 [static]

Definition at line 49 of file sig_analog.c.

Referenced by __analog_ss_thread().

int analog_matchdigittimeout = 3000 [static]

Definition at line 48 of file sig_analog.c.

Referenced by __analog_ss_thread().

unsigned int cid_type

Definition at line 82 of file sig_analog.c.

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

const char const* name

Definition at line 56 of file sig_analog.c.

Definition at line 55 of file sig_analog.c.

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


Generated on Wed Oct 28 13:33:39 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6