sig_analog.h File Reference

Interface header for analog signaling module. More...

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

Include dependency graph for sig_analog.h:

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

Go to the source code of this file.

Data Structures

struct  analog_callback
struct  analog_dialoperation
struct  analog_pvt
struct  analog_subchannel

Defines

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

Enumerations

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

Functions

int analog_answer (struct analog_pvt *p, struct ast_channel *ast)
int analog_available (struct analog_pvt *p)
int analog_call (struct analog_pvt *p, struct ast_channel *ast, const char *rdest, int timeout)
const char * analog_cidstart_to_str (enum analog_cid_start cid_start)
const char * analog_cidtype_to_str (unsigned int cid_type)
int analog_config_complete (struct analog_pvt *p)
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure.
int analog_dnd (struct analog_pvt *p, int flag)
struct ast_frameanalog_exception (struct analog_pvt *p, struct ast_channel *ast)
int analog_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
void analog_free (struct analog_pvt *p)
void analog_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, struct ast_frame **dest)
void * analog_handle_init_event (struct analog_pvt *i, int event)
int analog_hangup (struct analog_pvt *p, struct ast_channel *ast)
struct analog_pvtanalog_new (enum analog_sigtype signallingtype, 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)

Variables

struct analog_callback analog_callbacks


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

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

Referenced by dahdi_answer().

01450 {
01451    int res = 0;
01452    int idx;
01453    int oldstate = ast_channel_state(ast);
01454 
01455    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
01456    ast_setstate(ast, AST_STATE_UP);
01457    idx = analog_get_index(ast, p, 1);
01458    if (idx < 0) {
01459       idx = ANALOG_SUB_REAL;
01460    }
01461    switch (p->sig) {
01462    case ANALOG_SIG_FXSLS:
01463    case ANALOG_SIG_FXSGS:
01464    case ANALOG_SIG_FXSKS:
01465       analog_set_ringtimeout(p, 0);
01466       /* Fall through */
01467    case ANALOG_SIG_EM:
01468    case ANALOG_SIG_EM_E1:
01469    case ANALOG_SIG_EMWINK:
01470    case ANALOG_SIG_FEATD:
01471    case ANALOG_SIG_FEATDMF:
01472    case ANALOG_SIG_FEATDMF_TA:
01473    case ANALOG_SIG_E911:
01474    case ANALOG_SIG_FGC_CAMA:
01475    case ANALOG_SIG_FGC_CAMAMF:
01476    case ANALOG_SIG_FEATB:
01477    case ANALOG_SIG_SF:
01478    case ANALOG_SIG_SFWINK:
01479    case ANALOG_SIG_SF_FEATD:
01480    case ANALOG_SIG_SF_FEATDMF:
01481    case ANALOG_SIG_SF_FEATB:
01482    case ANALOG_SIG_FXOLS:
01483    case ANALOG_SIG_FXOGS:
01484    case ANALOG_SIG_FXOKS:
01485       /* Pick up the line */
01486       ast_debug(1, "Took %s off hook\n", ast_channel_name(ast));
01487       if (p->hanguponpolarityswitch) {
01488          gettimeofday(&p->polaritydelaytv, NULL);
01489       }
01490       res = analog_off_hook(p);
01491       analog_play_tone(p, idx, -1);
01492       analog_set_dialing(p, 0);
01493       if ((idx == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
01494          if (oldstate == AST_STATE_RINGING) {
01495             ast_debug(1, "Finally swapping real and threeway\n");
01496             analog_play_tone(p, ANALOG_SUB_THREEWAY, -1);
01497             analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
01498             analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
01499          }
01500       }
01501 
01502       switch (p->sig) {
01503       case ANALOG_SIG_FXSLS:
01504       case ANALOG_SIG_FXSKS:
01505       case ANALOG_SIG_FXSGS:
01506          analog_set_echocanceller(p, 1);
01507          analog_train_echocanceller(p);
01508          break;
01509       case ANALOG_SIG_FXOLS:
01510       case ANALOG_SIG_FXOKS:
01511       case ANALOG_SIG_FXOGS:
01512          analog_answer_polarityswitch(p);
01513          break;
01514       default:
01515          break;
01516       }
01517       break;
01518    default:
01519       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
01520       res = -1;
01521       break;
01522    }
01523    ast_setstate(ast, AST_STATE_UP);
01524    return res;
01525 }

int analog_available ( struct analog_pvt p  ) 

Definition at line 783 of file sig_analog.c.

References 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, NULL, analog_pvt::outgoing, analog_subchannel::owner, analog_pvt::owner, analog_pvt::sig, and analog_pvt::subs.

Referenced by available().

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

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

Definition at line 975 of file sig_analog.c.

References 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_connected(), ast_channel_get_cc_config_params(), ast_channel_name(), AST_CONTROL_BUSY, AST_CONTROL_RINGING, ast_copy_string(), ast_debug, ast_get_cc_monitor_policy(), ast_log, ast_queue_cc_frame(), ast_queue_control(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero, ast_tvnow(), c, analog_pvt::caller, analog_pvt::callwait_name, analog_pvt::callwait_num, 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, name, NULL, 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().

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

const char* analog_cidstart_to_str ( enum analog_cid_start  cid_start  ) 

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

00238 {
00239    switch (cid_start) {
00240    case ANALOG_CID_START_RING:
00241       return "Ring";
00242    case ANALOG_CID_START_POLARITY:
00243       return "Polarity";
00244    case ANALOG_CID_START_POLARITY_IN:
00245       return "Polarity_In";
00246    case ANALOG_CID_START_DTMF_NOALERT:
00247       return "DTMF";
00248    }
00249 
00250    return "Unknown";
00251 }

const char* analog_cidtype_to_str ( unsigned int  cid_type  ) 

Definition at line 152 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00153 {
00154    int i;
00155 
00156    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00157       if (cid_type == cidtypes[i].cid_type) {
00158          return cidtypes[i].name;
00159       }
00160    }
00161 
00162    return "Unknown";
00163 }

int analog_config_complete ( struct analog_pvt p  ) 

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

03943 {
03944    /* No call waiting on non FXS channels */
03945    if ((p->sig != ANALOG_SIG_FXOKS) && (p->sig != ANALOG_SIG_FXOLS) && (p->sig != ANALOG_SIG_FXOGS)) {
03946       p->permcallwaiting = 0;
03947    }
03948 
03949    analog_set_callwaiting(p, p->permcallwaiting);
03950 
03951    return 0;
03952 }

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

References ast_free.

Referenced by destroy_dahdi_pvt().

03938 {
03939    ast_free(doomed);
03940 }

int analog_dnd ( struct analog_pvt p,
int  flag 
)

Definition at line 3998 of file sig_analog.c.

References analog_publish_dnd_state(), ast_verb, analog_pvt::channel, and analog_pvt::dnd.

Referenced by __analog_ss_thread(), and dahdi_dnd().

03999 {
04000    if (flag == -1) {
04001       return p->dnd;
04002    }
04003 
04004    p->dnd = flag;
04005 
04006    ast_verb(3, "%s DND on channel %d\n",
04007          flag ? "Enabled" : "Disabled",
04008          p->channel);
04009    analog_publish_dnd_state(p->channel, flag ? "enabled" : "disabled");
04010 
04011    return 0;
04012 }

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

Definition at line 3534 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_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_channel_fd(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_CONTROL_ANSWER, ast_debug, AST_FRAME_NULL, ast_log, ast_queue_control(), ast_queue_unhold(), 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, analog_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::mallocd, name, NULL, 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().

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

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

Definition at line 3960 of file sig_analog.c.

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

Referenced by dahdi_fixup().

03961 {
03962    struct analog_pvt *new_pvt = newp;
03963    int x;
03964    ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, ast_channel_name(newchan));
03965    if (new_pvt->owner == oldchan) {
03966       analog_set_new_owner(new_pvt, newchan);
03967    }
03968    for (x = 0; x < 3; x++) {
03969       if (new_pvt->subs[x].owner == oldchan) {
03970          new_pvt->subs[x].owner = newchan;
03971       }
03972    }
03973 
03974    analog_update_conf(new_pvt);
03975    return 0;
03976 }

void analog_free ( struct analog_pvt p  ) 

Definition at line 3954 of file sig_analog.c.

References ast_free.

03955 {
03956    ast_free(p);
03957 }

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

Definition at line 1552 of file sig_analog.c.

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

Referenced by __analog_handle_event(), and dahdi_read().

01553 {
01554    struct ast_frame *f = *dest;
01555 
01556    ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
01557       f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
01558       (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
01559 
01560    if (analog_check_confirmanswer(p)) {
01561       if (f->frametype == AST_FRAME_DTMF_END) {
01562          ast_debug(1, "Confirm answer on %s!\n", ast_channel_name(ast));
01563          /* Upon receiving a DTMF digit, consider this an answer confirmation instead
01564          of a DTMF digit */
01565          p->subs[idx].f.frametype = AST_FRAME_CONTROL;
01566          p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
01567          /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
01568          analog_set_confirmanswer(p, 0);
01569       } else {
01570          p->subs[idx].f.frametype = AST_FRAME_NULL;
01571          p->subs[idx].f.subclass.integer = 0;
01572       }
01573       *dest = &p->subs[idx].f;
01574    } else if (p->callwaitcas) {
01575       if (f->frametype == AST_FRAME_DTMF_END) {
01576          if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
01577             ast_debug(1, "Got some DTMF, but it's for the CAS\n");
01578             p->caller.id.name.str = p->callwait_name;
01579             p->caller.id.number.str = p->callwait_num;
01580             analog_send_callerid(p, 1, &p->caller);
01581          }
01582          if (analog_handles_digit(f)) {
01583             p->callwaitcas = 0;
01584          }
01585       }
01586       p->subs[idx].f.frametype = AST_FRAME_NULL;
01587       p->subs[idx].f.subclass.integer = 0;
01588       *dest = &p->subs[idx].f;
01589    } else {
01590       analog_cb_handle_dtmf(p, ast, idx, dest);
01591    }
01592 }

void* analog_handle_init_event ( struct analog_pvt i,
int  event 
)

Definition at line 3654 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_publish_channel_alarm_clear(), 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_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), ast_debug, ast_hangup(), ast_log, ast_pthread_create_detached, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verb, ast_channel::callid, analog_pvt::chan_pvt, analog_pvt::channel, analog_pvt::cid_start, errno, analog_pvt::fxsoffhookstate, analog_pvt::hanguponpolarityswitch, analog_pvt::immediate, analog_pvt::inalarm, LOG_NOTICE, LOG_WARNING, NULL, analog_pvt::polarity, POLARITY_REV, analog_pvt::ringt_base, analog_pvt::sig, and analog_pvt::ss_astchan.

Referenced by do_monitor().

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

int analog_hangup ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 1239 of file sig_analog.c.

References 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_channel_name(), ast_channel_setoption(), ast_channel_tech_pvt(), ast_channel_unlock, AST_CONTROL_ANSWER, ast_copy_string(), ast_debug, ast_free, ast_log, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_hold(), ast_queue_unhold(), AST_STATE_RESERVED, AST_STATE_UP, 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, NULL, 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, analog_pvt::sig, and analog_pvt::subs.

Referenced by dahdi_hangup().

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

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

Definition at line 3907 of file sig_analog.c.

References analog_subchannel::allocd, ANALOG_CID_START_RING, ANALOG_SIG_NONE, ANALOG_SUB_REAL, ast_calloc, 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().

03908 {
03909    struct analog_pvt *p;
03910 
03911    p = ast_calloc(1, sizeof(*p));
03912    if (!p) {
03913       return p;
03914    }
03915 
03916    p->outsigmod = ANALOG_SIG_NONE;
03917    p->sig = signallingtype;
03918    p->chan_pvt = private_data;
03919 
03920    /* Some defaults for values */
03921    p->cid_start = ANALOG_CID_START_RING;
03922    p->cid_signalling = CID_SIG_BELL;
03923    /* Sub real is assumed to always be alloc'd */
03924    p->subs[ANALOG_SUB_REAL].allocd = 1;
03925 
03926    return p;
03927 }

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

Definition at line 760 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, NULL, and analog_pvt::owner.

Referenced by dahdi_request().

00761 {
00762    struct ast_channel *ast;
00763 
00764    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
00765    *callwait = (p->owner != NULL);
00766 
00767    if (p->owner) {
00768       if (analog_alloc_sub(p, ANALOG_SUB_CALLWAIT)) {
00769          ast_log(LOG_ERROR, "Unable to alloc subchannel\n");
00770          return NULL;
00771       }
00772    }
00773 
00774    analog_set_outgoing(p, 1);
00775    ast = analog_new_ast_channel(p, AST_STATE_RESERVED, 0,
00776       p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor);
00777    if (!ast) {
00778       analog_set_outgoing(p, 0);
00779    }
00780    return ast;
00781 }

const char* analog_sigtype_to_str ( enum analog_sigtype  sigtype  ) 

Definition at line 126 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

Referenced by __analog_ss_thread(), and analog_handle_init_event().

00127 {
00128    int i;
00129 
00130    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00131       if (sigtype == sigtypes[i].sigtype) {
00132          return sigtypes[i].name;
00133       }
00134    }
00135 
00136    return "Unknown";
00137 }

int analog_ss_thread_start ( struct analog_pvt p,
struct ast_channel ast 
)

Definition at line 2649 of file sig_analog.c.

References __analog_ss_thread(), ast_pthread_create_detached, and NULL.

Referenced by mwi_thread().

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

enum analog_cid_start analog_str_to_cidstart ( const char *  value  ) 

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

00223 {
00224    if (!strcasecmp(value, "ring")) {
00225       return ANALOG_CID_START_RING;
00226    } else if (!strcasecmp(value, "polarity")) {
00227       return ANALOG_CID_START_POLARITY;
00228    } else if (!strcasecmp(value, "polarity_in")) {
00229       return ANALOG_CID_START_POLARITY_IN;
00230    } else if (!strcasecmp(value, "dtmf")) {
00231       return ANALOG_CID_START_DTMF_NOALERT;
00232    }
00233 
00234    return 0;
00235 }

unsigned int analog_str_to_cidtype ( const char *  name  ) 

Definition at line 139 of file sig_analog.c.

References ARRAY_LEN, and cidtypes.

00140 {
00141    int i;
00142 
00143    for (i = 0; i < ARRAY_LEN(cidtypes); i++) {
00144       if (!strcasecmp(cidtypes[i].name, name)) {
00145          return cidtypes[i].cid_type;
00146       }
00147    }
00148 
00149    return 0;
00150 }

enum analog_sigtype analog_str_to_sigtype ( const char *  name  ) 

Definition at line 113 of file sig_analog.c.

References ARRAY_LEN, and sigtypes.

00114 {
00115    int i;
00116 
00117    for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
00118       if (!strcasecmp(sigtypes[i].name, name)) {
00119          return sigtypes[i].sigtype;
00120       }
00121    }
00122 
00123    return 0;
00124 }


Variable Documentation

Global analog callbacks to the upper layer.

Definition at line 3357 of file chan_dahdi.c.

Referenced by analog_all_subchannels_hungup(), analog_alloc_sub(), analog_answer_polarityswitch(), analog_callwait(), analog_cancel_cidspill(), analog_cb_handle_dtmf(), analog_check_confirmanswer(), analog_check_for_conference(), analog_check_waitingfordt(), analog_confmute(), analog_deadlock_avoidance_private(), analog_decrease_ss_count(), analog_dial_digits(), analog_distinctive_ring(), analog_dsp_reset_and_flush_digits(), analog_dsp_set_digitmode(), analog_flash(), analog_get_and_handle_alarms(), analog_get_bridged_channel(), analog_get_callerid(), analog_get_event(), analog_get_orig_dialstring(), analog_get_sub_fd(), analog_handle_notify_message(), analog_hangup_polarityswitch(), analog_has_voicemail(), analog_have_progressdetect(), analog_increase_ss_count(), analog_is_dialing(), analog_is_off_hook(), analog_lock_private(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_alarm(), analog_set_cadence(), analog_set_callwaiting(), analog_set_confirmanswer(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_linear_mode(), analog_set_needringing(), analog_set_new_owner(), analog_set_outgoing(), analog_set_pulsedial(), analog_set_ringtimeout(), analog_set_waitingfordt(), analog_start(), analog_start_cid_detect(), analog_start_polarityswitch(), analog_stop_callwait(), analog_stop_cid_detect(), analog_swap_subs(), analog_train_echocanceller(), analog_unalloc_sub(), analog_unlock_private(), analog_update_conf(), analog_wait_event(), and analog_wink().


Generated on Thu Apr 16 06:33:46 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6