Sat Feb 11 06:36:45 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"

Include dependency graph for sig_analog.h:

This graph shows which files directly or indirectly include this file:

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, const 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 1488 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_channel_name(), 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().

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

int analog_available ( struct analog_pvt p  ) 

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

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

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

Definition at line 1005 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_channel_name(), 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::outgoing, analog_pvt::outsigmod, analog_pvt::owner, analog_subchannel::owner, pbx_builtin_getvar_helper(), analog_pvt::polaritydelaytv, analog_pvt::pulse, S_COR, analog_pvt::sig, ast_party_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().

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

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

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

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

References ast_free.

Referenced by destroy_dahdi_pvt().

03885 {
03886    ast_free(doomed);
03887 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

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

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

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

Definition at line 3498 of file sig_analog.c.

References __analog_handle_event(), ast_channel::_state, analog_event2str(), ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_WINKFLASH, analog_get_event(), analog_get_index, analog_off_hook(), analog_ring(), analog_set_dialing(), analog_set_echocanceller(), analog_set_new_owner(), analog_stop_callwait(), ANALOG_SUB_REAL, analog_update_conf(), ast_bridged_channel(), ast_channel_name(), AST_CONTROL_ANSWER, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_tv(), ast_verb, analog_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, analog_subchannel::f, f, ast_channel::fds, analog_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::mallocd, 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().

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

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

Definition at line 3907 of file sig_analog.c.

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

Referenced by dahdi_fixup().

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

void analog_free ( struct analog_pvt p  ) 

Definition at line 3901 of file sig_analog.c.

References ast_free.

03902 {
03903    ast_free(p);
03904 }

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

Definition at line 1591 of file sig_analog.c.

References analog_cb_handle_dtmf(), analog_check_confirmanswer(), analog_handles_digit(), analog_send_callerid(), analog_set_confirmanswer(), ast_channel_name(), 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().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

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

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1272 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_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_name(), 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::outgoing, analog_pvt::owner, analog_subchannel::owner, analog_pvt::permcallwaiting, analog_pvt::permhidecallerid, analog_pvt::polarity, POLARITY_IDLE, S_OR, analog_pvt::sig, analog_pvt::subs, and ast_channel::tech_pvt.

Referenced by dahdi_hangup().

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

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

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

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

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

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

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

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

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02639 {
02640    pthread_t threadid;
02641 
02642    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02643 }

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 Sat Feb 11 06:36:46 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6