Wed Apr 6 11:30:10 2011

Asterisk developer's documentation


sig_analog.h File Reference

Interface header for analog signaling module. More...

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

Go to the source code of this file.

Data Structures

struct  analog_callback
struct  analog_dialoperation
struct  analog_pvt
struct  analog_subchannel

Defines

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

Enumerations

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

Functions

int analog_answer (struct analog_pvt *p, struct ast_channel *ast)
int analog_available (struct analog_pvt *p)
int analog_call (struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout)
const char * analog_cidstart_to_str (enum analog_cid_start cid_start)
const char * analog_cidtype_to_str (unsigned int cid_type)
int analog_config_complete (struct analog_pvt *p)
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure.
int analog_dnd (struct analog_pvt *p, int flag)
ast_frameanalog_exception (struct analog_pvt *p, struct ast_channel *ast)
int analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
void analog_free (struct analog_pvt *p)
void analog_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, struct ast_frame **dest)
void * analog_handle_init_event (struct analog_pvt *i, int event)
int analog_hangup (struct analog_pvt *p, struct ast_channel *ast)
analog_pvtanalog_new (enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data)
ast_channelanalog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
const char * analog_sigtype_to_str (enum analog_sigtype sigtype)
int analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *ast)
enum analog_cid_start analog_str_to_cidstart (const char *value)
unsigned int analog_str_to_cidtype (const char *name)
enum analog_sigtype analog_str_to_sigtype (const char *name)


Detailed Description

Interface header for analog signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_analog.h.


Define Documentation

#define ANALOG_MAX_CID   300

Definition at line 33 of file sig_analog.h.

Referenced by __analog_ss_thread(), and my_get_callerid().

#define ANALOG_SMDI_MD_WAIT_TIMEOUT   1500

Definition at line 32 of file sig_analog.h.

Referenced by __analog_ss_thread().

#define READ_SIZE   160

Definition at line 34 of file sig_analog.h.

#define RING_PATTERNS   3

Definition at line 35 of file sig_analog.h.

Referenced by __analog_ss_thread(), and my_distinctive_ring().


Enumeration Type Documentation

enum analog_cid_start

Enumerator:
ANALOG_CID_START_POLARITY 
ANALOG_CID_START_POLARITY_IN 
ANALOG_CID_START_RING 
ANALOG_CID_START_DTMF_NOALERT 

Definition at line 112 of file sig_analog.h.

enum analog_dsp_digitmode

Enumerator:
ANALOG_DIGITMODE_DTMF 
ANALOG_DIGITMODE_MF 

Definition at line 107 of file sig_analog.h.

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

enum analog_event

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

Definition at line 72 of file sig_analog.h.

enum analog_sigtype

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

Definition at line 38 of file sig_analog.h.

enum analog_sub

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

Definition at line 101 of file sig_analog.h.

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

enum analog_tone

Enumerator:
ANALOG_TONE_RINGTONE 
ANALOG_TONE_STUTTER 
ANALOG_TONE_CONGESTION 
ANALOG_TONE_DIALTONE 
ANALOG_TONE_DIALRECALL 
ANALOG_TONE_INFO 

Definition at line 63 of file sig_analog.h.

enum dialop

Enumerator:
ANALOG_DIAL_OP_REPLACE 

Definition at line 119 of file sig_analog.h.

00119             {
00120    ANALOG_DIAL_OP_REPLACE = 2,
00121 };


Function Documentation

int analog_answer ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1477 of file sig_analog.c.

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

Referenced by dahdi_answer().

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

int analog_available ( struct analog_pvt p  ) 

Definition at line 796 of file sig_analog.c.

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

Referenced by available().

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

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

Definition at line 993 of file sig_analog.c.

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

Referenced by dahdi_call().

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

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

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

00219 {
00220    switch (cid_start) {
00221    case ANALOG_CID_START_RING:
00222       return "Ring";
00223    case ANALOG_CID_START_POLARITY:
00224       return "Polarity";
00225    case ANALOG_CID_START_POLARITY_IN:
00226       return "Polarity_In";
00227    case ANALOG_CID_START_DTMF_NOALERT:
00228       return "DTMF";
00229    }
00230 
00231    return "Unknown";
00232 }

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 3844 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.

03845 {
03846    /* No call waiting on non FXS channels */
03847    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03848       p->permcallwaiting = 0;
03849    }
03850 
03851    analog_set_callwaiting(p, p->permcallwaiting);
03852 
03853    return 0;
03854 }

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

References ast_free.

Referenced by destroy_dahdi_pvt().

03840 {
03841    ast_free(doomed);
03842 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

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

03881 {
03882    if (flag == -1) {
03883       return p->dnd;
03884    }
03885 
03886    p->dnd = flag;
03887 
03888    ast_verb(3, "%s DND on channel %d\n",
03889          flag ? "Enabled" : "Disabled",
03890          p->channel);
03891    manager_event(EVENT_FLAG_SYSTEM, "DNDState",
03892          "Channel: DAHDI/%d\r\n"
03893          "Status: %s\r\n", p->channel,
03894          flag ? "enabled" : "disabled");
03895 
03896    return 0;
03897 }

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

Definition at line 3453 of file sig_analog.c.

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

Referenced by dahdi_exception(), and dahdi_read().

03454 {
03455    int res;
03456    int idx;
03457    struct ast_frame *f;
03458 
03459    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
03460 
03461    idx = analog_get_index(ast, p, 1);
03462    if (idx < 0) {
03463       idx = ANALOG_SUB_REAL;
03464    }
03465 
03466    p->subs[idx].f.frametype = AST_FRAME_NULL;
03467    p->subs[idx].f.datalen = 0;
03468    p->subs[idx].f.samples = 0;
03469    p->subs[idx].f.mallocd = 0;
03470    p->subs[idx].f.offset = 0;
03471    p->subs[idx].f.subclass.integer = 0;
03472    p->subs[idx].f.delivery = ast_tv(0,0);
03473    p->subs[idx].f.src = "dahdi_exception";
03474    p->subs[idx].f.data.ptr = NULL;
03475 
03476    if (!p->owner) {
03477       /* If nobody owns us, absorb the event appropriately, otherwise
03478          we loop indefinitely.  This occurs when, during call waiting, the
03479          other end hangs up our channel so that it no longer exists, but we
03480          have neither FLASH'd nor ONHOOK'd to signify our desire to
03481          change to the other channel. */
03482       res = analog_get_event(p);
03483 
03484       /* Switch to real if there is one and this isn't something really silly... */
03485       if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
03486          (res != ANALOG_EVENT_HOOKCOMPLETE)) {
03487          ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
03488          analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
03489          if (p->owner && ast != p->owner) {
03490             /*
03491              * Could this even happen?
03492              * Possible deadlock because we do not have the real-call lock.
03493              */
03494             ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n",
03495                analog_event2str(res), ast->name, p->owner->name);
03496          }
03497          if (p->owner && ast_bridged_channel(p->owner)) {
03498             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03499          }
03500       }
03501       switch (res) {
03502       case ANALOG_EVENT_ONHOOK:
03503          analog_set_echocanceller(p, 0);
03504          if (p->owner) {
03505             ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name);
03506             analog_ring(p);
03507             analog_stop_callwait(p);
03508          } else {
03509             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03510                analog_event2str(res));
03511          }
03512          analog_update_conf(p);
03513          break;
03514       case ANALOG_EVENT_RINGOFFHOOK:
03515          analog_set_echocanceller(p, 1);
03516          analog_off_hook(p);
03517          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
03518             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03519             analog_set_dialing(p, 0);
03520          }
03521          break;
03522       case ANALOG_EVENT_HOOKCOMPLETE:
03523       case ANALOG_EVENT_RINGERON:
03524       case ANALOG_EVENT_RINGEROFF:
03525          /* Do nothing */
03526          break;
03527       case ANALOG_EVENT_WINKFLASH:
03528          gettimeofday(&p->flashtime, NULL);
03529          if (p->owner) {
03530             ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
03531             if (p->owner->_state != AST_STATE_UP) {
03532                /* Answer if necessary */
03533                ast_queue_control(p->owner, AST_CONTROL_ANSWER);
03534                ast_setstate(p->owner, AST_STATE_UP);
03535             }
03536             analog_stop_callwait(p);
03537             if (ast_bridged_channel(p->owner)) {
03538                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
03539             }
03540          } else {
03541             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
03542                analog_event2str(res));
03543          }
03544          analog_update_conf(p);
03545          break;
03546       default:
03547          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", analog_event2str(res));
03548          break;
03549       }
03550       f = &p->subs[idx].f;
03551       return f;
03552    }
03553    ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
03554    /* If it's not us, return NULL immediately */
03555    if (ast != p->owner) {
03556       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
03557       f = &p->subs[idx].f;
03558       return f;
03559    }
03560    f = __analog_handle_event(p, ast);
03561    return f;
03562 }

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

Definition at line 3862 of file sig_analog.c.

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

03863 {
03864    struct analog_pvt *new_pvt = newp;
03865    int x;
03866    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
03867    if (new_pvt->owner == oldchan) {
03868       analog_set_new_owner(new_pvt, newchan);
03869    }
03870    for (x = 0; x < 3; x++) {
03871       if (new_pvt->subs[x].owner == oldchan) {
03872          new_pvt->subs[x].owner = newchan;
03873       }
03874    }
03875 
03876    analog_update_conf(new_pvt);
03877    return 0;
03878 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3856 of file sig_analog.c.

References ast_free.

03857 {
03858    ast_free(p);
03859 }

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

Definition at line 1580 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and dahdi_read().

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

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

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

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1260 of file sig_analog.c.

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

Referenced by dahdi_hangup().

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

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

Definition at line 3808 of file sig_analog.c.

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

03809 {
03810    struct analog_pvt *p;
03811 
03812    p = ast_calloc(1, sizeof(*p));
03813    if (!p) {
03814       return p;
03815    }
03816 
03817    p->calls = c;
03818    p->outsigmod = ANALOG_SIG_NONE;
03819    p->sig = signallingtype;
03820    p->chan_pvt = private_data;
03821 
03822    /* Some defaults for values */
03823    p->cid_start = ANALOG_CID_START_RING;
03824    p->cid_signalling = CID_SIG_BELL;
03825    /* Sub real is assumed to always be alloc'd */
03826    p->subs[ANALOG_SUB_REAL].allocd = 1;
03827 
03828    return p;
03829 }

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

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

00774 {
00775    struct ast_channel *ast;
00776 
00777    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
00778    *callwait = (p->owner != NULL);
00779 
00780    if (p->owner) {
00781       if (analog_alloc_sub(p, ANALOG_SUB_CALLWAIT)) {
00782          ast_log(LOG_ERROR, "Unable to alloc subchannel\n");
00783          return NULL;
00784       }
00785    }
00786 
00787    p->outgoing = 1;
00788    ast = analog_new_ast_channel(p, AST_STATE_RESERVED, 0,
00789       p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor);
00790    if (!ast) {
00791       p->outgoing = 0;
00792    }
00793    return ast;
00794 }

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

References __analog_ss_thread(), and ast_pthread_create_detached.

Referenced by mwi_thread().

02596 {
02597    pthread_t threadid;
02598 
02599    return ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p);
02600 }

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

Definition at line 203 of file sig_analog.c.

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, and ANALOG_CID_START_RING.

00204 {
00205    if (!strcasecmp(value, "ring")) {
00206       return ANALOG_CID_START_RING;
00207    } else if (!strcasecmp(value, "polarity")) {
00208       return ANALOG_CID_START_POLARITY;
00209    } else if (!strcasecmp(value, "polarity_in")) {
00210       return ANALOG_CID_START_POLARITY_IN;
00211    } else if (!strcasecmp(value, "dtmf")) {
00212       return ANALOG_CID_START_DTMF_NOALERT;
00213    }
00214 
00215    return 0;
00216 }

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 Wed Apr 6 11:30:10 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7