Mon Mar 19 11:30:55 2012

Asterisk developer's documentation


sig_analog.h File Reference

Interface header for analog signaling module. More...

#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/smdi.h"

Go to the source code of this file.

Data Structures

struct  analog_callback
struct  analog_dialoperation
struct  analog_pvt
struct  analog_subchannel

Defines

#define ANALOG_MAX_CID   300
#define ANALOG_SMDI_MD_WAIT_TIMEOUT   1500
#define READ_SIZE   160
#define RING_PATTERNS   3

Enumerations

enum  analog_cid_start { ANALOG_CID_START_POLARITY = 1, ANALOG_CID_START_POLARITY_IN, ANALOG_CID_START_RING, ANALOG_CID_START_DTMF_NOALERT }
enum  analog_dsp_digitmode { ANALOG_DIGITMODE_DTMF = 1, ANALOG_DIGITMODE_MF }
enum  analog_event {
  ANALOG_EVENT_NONE = 0, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH,
  ANALOG_EVENT_ALARM, ANALOG_EVENT_NOALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_RINGERON,
  ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_POLARITY,
  ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_REMOVED, ANALOG_EVENT_NEONMWI_ACTIVE,
  ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_TX_CED_DETECTED, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_EC_NLP_DISABLED,
  ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_ERROR, ANALOG_EVENT_DTMFCID, ANALOG_EVENT_PULSEDIGIT = (1 << 16),
  ANALOG_EVENT_DTMFDOWN = (1 << 17), ANALOG_EVENT_DTMFUP = (1 << 18)
}
enum  analog_sigtype {
  ANALOG_SIG_NONE = -1, ANALOG_SIG_FXOLS = 1, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOGS,
  ANALOG_SIG_FXSLS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSGS, ANALOG_SIG_EMWINK,
  ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF,
  ANALOG_SIG_E911, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FEATB,
  ANALOG_SIG_SFWINK, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF,
  ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_SF_FEATB
}
enum  analog_sub { ANALOG_SUB_REAL = 0, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY }
enum  analog_tone {
  ANALOG_TONE_RINGTONE = 0, ANALOG_TONE_STUTTER, ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALTONE,
  ANALOG_TONE_DIALRECALL, ANALOG_TONE_INFO
}
enum  dialop { ANALOG_DIAL_OP_REPLACE = 2 }

Functions

int analog_answer (struct analog_pvt *p, struct ast_channel *ast)
int analog_available (struct analog_pvt *p)
int analog_call (struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout)
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)
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure.
int analog_dnd (struct analog_pvt *p, int flag)
ast_frameanalog_exception (struct analog_pvt *p, struct ast_channel *ast)
int analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
void analog_free (struct analog_pvt *p)
void analog_handle_dtmf (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)
int analog_hangup (struct analog_pvt *p, struct ast_channel *ast)
analog_pvtanalog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data)
ast_channelanalog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
const char * analog_sigtype_to_str (enum analog_sigtype sigtype)
int analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *ast)
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)


Detailed Description

Interface header for analog signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_analog.h.


Define Documentation

#define ANALOG_MAX_CID   300

Definition at line 33 of file sig_analog.h.

Referenced by __analog_ss_thread(), and my_get_callerid().

#define ANALOG_SMDI_MD_WAIT_TIMEOUT   1500

Definition at line 32 of file sig_analog.h.

Referenced by __analog_ss_thread().

#define READ_SIZE   160

Definition at line 34 of file sig_analog.h.

#define RING_PATTERNS   3

Definition at line 35 of file sig_analog.h.

Referenced by __analog_ss_thread(), and my_distinctive_ring().


Enumeration Type Documentation

enum analog_cid_start

Enumerator:
ANALOG_CID_START_POLARITY 
ANALOG_CID_START_POLARITY_IN 
ANALOG_CID_START_RING 
ANALOG_CID_START_DTMF_NOALERT 

Definition at line 112 of file sig_analog.h.

enum analog_dsp_digitmode

Enumerator:
ANALOG_DIGITMODE_DTMF 
ANALOG_DIGITMODE_MF 

Definition at line 107 of file sig_analog.h.

00107                           {
00108    ANALOG_DIGITMODE_DTMF = 1,
00109    ANALOG_DIGITMODE_MF,
00110 };

enum analog_event

Enumerator:
ANALOG_EVENT_NONE 
ANALOG_EVENT_ONHOOK 
ANALOG_EVENT_RINGOFFHOOK 
ANALOG_EVENT_WINKFLASH 
ANALOG_EVENT_ALARM 
ANALOG_EVENT_NOALARM 
ANALOG_EVENT_DIALCOMPLETE 
ANALOG_EVENT_RINGERON 
ANALOG_EVENT_RINGEROFF 
ANALOG_EVENT_HOOKCOMPLETE 
ANALOG_EVENT_PULSE_START 
ANALOG_EVENT_POLARITY 
ANALOG_EVENT_RINGBEGIN 
ANALOG_EVENT_EC_DISABLED 
ANALOG_EVENT_REMOVED 
ANALOG_EVENT_NEONMWI_ACTIVE 
ANALOG_EVENT_NEONMWI_INACTIVE 
ANALOG_EVENT_TX_CED_DETECTED 
ANALOG_EVENT_RX_CED_DETECTED 
ANALOG_EVENT_EC_NLP_DISABLED 
ANALOG_EVENT_EC_NLP_ENABLED 
ANALOG_EVENT_ERROR 
ANALOG_EVENT_DTMFCID 
ANALOG_EVENT_PULSEDIGIT 
ANALOG_EVENT_DTMFDOWN 
ANALOG_EVENT_DTMFUP 

Definition at line 72 of file sig_analog.h.

enum analog_sigtype

Enumerator:
ANALOG_SIG_NONE 
ANALOG_SIG_FXOLS 
ANALOG_SIG_FXOKS 
ANALOG_SIG_FXOGS 
ANALOG_SIG_FXSLS 
ANALOG_SIG_FXSKS 
ANALOG_SIG_FXSGS 
ANALOG_SIG_EMWINK 
ANALOG_SIG_EM 
ANALOG_SIG_EM_E1 
ANALOG_SIG_FEATD 
ANALOG_SIG_FEATDMF 
ANALOG_SIG_E911 
ANALOG_SIG_FGC_CAMA 
ANALOG_SIG_FGC_CAMAMF 
ANALOG_SIG_FEATB 
ANALOG_SIG_SFWINK 
ANALOG_SIG_SF 
ANALOG_SIG_SF_FEATD 
ANALOG_SIG_SF_FEATDMF 
ANALOG_SIG_FEATDMF_TA 
ANALOG_SIG_SF_FEATB 

Definition at line 38 of file sig_analog.h.

enum analog_sub

Enumerator:
ANALOG_SUB_REAL  Active call
ANALOG_SUB_CALLWAIT  Call-Waiting call on hold
ANALOG_SUB_THREEWAY  Three-way call

Definition at line 101 of file sig_analog.h.

00101                 {
00102    ANALOG_SUB_REAL = 0,       /*!< Active call */
00103    ANALOG_SUB_CALLWAIT,       /*!< Call-Waiting call on hold */
00104    ANALOG_SUB_THREEWAY,       /*!< Three-way call */
00105 };

enum analog_tone

Enumerator:
ANALOG_TONE_RINGTONE 
ANALOG_TONE_STUTTER 
ANALOG_TONE_CONGESTION 
ANALOG_TONE_DIALTONE 
ANALOG_TONE_DIALRECALL 
ANALOG_TONE_INFO 

Definition at line 63 of file sig_analog.h.

enum dialop

Enumerator:
ANALOG_DIAL_OP_REPLACE 

Definition at line 119 of file sig_analog.h.

00119             {
00120    ANALOG_DIAL_OP_REPLACE = 2,
00121 };


Function Documentation

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1485 of file sig_analog.c.

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

Referenced by dahdi_answer().

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

int analog_available ( struct analog_pvt p  ) 

Definition at line 805 of file sig_analog.c.

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

Referenced by available().

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

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

Definition at line 1002 of file sig_analog.c.

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

Referenced by dahdi_call().

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

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

Definition at line 227 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

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

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 142 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

int analog_config_complete ( struct analog_pvt p  ) 

Definition at line 3886 of file sig_analog.c.

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

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

void analog_delete ( struct analog_pvt doomed  ) 

Delete the analog private structure.

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

Definition at line 3881 of file sig_analog.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

03882 {
03883    ast_free(doomed);
03884 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

Definition at line 3922 of file sig_analog.c.

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

Referenced by __analog_ss_thread(), and dahdi_dnd().

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

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

Definition at line 3495 of file sig_analog.c.

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

Referenced by dahdi_exception(), and dahdi_read().

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

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

Definition at line 3904 of file sig_analog.c.

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

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

void analog_free ( struct analog_pvt p  ) 

Definition at line 3898 of file sig_analog.c.

References ast_free.

03899 {
03900    ast_free(p);
03901 }

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

Definition at line 1588 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and dahdi_read().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3606 of file sig_analog.c.

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

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1269 of file sig_analog.c.

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

Referenced by dahdi_hangup().

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

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

Definition at line 3850 of file sig_analog.c.

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

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

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

Definition at line 782 of file sig_analog.c.

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

Referenced by dahdi_request().

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

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 116 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

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

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 2635 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02636 {
02637    pthread_t threadid;
02638 
02639    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02640 }

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 212 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

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

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 129 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 103 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

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


Generated on Mon Mar 19 11:30:55 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7