Wed Aug 7 17:16:13 2019

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

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

int analog_available ( struct analog_pvt p  ) 

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

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

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

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

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

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

03920 {
03921    /* No call waiting on non FXS channels */
03922    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03923       p->permcallwaiting = 0;
03924    }
03925 
03926    analog_set_callwaiting(p, p->permcallwaiting);
03927 
03928    return 0;
03929 }

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

References ast_free.

Referenced by destroy_dahdi_pvt().

03915 {
03916    ast_free(doomed);
03917 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

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

03956 {
03957    if (flag == -1) {
03958       return p->dnd;
03959    }
03960 
03961    p->dnd = flag;
03962 
03963    ast_verb(3, "%s DND on channel %d\n",
03964          flag ? "Enabled" : "Disabled",
03965          p->channel);
03966    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03967          "Channel: DAHDI/%d\r\n"
03968          "Status: %s\r\n", p->channel,
03969          flag ? "enabled" : "disabled");
03970 
03971    return 0;
03972 }

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

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

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

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

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

03938 {
03939    struct analog_pvt *new_pvt = newp;
03940    int x;
03941    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03942    if (new_pvt->owner == oldchan) {
03943       analog_set_new_owner(new_pvt, newchan);
03944    }
03945    for (x = 0; x < 3; x++) {
03946       if (new_pvt->subs[x].owner == oldchan) {
03947          new_pvt->subs[x].owner = newchan;
03948       }
03949    }
03950 
03951    analog_update_conf(new_pvt);
03952    return 0;
03953 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3931 of file sig_analog.c.

References ast_free.

03932 {
03933    ast_free(p);
03934 }

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

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

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

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

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

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

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

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

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

03884 {
03885    struct analog_pvt *p;
03886 
03887    p = ast_calloc(1, sizeof(*p));
03888    if (!p) {
03889       return p;
03890    }
03891 
03892    p->calls = c;
03893    p->outsigmod = ANALOG_SIG_NONE;
03894    p->sig = signallingtype;
03895    p->chan_pvt = private_data;
03896 
03897    /* Some defaults for values */
03898    p->cid_start = ANALOG_CID_START_RING;
03899    p->cid_signalling = CID_SIG_BELL;
03900    /* Sub real is assumed to always be alloc'd */
03901    p->subs[ANALOG_SUB_REAL].allocd = 1;
03902 
03903    return p;
03904 }

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

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

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

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

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02645 {
02646    pthread_t threadid;
02647 
02648    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02649 }

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 7 Aug 2019 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1