Tue Aug 20 16:35:16 2013

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)
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)
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)
struct analog_pvtanalog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data)
struct 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

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.

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 };

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.

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 };

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

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

Referenced by dahdi_answer().

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

int analog_available ( struct analog_pvt p  ) 

Definition at line 813 of file sig_analog.c.

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

Referenced by available().

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

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

Definition at line 1010 of file sig_analog.c.

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

Referenced by dahdi_call().

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

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

Definition at line 231 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

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

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 146 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

int analog_config_complete ( struct analog_pvt p  ) 

Definition at line 3929 of file sig_analog.c.

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

Referenced by mkintf().

03930 {
03931    /* No call waiting on non FXS channels */
03932    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03933       p->permcallwaiting = 0;
03934    }
03935 
03936    analog_set_callwaiting(p, p->permcallwaiting);
03937 
03938    return 0;
03939 }

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

References ast_free.

Referenced by destroy_dahdi_pvt().

03925 {
03926    ast_free(doomed);
03927 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

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

03966 {
03967    if (flag == -1) {
03968       return p->dnd;
03969    }
03970 
03971    p->dnd = flag;
03972 
03973    ast_verb(3, "%s DND on channel %d\n",
03974          flag ? "Enabled" : "Disabled",
03975          p->channel);
03976    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03977          "Channel: DAHDI/%d\r\n"
03978          "Status: %s\r\n", p->channel,
03979          flag ? "enabled" : "disabled");
03980 
03981    return 0;
03982 }

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

Definition at line 3525 of file sig_analog.c.

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

Referenced by dahdi_exception(), and dahdi_read().

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

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

Definition at line 3947 of file sig_analog.c.

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

Referenced by dahdi_fixup().

03948 {
03949    struct analog_pvt *new_pvt = newp;
03950    int x;
03951    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03952    if (new_pvt->owner == oldchan) {
03953       analog_set_new_owner(new_pvt, newchan);
03954    }
03955    for (x = 0; x < 3; x++) {
03956       if (new_pvt->subs[x].owner == oldchan) {
03957          new_pvt->subs[x].owner = newchan;
03958       }
03959    }
03960 
03961    analog_update_conf(new_pvt);
03962    return 0;
03963 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3941 of file sig_analog.c.

References ast_free.

03942 {
03943    ast_free(p);
03944 }

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

Definition at line 1596 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and dahdi_read().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3647 of file sig_analog.c.

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

Referenced by do_monitor().

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1277 of file sig_analog.c.

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

Referenced by dahdi_hangup().

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

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

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

03894 {
03895    struct analog_pvt *p;
03896 
03897    p = ast_calloc(1, sizeof(*p));
03898    if (!p) {
03899       return p;
03900    }
03901 
03902    p->calls = c;
03903    p->outsigmod = ANALOG_SIG_NONE;
03904    p->sig = signallingtype;
03905    p->chan_pvt = private_data;
03906 
03907    /* Some defaults for values */
03908    p->cid_start = ANALOG_CID_START_RING;
03909    p->cid_signalling = CID_SIG_BELL;
03910    /* Sub real is assumed to always be alloc'd */
03911    p->subs[ANALOG_SUB_REAL].allocd = 1;
03912 
03913    return p;
03914 }

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

Definition at line 790 of file sig_analog.c.

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

Referenced by dahdi_request().

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

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 120 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

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

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 2651 of file sig_analog.c.

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02652 {
02653    pthread_t threadid;
02654 
02655    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02656 }

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 216 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

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

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 133 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

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

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 107 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

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


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1