Asterisk - The Open Source Telephony Project  21.4.1
Macros | Functions | Variables
sig_analog.c File Reference

Analog signaling module. More...

#include "asterisk.h"
#include <errno.h>
#include <ctype.h>
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/pickup.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/say.h"
#include "asterisk/manager.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/causes.h"
#include "asterisk/features_config.h"
#include "asterisk/bridge.h"
#include "asterisk/parking.h"
#include "sig_analog.h"

Go to the source code of this file.

Macros

#define analog_get_index(ast, p, nullok)   _analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
 
#define ANALOG_NEED_MFDETECT(p)   (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB))
 
#define gen_analog_field_callback(type, callback_name, def_value)
 
#define ISTRUNK(p)
 
#define MIN_MS_SINCE_FLASH   ( (2000) )
 
#define POLARITY_IDLE   0
 
#define POLARITY_REV   1
 

Functions

static struct ast_frame__analog_handle_event (struct analog_pvt *p, struct ast_channel *ast)
 
static void * __analog_ss_thread (void *data)
 
static int _analog_get_index (struct ast_channel *ast, struct analog_pvt *p, int nullok, const char *fname, unsigned long line)
 
static void analog_all_subchannels_hungup (struct analog_pvt *p)
 
static int analog_alloc_sub (struct analog_pvt *p, enum analog_sub x)
 
int analog_answer (struct analog_pvt *p, struct ast_channel *ast)
 
static void analog_answer_polarityswitch (struct analog_pvt *p)
 
static int analog_attempt_transfer (struct analog_pvt *p)
 
int analog_available (struct analog_pvt *p)
 
int analog_call (struct analog_pvt *p, struct ast_channel *ast, const char *rdest, int timeout)
 
static int analog_callwait (struct analog_pvt *p)
 
static void analog_cancel_cidspill (struct analog_pvt *p)
 
static int analog_canmatch_featurecode (const char *pickupexten, const char *exten)
 
static void analog_cb_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
 
static int analog_check_confirmanswer (struct analog_pvt *p)
 
static int analog_check_for_conference (struct analog_pvt *p)
 
static int analog_check_waitingfordt (struct analog_pvt *p)
 
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)
 
static int analog_confmute (struct analog_pvt *p, int mute)
 
static void analog_deadlock_avoidance_private (struct analog_pvt *p)
 
static void analog_decrease_ss_count (void)
 
void analog_delete (struct analog_pvt *doomed)
 Delete the analog private structure. More...
 
static int analog_dial_digits (struct analog_pvt *p, enum analog_sub sub, struct analog_dialoperation *dop)
 
static int analog_distinctive_ring (struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata)
 
int analog_dnd (struct analog_pvt *p, int flag)
 
static int analog_dsp_reset_and_flush_digits (struct analog_pvt *p)
 
static int analog_dsp_set_digitmode (struct analog_pvt *p, enum analog_dsp_digitmode mode)
 
static char * analog_event2str (enum analog_event event)
 
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)
 
static int analog_flash (struct analog_pvt *p)
 
void analog_free (struct analog_pvt *p)
 
static void analog_get_and_handle_alarms (struct analog_pvt *p)
 
static void * analog_get_bridged_channel (struct ast_channel *chan)
 
static int analog_get_callerid (struct analog_pvt *p, char *name, char *number, enum analog_event *ev, size_t timeout)
 
static int analog_get_event (struct analog_pvt *p)
 
static const char * analog_get_orig_dialstring (struct analog_pvt *p)
 
static int analog_get_sub_fd (struct analog_pvt *p, enum analog_sub sub)
 
void analog_handle_dtmf (struct analog_pvt *p, struct ast_channel *ast, enum analog_sub idx, struct ast_frame **dest)
 
void * analog_handle_init_event (struct analog_pvt *i, int event)
 
static int analog_handle_notify_message (struct ast_channel *chan, struct analog_pvt *p, int cid_flags, int neon_mwievent)
 
static int analog_handles_digit (struct ast_frame *f)
 
int analog_hangup (struct analog_pvt *p, struct ast_channel *ast)
 
static void analog_hangup_polarityswitch (struct analog_pvt *p)
 
static int analog_has_voicemail (struct analog_pvt *p)
 
static int analog_have_progressdetect (struct analog_pvt *p)
 
static void analog_increase_ss_count (void)
 
static int analog_is_dialing (struct analog_pvt *p, enum analog_sub index)
 
static int analog_is_off_hook (struct analog_pvt *p)
 
static void analog_lock_private (struct analog_pvt *p)
 
static void analog_lock_sub_owner (struct analog_pvt *pvt, enum analog_sub sub_idx)
 
static int analog_my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
 
struct analog_pvtanalog_new (enum analog_sigtype signallingtype, void *private_data)
 
static struct ast_channelanalog_new_ast_channel (struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
 
static int analog_off_hook (struct analog_pvt *p)
 
static int analog_on_hook (struct analog_pvt *p)
 
static int analog_play_tone (struct analog_pvt *p, enum analog_sub sub, enum analog_tone tone)
 
static void analog_publish_channel_alarm_clear (int channel)
 
static void analog_publish_dnd_state (int channel, const char *status)
 
struct ast_channelanalog_request (struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
 
static int analog_ring (struct analog_pvt *p)
 
static int analog_send_callerid (struct analog_pvt *p, int cwcid, struct ast_party_caller *caller)
 
static void analog_set_alarm (struct analog_pvt *p, int in_alarm)
 
static void analog_set_cadence (struct analog_pvt *p, struct ast_channel *chan)
 
static void analog_set_callwaiting (struct analog_pvt *p, int callwaiting_enable)
 
static void analog_set_confirmanswer (struct analog_pvt *p, int flag)
 
static void analog_set_dialing (struct analog_pvt *p, int is_dialing)
 
static int analog_set_echocanceller (struct analog_pvt *p, int enable)
 
static void analog_set_inthreeway (struct analog_pvt *p, enum analog_sub sub, int inthreeway)
 
static int analog_set_linear_mode (struct analog_pvt *p, enum analog_sub sub, int linear_mode)
 
static void analog_set_needringing (struct analog_pvt *p, int value)
 
static void analog_set_new_owner (struct analog_pvt *p, struct ast_channel *new_owner)
 
static void analog_set_outgoing (struct analog_pvt *p, int is_outgoing)
 
static void analog_set_pulsedial (struct analog_pvt *p, int flag)
 
static void analog_set_ringtimeout (struct analog_pvt *p, int ringt)
 
static void analog_set_waitingfordt (struct analog_pvt *p, struct ast_channel *ast)
 
const char * analog_sigtype_to_str (enum analog_sigtype sigtype)
 
int analog_ss_thread_start (struct analog_pvt *p, struct ast_channel *chan)
 
static int analog_start (struct analog_pvt *p)
 
static int analog_start_cid_detect (struct analog_pvt *p, int cid_signalling)
 
static void analog_start_polarityswitch (struct analog_pvt *p)
 
static int analog_stop_callwait (struct analog_pvt *p)
 
static int analog_stop_cid_detect (struct analog_pvt *p)
 
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)
 
static void analog_swap_subs (struct analog_pvt *p, enum analog_sub a, enum analog_sub b)
 
static int analog_train_echocanceller (struct analog_pvt *p)
 
static int analog_unalloc_sub (struct analog_pvt *p, enum analog_sub x)
 
static void analog_unlock_private (struct analog_pvt *p)
 
static int analog_update_conf (struct analog_pvt *p)
 
static int analog_wait_event (struct analog_pvt *p)
 
static int analog_wink (struct analog_pvt *p, enum analog_sub index)
 
 gen_analog_field_callback (int, firstdigit_timeout, ANALOG_FIRST_DIGIT_TIMEOUT)
 
 gen_analog_field_callback (int, interdigit_timeout, ANALOG_INTER_DIGIT_TIMEOUT)
 
 gen_analog_field_callback (int, matchdigit_timeout, ANALOG_MATCH_DIGIT_TIMEOUT)
 

Variables

static char analog_defaultcic [64] = ""
 
static char analog_defaultozz [64] = ""
 
struct {
   unsigned int   cid_type
 
   const char *   name
 
cidtypes []
 
struct {
   const char *   name
 
   enum analog_sigtype   sigtype
 
sigtypes []
 

Detailed Description

Analog signaling module.

Author
Matthew Fredrickson cresl.nosp@m.in@d.nosp@m.igium.nosp@m..com

Definition in file sig_analog.c.

Macro Definition Documentation

#define ISTRUNK (   p)
Value:
((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \
(p->sig == ANALOG_SIG_FXSGS))

Definition at line 107 of file sig_analog.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 64 of file sig_analog.c.

Referenced by __analog_handle_event().

#define POLARITY_IDLE   0
Note
Define if you want to check the hook state for an FXO (FXS signalled) interface before dialing on it. Certain FXO interfaces always think they're out of service with this method however.

Definition at line 62 of file sig_analog.c.

Referenced by __analog_handle_event().

Function Documentation

static struct ast_frame* __analog_handle_event ( struct analog_pvt p,
struct ast_channel ast 
)
static

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

< Channel is down and available

< Channel is down, but reserved

< Channel is off hook

< Line is busy

< Digits (or equivalent) have been dialed while offhook

< Channel has detected an incoming call and is waiting for ring

< Digits (or equivalent) have been dialed

< Remote end is ringing

< Line is up

< Line is ringing

Definition at line 2773 of file sig_analog.c.

References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_party_caller::ani, ast_party_caller::ani2, ast_alloca, ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), ast_control_pvt_cause_code::ast_cause, ast_channel_hangupcause_hash_set(), AST_CHANNEL_NAME, AST_CONTROL_ANSWER, AST_CONTROL_FLASH, AST_CONTROL_OFFHOOK, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RING, AST_CONTROL_RINGING, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup_with_cause(), ast_queue_hold(), ast_queue_unhold(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_tvdiff_ms(), ast_tvnow(), analog_pvt::calledsubscriberheld, analog_pvt::callwaitcas, ast_control_pvt_cause_code::chan_name, analog_pvt::channel, analog_pvt::cidrings, ast_control_pvt_cause_code::code, analog_pvt::cshactive, analog_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, analog_pvt::dialing, analog_pvt::dialmode, analog_subchannel::f, analog_pvt::flashtime, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, ast_frame::mallocd, MIN_MS_SINCE_FLASH, analog_pvt::msgstate, ast_party_id::name, ast_party_id::number, ast_frame::offset, analog_pvt::origcid_name, analog_pvt::origcid_num, analog_pvt::owner, POLARITY_IDLE, S_COR, ast_frame::samples, ast_frame::src, ast_party_name::str, ast_party_number::str, ast_frame::subclass, analog_pvt::subs, analog_pvt::transfertobusy, ast_party_name::valid, ast_party_number::valid, and analog_pvt::whichwink.

2774 {
2775  int res, x;
2776  int mysig;
2777  int idx;
2778  char *c;
2779  pthread_t threadid;
2780  struct ast_channel *chan;
2781  struct ast_frame *f;
2782  struct ast_control_pvt_cause_code *cause_code = NULL;
2783  int data_size = sizeof(*cause_code);
2784  char *subclass = NULL;
2785 
2786  ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
2787 
2788  idx = analog_get_index(ast, p, 0);
2789  if (idx < 0) {
2790  return &ast_null_frame;
2791  }
2792  if (idx != ANALOG_SUB_REAL) {
2793  ast_log(LOG_ERROR, "We got an event on a non real sub. Fix it!\n");
2794  }
2795 
2796  mysig = p->sig;
2797  if (p->outsigmod > -1) {
2798  mysig = p->outsigmod;
2799  }
2800 
2801  p->subs[idx].f.frametype = AST_FRAME_NULL;
2802  p->subs[idx].f.subclass.integer = 0;
2803  p->subs[idx].f.datalen = 0;
2804  p->subs[idx].f.samples = 0;
2805  p->subs[idx].f.mallocd = 0;
2806  p->subs[idx].f.offset = 0;
2807  p->subs[idx].f.src = "dahdi_handle_event";
2808  p->subs[idx].f.data.ptr = NULL;
2809  f = &p->subs[idx].f;
2810 
2811  res = analog_get_event(p);
2812 
2813  ast_debug(1, "Got event %s(%d) on channel %d (index %u)\n", analog_event2str(res), res, p->channel, idx);
2814 
2815  if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) {
2816  analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0);
2817  ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
2818  analog_confmute(p, 0);
2819  if (p->dialmode == ANALOG_DIALMODE_BOTH || p->dialmode == ANALOG_DIALMODE_PULSE) {
2820  p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
2821  p->subs[idx].f.subclass.integer = res & 0xff;
2822  analog_handle_dtmf(p, ast, idx, &f);
2823  } else {
2824  ast_debug(1, "Dropping pulse digit '%c' because pulse dialing disabled on channel %d\n", res & 0xff, p->channel);
2825  }
2826  return f;
2827  }
2828 
2829  if (res & ANALOG_EVENT_DTMFDOWN) {
2830  ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
2831  /* Mute conference */
2832  analog_confmute(p, 1);
2834  p->subs[idx].f.subclass.integer = res & 0xff;
2835  analog_handle_dtmf(p, ast, idx, &f);
2836  return f;
2837  }
2838 
2839  switch (res) {
2840  case ANALOG_EVENT_ALARM:
2841  case ANALOG_EVENT_POLARITY:
2842  case ANALOG_EVENT_ONHOOK:
2843  /* add length of "ANALOG " */
2844  data_size += 7;
2845  subclass = analog_event2str(res);
2846  data_size += strlen(subclass);
2847  cause_code = ast_alloca(data_size);
2848  memset(cause_code, 0, data_size);
2849  cause_code->ast_cause = AST_CAUSE_NORMAL_CLEARING;
2850  ast_copy_string(cause_code->chan_name, ast_channel_name(ast), AST_CHANNEL_NAME);
2851  snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "ANALOG %s", subclass);
2852  break;
2853  default:
2854  break;
2855  }
2856 
2857  switch (res) {
2858  case ANALOG_EVENT_EC_DISABLED:
2859  ast_verb(3, "Channel %d echo canceller disabled due to CED detection\n", p->channel);
2860  analog_set_echocanceller(p, 0);
2861  break;
2862 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2863  case ANALOG_EVENT_TX_CED_DETECTED:
2864  ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel);
2865  break;
2866  case ANALOG_EVENT_RX_CED_DETECTED:
2867  ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel);
2868  break;
2869  case ANALOG_EVENT_EC_NLP_DISABLED:
2870  ast_verb(3, "Channel %d echo canceller disabled its NLP.\n", p->channel);
2871  break;
2872  case ANALOG_EVENT_EC_NLP_ENABLED:
2873  ast_verb(3, "Channel %d echo canceller enabled its NLP.\n", p->channel);
2874  break;
2875 #endif
2876  case ANALOG_EVENT_PULSE_START:
2877  /* Stop tone if there's a pulse start and the PBX isn't started */
2878  if (!ast_channel_pbx(ast))
2879  analog_play_tone(p, ANALOG_SUB_REAL, -1);
2880  break;
2881  case ANALOG_EVENT_DIALCOMPLETE:
2882  if (p->inalarm) {
2883  break;
2884  }
2885  x = analog_is_dialing(p, idx);
2886  if (!x) { /* if not still dialing in driver */
2887  analog_set_echocanceller(p, 1);
2888  if (p->echobreak) {
2889  analog_train_echocanceller(p);
2890  ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
2891  p->dop.op = ANALOG_DIAL_OP_REPLACE;
2892  analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
2893  p->echobreak = 0;
2894  } else {
2895  analog_set_dialing(p, 0);
2896  if ((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) {
2897  /* if thru with dialing after offhook */
2899  ast_setstate(ast, AST_STATE_UP);
2900  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
2902  break;
2903  } else { /* if to state wait for offhook to dial rest */
2904  /* we now wait for off hook */
2906  }
2907  }
2908  if (ast_channel_state(ast) == AST_STATE_DIALING) {
2909  if (analog_have_progressdetect(p)) {
2910  ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
2911  } else if (analog_check_confirmanswer(p) || (!p->dialednone
2912  && ((mysig == ANALOG_SIG_EM) || (mysig == ANALOG_SIG_EM_E1)
2913  || (mysig == ANALOG_SIG_EMWINK) || (mysig == ANALOG_SIG_FEATD)
2914  || (mysig == ANALOG_SIG_FEATDMF_TA) || (mysig == ANALOG_SIG_FEATDMF)
2915  || (mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA)
2916  || (mysig == ANALOG_SIG_FGC_CAMAMF) || (mysig == ANALOG_SIG_FEATB)
2917  || (mysig == ANALOG_SIG_SF) || (mysig == ANALOG_SIG_SFWINK)
2918  || (mysig == ANALOG_SIG_SF_FEATD) || (mysig == ANALOG_SIG_SF_FEATDMF)
2919  || (mysig == ANALOG_SIG_SF_FEATB)))) {
2921  } else if (!p->answeronpolarityswitch) {
2922  ast_setstate(ast, AST_STATE_UP);
2923  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
2925  /* If aops=0 and hops=1, this is necessary */
2926  p->polarity = POLARITY_REV;
2927  } else {
2928  /* Start clean, so we can catch the change to REV polarity when party answers */
2929  p->polarity = POLARITY_IDLE;
2930  }
2931  }
2932  }
2933  }
2934  break;
2935  case ANALOG_EVENT_ALARM:
2936  analog_set_alarm(p, 1);
2937  analog_get_and_handle_alarms(p);
2938  cause_code->ast_cause = AST_CAUSE_NETWORK_OUT_OF_ORDER;
2939  case ANALOG_EVENT_ONHOOK:
2940  if (p->calledsubscriberheld && (p->sig == ANALOG_SIG_FXOLS || p->sig == ANALOG_SIG_FXOGS || p->sig == ANALOG_SIG_FXOKS) && idx == ANALOG_SUB_REAL) {
2941  ast_debug(4, "Channel state on %s is %d\n", ast_channel_name(ast), ast_channel_state(ast));
2942  /* Called Subscriber Held: don't let the called party hang up on an incoming call immediately (if it's the only call). */
2943  if (p->subs[ANALOG_SUB_CALLWAIT].owner || p->subs[ANALOG_SUB_THREEWAY].owner) {
2944  ast_debug(2, "Letting this call hang up normally, since it's not the only call\n");
2945  } else if (!p->owner || !p->subs[ANALOG_SUB_REAL].owner || ast_channel_state(ast) != AST_STATE_UP) {
2946  ast_debug(2, "Called Subscriber Held does not apply: channel state is %d\n", ast_channel_state(ast));
2947  } else if (!p->owner || !p->subs[ANALOG_SUB_REAL].owner || strcmp(ast_channel_appl(p->subs[ANALOG_SUB_REAL].owner), "AppDial")) {
2948  /* Called Subscriber held only applies to incoming calls, not outgoing calls.
2949  * We can't use p->outgoing because that is always true, for both incoming and outgoing calls, so it's not accurate.
2950  * We can check the channel application/data instead.
2951  * For incoming calls to the channel, it will look like: AppDial / (Outgoing Line)
2952  * We only want this behavior for regular calls anyways (and not, say, Queue),
2953  * so this would actually work great. But accessing ast_channel_appl can cause a crash if there are no calls left,
2954  * so this check must occur AFTER we confirm the channel state *is* still UP.
2955  */
2956  ast_debug(2, "Called Subscriber Held does not apply: not an incoming call\n");
2957  } else if (analog_is_off_hook(p)) {
2958  ast_log(LOG_WARNING, "Got ONHOOK but channel %d is off hook?\n", p->channel); /* Shouldn't happen */
2959  } else {
2960  ast_verb(3, "Holding incoming call %s for channel %d\n", ast_channel_name(ast), p->channel);
2961  /* Inhibit dahdi_hangup from getting called, and do nothing else now.
2962  * When the DAHDI channel goes off hook again, it'll just get reconnected with the incoming call,
2963  * to which, as far as its concerned, nothing has happened. */
2964  p->cshactive = 1; /* Keep track that this DAHDI channel is currently being held by an incoming call. */
2965  break;
2966  }
2967  }
2968  ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
2969  ast_channel_hangupcause_hash_set(ast, cause_code, data_size);
2970  switch (p->sig) {
2971  case ANALOG_SIG_FXOLS:
2972  case ANALOG_SIG_FXOGS:
2973  case ANALOG_SIG_FXOKS:
2974  analog_start_polarityswitch(p);
2975  p->fxsoffhookstate = 0;
2976  p->onhooktime = time(NULL);
2977  p->msgstate = -1;
2978  /* Check for some special conditions regarding call waiting */
2979  if (idx == ANALOG_SUB_REAL) {
2980  /* The normal line was hung up */
2981  if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
2982  /* Need to hold the lock for real-call, private, and call-waiting call */
2983  analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
2984  if (!p->subs[ANALOG_SUB_CALLWAIT].owner) {
2985  /*
2986  * The call waiting call disappeared.
2987  * This is now a normal hangup.
2988  */
2989  analog_set_echocanceller(p, 0);
2990  return NULL;
2991  }
2992 
2993  /* There's a call waiting call, so ring the phone, but make it unowned in the meantime */
2994  analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
2995  ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
2996  analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
2997  analog_stop_callwait(p);
2998  analog_set_new_owner(p, NULL);
2999  /* Don't start streaming audio yet if the incoming call isn't up yet */
3000  if (ast_channel_state(p->subs[ANALOG_SUB_REAL].owner) != AST_STATE_UP) {
3001  analog_set_dialing(p, 1);
3002  }
3003  /* Unlock the call-waiting call that we swapped to real-call. */
3004  ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
3005  analog_ring(p);
3006  } else if (p->subs[ANALOG_SUB_THREEWAY].owner) {
3007  unsigned int mssinceflash;
3008 
3009  /* Need to hold the lock for real-call, private, and 3-way call */
3010  analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY);
3011  if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
3012  ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
3013  /* Just hangup */
3014  return NULL;
3015  }
3016  if (p->owner != ast) {
3017  ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
3018  ast_log(LOG_WARNING, "This isn't good...\n");
3019  /* Just hangup */
3020  return NULL;
3021  }
3022 
3023  mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
3024  ast_debug(1, "Last flash was %u ms ago\n", mssinceflash);
3025  if (mssinceflash < MIN_MS_SINCE_FLASH) {
3026  /* It hasn't been long enough since the last flashook. This is probably a bounce on
3027  hanging up. Hangup both channels now */
3028  ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
3029  ast_queue_hangup_with_cause(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER);
3031  ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
3032  } else if ((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) {
3033  if (p->transfer) {
3034  /* In any case this isn't a threeway call anymore */
3035  analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
3036  analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
3037 
3038  /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
3039  if (!p->transfertobusy && ast_channel_state(ast) == AST_STATE_BUSY) {
3040  /* Swap subs and dis-own channel */
3041  analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
3042  /* Unlock the 3-way call that we swapped to real-call. */
3043  ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
3044  analog_set_new_owner(p, NULL);
3045  /* Ring the phone */
3046  analog_ring(p);
3047  } else if (!analog_attempt_transfer(p)) {
3048  /*
3049  * Transfer successful. Don't actually hang up at this point.
3050  * Let our channel legs of the calls die off as the transfer
3051  * percolates through the core.
3052  */
3053  break;
3054  }
3055  } else {
3057  ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
3058  }
3059  } else {
3060  /* Swap subs and dis-own channel */
3061  analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
3062  /* Unlock the 3-way call that we swapped to real-call. */
3063  ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
3064  analog_set_new_owner(p, NULL);
3065  /* Ring the phone */
3066  analog_ring(p);
3067  }
3068  }
3069  } else {
3070  ast_log(LOG_WARNING, "Got a hangup and my index is %u?\n", idx);
3071  }
3072  /* Fall through */
3073  default:
3074  analog_set_echocanceller(p, 0);
3075  return NULL;
3076  }
3077  break;
3078  case ANALOG_EVENT_RINGOFFHOOK:
3079  if (p->inalarm) {
3080  break;
3081  }
3082  /* for E911, its supposed to wait for offhook then dial
3083  the second half of the dial string */
3084  if (((mysig == ANALOG_SIG_E911) || (mysig == ANALOG_SIG_FGC_CAMA) || (mysig == ANALOG_SIG_FGC_CAMAMF)) && (ast_channel_state(ast) == AST_STATE_DIALING_OFFHOOK)) {
3085  c = strchr(p->dialdest, '/');
3086  if (c) {
3087  c++;
3088  } else {
3089  c = p->dialdest;
3090  }
3091 
3092  if (*c) {
3093  int numchars = snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
3094  if (numchars >= sizeof(p->dop.dialstr)) {
3095  ast_log(LOG_WARNING, "Dial string '%s' truncated\n", c);
3096  }
3097  } else {
3098  ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
3099  }
3100 
3101  if (strlen(p->dop.dialstr) > 4) {
3102  memset(p->echorest, 'w', sizeof(p->echorest) - 1);
3103  strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
3104  p->echorest[sizeof(p->echorest) - 1] = '\0';
3105  p->echobreak = 1;
3106  p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
3107  } else {
3108  p->echobreak = 0;
3109  }
3110  if (analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop)) {
3111  analog_on_hook(p);
3112  return NULL;
3113  }
3114  analog_set_dialing(p, 1);
3115  return &p->subs[idx].f;
3116  }
3117  switch (p->sig) {
3118  case ANALOG_SIG_FXOLS:
3119  case ANALOG_SIG_FXOGS:
3120  case ANALOG_SIG_FXOKS:
3121  p->fxsoffhookstate = 1;
3122  switch (ast_channel_state(ast)) {
3123  case AST_STATE_RINGING:
3124  analog_set_echocanceller(p, 1);
3125  analog_train_echocanceller(p);
3126  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
3128  /* Make sure it stops ringing */
3129  analog_set_needringing(p, 0);
3130  analog_off_hook(p);
3131  ast_debug(1, "channel %d answered\n", p->channel);
3132 
3133  /* Cancel any running CallerID spill */
3134  analog_cancel_cidspill(p);
3135 
3136  analog_set_dialing(p, 0);
3137  p->callwaitcas = 0;
3138  if (analog_check_confirmanswer(p)) {
3139  /* Ignore answer if "confirm answer" is enabled */
3140  p->subs[idx].f.frametype = AST_FRAME_NULL;
3141  p->subs[idx].f.subclass.integer = 0;
3142  } else if (!ast_strlen_zero(p->dop.dialstr)) {
3143  /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
3144  res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
3145  if (res) {
3146  p->dop.dialstr[0] = '\0';
3147  return NULL;
3148  } else {
3149  ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
3150  p->subs[idx].f.frametype = AST_FRAME_NULL;
3151  p->subs[idx].f.subclass.integer = 0;
3152  analog_set_dialing(p, 1);
3153  }
3154  p->dop.dialstr[0] = '\0';
3156  } else {
3157  ast_setstate(ast, AST_STATE_UP);
3158  analog_answer_polarityswitch(p);
3159  }
3160  return &p->subs[idx].f;
3161  case AST_STATE_DOWN:
3163  ast_channel_rings_set(ast, 1);
3164  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
3166  ast_debug(1, "channel %d picked up\n", p->channel);
3167  return &p->subs[idx].f;
3168  case AST_STATE_UP:
3169  /* Make sure it stops ringing */
3170  analog_off_hook(p);
3171  /* Okay -- probably call waiting */
3172  ast_queue_unhold(p->owner);
3173  break;
3174  case AST_STATE_RESERVED:
3175  /* Start up dialtone */
3176  if (analog_has_voicemail(p)) {
3177  res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_STUTTER);
3178  } else {
3179  res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALTONE);
3180  }
3181  break;
3182  default:
3183  ast_log(LOG_WARNING, "FXO phone off hook in weird state %u??\n", ast_channel_state(ast));
3184  }
3185  break;
3186  case ANALOG_SIG_FXSLS:
3187  case ANALOG_SIG_FXSGS:
3188  case ANALOG_SIG_FXSKS:
3189  if (ast_channel_state(ast) == AST_STATE_RING) {
3190  analog_set_ringtimeout(p, p->ringt_base);
3191  }
3192 
3193  /* Fall through */
3194  case ANALOG_SIG_EM:
3195  case ANALOG_SIG_EM_E1:
3196  case ANALOG_SIG_EMWINK:
3197  case ANALOG_SIG_FEATD:
3198  case ANALOG_SIG_FEATDMF:
3199  case ANALOG_SIG_FEATDMF_TA:
3200  case ANALOG_SIG_E911:
3201  case ANALOG_SIG_FGC_CAMA:
3202  case ANALOG_SIG_FGC_CAMAMF:
3203  case ANALOG_SIG_FEATB:
3204  case ANALOG_SIG_SF:
3205  case ANALOG_SIG_SFWINK:
3206  case ANALOG_SIG_SF_FEATD:
3207  case ANALOG_SIG_SF_FEATDMF:
3208  case ANALOG_SIG_SF_FEATB:
3209  switch (ast_channel_state(ast)) {
3210  case AST_STATE_PRERING:
3212  /* Fall through */
3213  case AST_STATE_DOWN:
3214  case AST_STATE_RING:
3215  ast_debug(1, "Ring detected\n");
3216  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
3218  break;
3219  case AST_STATE_RINGING:
3220  case AST_STATE_DIALING:
3221  if (p->outgoing) {
3222  ast_debug(1, "Line answered\n");
3223  if (analog_check_confirmanswer(p)) {
3224  p->subs[idx].f.frametype = AST_FRAME_NULL;
3225  p->subs[idx].f.subclass.integer = 0;
3226  } else {
3227  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
3229  ast_setstate(ast, AST_STATE_UP);
3230  }
3231  break;
3232  }
3233  /* Fall through */
3234  default:
3235  ast_log(LOG_WARNING, "Ring/Off-hook in strange state %u on channel %d\n", ast_channel_state(ast), p->channel);
3236  break;
3237  }
3238  break;
3239  default:
3240  ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
3241  break;
3242  }
3243  break;
3244  case ANALOG_EVENT_RINGBEGIN:
3245  switch (p->sig) {
3246  case ANALOG_SIG_FXSLS:
3247  case ANALOG_SIG_FXSGS:
3248  case ANALOG_SIG_FXSKS:
3249  if (ast_channel_state(ast) == AST_STATE_RING) {
3250  analog_set_ringtimeout(p, p->ringt_base);
3251  }
3252  break;
3253  default:
3254  break;
3255  }
3256  break;
3257  case ANALOG_EVENT_RINGEROFF:
3258  if (p->inalarm) break;
3259  ast_channel_rings_set(ast, ast_channel_rings(ast) + 1);
3260  if (ast_channel_rings(ast) == p->cidrings) {
3261  analog_send_callerid(p, 0, &p->caller);
3262  }
3263 
3264  if (ast_channel_rings(ast) > p->cidrings) {
3265  analog_cancel_cidspill(p);
3266  p->callwaitcas = 0;
3267  }
3268  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
3270  break;
3271  case ANALOG_EVENT_RINGERON:
3272  break;
3273  case ANALOG_EVENT_NOALARM:
3274  analog_set_alarm(p, 0);
3275  analog_publish_channel_alarm_clear(p->channel);
3276  break;
3277  case ANALOG_EVENT_WINKFLASH:
3278  if (p->inalarm) {
3279  break;
3280  }
3281  /* Remember last time we got a flash-hook */
3282  gettimeofday(&p->flashtime, NULL);
3283  switch (mysig) {
3284  case ANALOG_SIG_FXOLS:
3285  case ANALOG_SIG_FXOGS:
3286  case ANALOG_SIG_FXOKS:
3287  ast_debug(1, "Winkflash, index: %u, normal: %d, callwait: %d, thirdcall: %d\n",
3288  idx, analog_get_sub_fd(p, ANALOG_SUB_REAL), analog_get_sub_fd(p, ANALOG_SUB_CALLWAIT), analog_get_sub_fd(p, ANALOG_SUB_THREEWAY));
3289 
3290  /* Cancel any running CallerID spill */
3291  analog_cancel_cidspill(p);
3292  p->callwaitcas = 0;
3293 
3294  if (idx != ANALOG_SUB_REAL) {
3295  ast_log(LOG_WARNING, "Got flash hook with index %u on channel %d?!?\n", idx, p->channel);
3296  goto winkflashdone;
3297  }
3298 
3299  if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
3300  /* Need to hold the lock for real-call, private, and call-waiting call */
3301  analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
3302  if (!p->subs[ANALOG_SUB_CALLWAIT].owner) {
3303  /*
3304  * The call waiting call dissappeared.
3305  * Let's just ignore this flash-hook.
3306  */
3307  ast_log(LOG_NOTICE, "Whoa, the call-waiting call disappeared.\n");
3308  goto winkflashdone;
3309  }
3310 
3311  /* Swap to call-wait */
3312  analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT);
3313  analog_play_tone(p, ANALOG_SUB_REAL, -1);
3314  analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
3315  ast_debug(1, "Making %s the new owner\n", ast_channel_name(p->owner));
3319  }
3320  analog_stop_callwait(p);
3321 
3322  /* Start music on hold if appropriate */
3323  if (!p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
3324  ast_queue_hold(p->subs[ANALOG_SUB_CALLWAIT].owner, p->mohsuggest);
3325  }
3326  ast_queue_hold(p->subs[ANALOG_SUB_REAL].owner, p->mohsuggest);
3328 
3329  /* Unlock the call-waiting call that we swapped to real-call. */
3330  ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
3331  } else if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
3332  if (!p->threewaycalling) {
3333  /* Just send a flash if no 3-way calling */
3335  goto winkflashdone;
3336  } else if (!analog_check_for_conference(p)) {
3337  ast_callid callid = 0;
3338  int callid_created;
3339  char cid_num[256];
3340  char cid_name[256];
3341 
3342  cid_num[0] = '\0';
3343  cid_name[0] = '\0';
3344  if (p->dahditrcallerid && p->owner) {
3345  if (ast_channel_caller(p->owner)->id.number.valid
3346  && ast_channel_caller(p->owner)->id.number.str) {
3347  ast_copy_string(cid_num, ast_channel_caller(p->owner)->id.number.str,
3348  sizeof(cid_num));
3349  }
3350  if (ast_channel_caller(p->owner)->id.name.valid
3351  && ast_channel_caller(p->owner)->id.name.str) {
3352  ast_copy_string(cid_name, ast_channel_caller(p->owner)->id.name.str,
3353  sizeof(cid_name));
3354  }
3355  }
3356  /* XXX This section needs much more error checking!!! XXX */
3357  /* Start a 3-way call if feasible */
3358  if (!((ast_channel_pbx(ast)) ||
3359  (ast_channel_state(ast) == AST_STATE_UP) ||
3360  (ast_channel_state(ast) == AST_STATE_RING))) {
3361  ast_debug(1, "Flash when call not up or ringing\n");
3362  goto winkflashdone;
3363  }
3364  if (analog_alloc_sub(p, ANALOG_SUB_THREEWAY)) {
3365  ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
3366  goto winkflashdone;
3367  }
3368 
3369  callid_created = ast_callid_threadstorage_auto(&callid);
3370 
3371  /*
3372  * Make new channel
3373  *
3374  * We cannot hold the p or ast locks while creating a new
3375  * channel.
3376  */
3377  analog_unlock_private(p);
3378  ast_channel_unlock(ast);
3379  chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY, NULL);
3380  ast_channel_lock(ast);
3381  analog_lock_private(p);
3382  if (!chan) {
3383  ast_log(LOG_WARNING,
3384  "Cannot allocate new call structure on channel %d\n",
3385  p->channel);
3386  analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
3387  ast_callid_threadstorage_auto_clean(callid, callid_created);
3388  goto winkflashdone;
3389  }
3390  if (p->dahditrcallerid) {
3391  if (!p->origcid_num) {
3392  p->origcid_num = ast_strdup(p->cid_num);
3393  }
3394  if (!p->origcid_name) {
3395  p->origcid_name = ast_strdup(p->cid_name);
3396  }
3397  ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
3398  ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
3399  }
3400  /* Swap things around between the three-way and real call */
3401  analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
3402  /* Disable echo canceller for better dialing */
3403  analog_set_echocanceller(p, 0);
3404  res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_DIALRECALL);
3405  if (res) {
3406  ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
3407  }
3408  analog_set_new_owner(p, chan);
3409  p->ss_astchan = chan;
3410  if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p)) {
3411  ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
3412  res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
3413  analog_set_echocanceller(p, 1);
3414  ast_hangup(chan);
3415  } else {
3416  ast_verb(3, "Started three way call on channel %d\n", p->channel);
3417 
3418  /* Start music on hold */
3419  ast_queue_hold(p->subs[ANALOG_SUB_THREEWAY].owner, p->mohsuggest);
3420  }
3421  ast_callid_threadstorage_auto_clean(callid, callid_created);
3422  }
3423  } else {
3424  /* Already have a 3 way call */
3425  enum analog_sub orig_3way_sub;
3426 
3427  /* Need to hold the lock for real-call, private, and 3-way call */
3428  analog_lock_sub_owner(p, ANALOG_SUB_THREEWAY);
3429  if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
3430  /*
3431  * The 3-way call dissappeared.
3432  * Let's just ignore this flash-hook.
3433  */
3434  ast_log(LOG_NOTICE, "Whoa, the 3-way call disappeared.\n");
3435  goto winkflashdone;
3436  }
3437  orig_3way_sub = ANALOG_SUB_THREEWAY;
3438 
3439  if (p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
3440  /* Call is already up, drop the last person */
3441  ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
3442  /* If the primary call isn't answered yet, use it */
3443  if ((ast_channel_state(p->subs[ANALOG_SUB_REAL].owner) != AST_STATE_UP) &&
3445  /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
3446  analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
3447  orig_3way_sub = ANALOG_SUB_REAL;
3448  analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
3449  }
3450  /* Drop the last call and stop the conference */
3451  ast_verb(3, "Dropping three-way call on %s\n", ast_channel_name(p->subs[ANALOG_SUB_THREEWAY].owner));
3453  analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
3454  analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
3455  } else {
3456  /* Lets see what we're up to */
3457  if (((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) &&
3458  (p->transfertobusy || (ast_channel_state(ast) != AST_STATE_BUSY))) {
3459  ast_verb(3, "Building conference call with %s and %s\n",
3460  ast_channel_name(p->subs[ANALOG_SUB_THREEWAY].owner),
3461  ast_channel_name(p->subs[ANALOG_SUB_REAL].owner));
3462  /* Put them in the threeway, and flip */
3463  analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 1);
3464  analog_set_inthreeway(p, ANALOG_SUB_REAL, 1);
3465  analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
3466  orig_3way_sub = ANALOG_SUB_REAL;
3467  ast_queue_unhold(p->subs[orig_3way_sub].owner);
3468  analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
3469  } else {
3470  ast_verb(3, "Dumping incomplete call on %s\n", ast_channel_name(p->subs[ANALOG_SUB_THREEWAY].owner));
3471  analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
3472  orig_3way_sub = ANALOG_SUB_REAL;
3474  analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
3476  analog_set_echocanceller(p, 1);
3477  }
3478  }
3479  ast_channel_unlock(p->subs[orig_3way_sub].owner);
3480  }
3481 winkflashdone:
3482  analog_update_conf(p);
3483  break;
3484  case ANALOG_SIG_EM:
3485  case ANALOG_SIG_EM_E1:
3486  case ANALOG_SIG_FEATD:
3487  case ANALOG_SIG_SF:
3488  case ANALOG_SIG_SFWINK:
3489  case ANALOG_SIG_SF_FEATD:
3490  case ANALOG_SIG_FXSLS:
3491  case ANALOG_SIG_FXSGS:
3492  if (p->dialing) {
3493  ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
3494  } else {
3495  ast_debug(1, "Got wink in weird state %u on channel %d\n", ast_channel_state(ast), p->channel);
3496  }
3497  break;
3498  case ANALOG_SIG_FEATDMF_TA:
3499  switch (p->whichwink) {
3500  case 0:
3501  ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", ast_channel_caller(p->owner)->ani2,
3502  S_COR(ast_channel_caller(p->owner)->ani.number.valid,
3503  ast_channel_caller(p->owner)->ani.number.str, ""));
3504  snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
3505  ast_channel_caller(p->owner)->ani2,
3506  S_COR(ast_channel_caller(p->owner)->ani.number.valid,
3507  ast_channel_caller(p->owner)->ani.number.str, ""));
3508  break;
3509  case 1:
3510  ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
3511  break;
3512  case 2:
3513  ast_log(LOG_WARNING, "Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA\n");
3514  return NULL;
3515  }
3516  p->whichwink++;
3517  /* Fall through */
3518  case ANALOG_SIG_FEATDMF:
3519  case ANALOG_SIG_E911:
3520  case ANALOG_SIG_FGC_CAMAMF:
3521  case ANALOG_SIG_FGC_CAMA:
3522  case ANALOG_SIG_FEATB:
3523  case ANALOG_SIG_SF_FEATDMF:
3524  case ANALOG_SIG_SF_FEATB:
3525  case ANALOG_SIG_EMWINK:
3526  /* FGD MF and EMWINK *Must* wait for wink */
3527  if (!ast_strlen_zero(p->dop.dialstr)) {
3528  res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
3529  if (res) {
3530  p->dop.dialstr[0] = '\0';
3531  return NULL;
3532  } else {
3533  ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
3534  }
3535  }
3536  p->dop.dialstr[0] = '\0';
3537  break;
3538  default:
3539  ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
3540  }
3541  break;
3542  case ANALOG_EVENT_HOOKCOMPLETE:
3543  if (p->inalarm) break;
3544  if (analog_check_waitingfordt(p)) {
3545  break;
3546  }
3547  switch (mysig) {
3548  case ANALOG_SIG_FXSLS: /* only interesting for FXS */
3549  case ANALOG_SIG_FXSGS:
3550  case ANALOG_SIG_FXSKS:
3551  case ANALOG_SIG_EM:
3552  case ANALOG_SIG_EM_E1:
3553  case ANALOG_SIG_EMWINK:
3554  case ANALOG_SIG_FEATD:
3555  case ANALOG_SIG_SF:
3556  case ANALOG_SIG_SFWINK:
3557  case ANALOG_SIG_SF_FEATD:
3558  if (!ast_strlen_zero(p->dop.dialstr)) {
3559  res = analog_dial_digits(p, ANALOG_SUB_REAL, &p->dop);
3560  if (res) {
3561  p->dop.dialstr[0] = '\0';
3562  return NULL;
3563  } else {
3564  ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
3565  }
3566  }
3567  p->dop.dialstr[0] = '\0';
3568  p->dop.op = ANALOG_DIAL_OP_REPLACE;
3569  break;
3570  case ANALOG_SIG_FEATDMF:
3571  case ANALOG_SIG_FEATDMF_TA:
3572  case ANALOG_SIG_E911:
3573  case ANALOG_SIG_FGC_CAMA:
3574  case ANALOG_SIG_FGC_CAMAMF:
3575  case ANALOG_SIG_FEATB:
3576  case ANALOG_SIG_SF_FEATDMF:
3577  case ANALOG_SIG_SF_FEATB:
3578  ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
3579  break;
3580  default:
3581  break;
3582  }
3583  break;
3584  case ANALOG_EVENT_POLARITY:
3585  /*
3586  * If we get a Polarity Switch event, this could be
3587  * due to line seizure, remote end connect or remote end disconnect.
3588  *
3589  * Check to see if we should change the polarity state and
3590  * mark the channel as UP or if this is an indication
3591  * of remote end disconnect.
3592  */
3593 
3594  if (p->polarityonanswerdelay > 0) {
3595  /* check if event is not too soon after OffHook or Answer */
3596  if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
3597  switch (ast_channel_state(ast)) {
3598  case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */
3599  case AST_STATE_RINGING: /*!< Remote end is ringing */
3600  if (p->answeronpolarityswitch) {
3601  ast_debug(1, "Answering on polarity switch! channel %d\n", p->channel);
3603  p->polarity = POLARITY_REV;
3604  if (p->hanguponpolarityswitch) {
3605  p->polaritydelaytv = ast_tvnow();
3606  }
3607  } else {
3608  ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel);
3609  }
3610  break;
3611 
3612  case AST_STATE_UP: /*!< Line is up */
3613  case AST_STATE_RING: /*!< Line is ringing */
3614  if (p->hanguponpolarityswitch) {
3615  ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel);
3616  ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3617  ast_channel_hangupcause_hash_set(ast, cause_code, data_size);
3619  p->polarity = POLARITY_IDLE;
3620  } else {
3621  ast_debug(1, "Ignore Hangup on polarity switch, channel %d\n", p->channel);
3622  }
3623  break;
3624 
3625  case AST_STATE_DOWN: /*!< Channel is down and available */
3626  case AST_STATE_RESERVED: /*!< Channel is down, but reserved */
3627  case AST_STATE_OFFHOOK: /*!< Channel is off hook */
3628  case AST_STATE_BUSY: /*!< Line is busy */
3629  case AST_STATE_DIALING_OFFHOOK: /*!< Digits (or equivalent) have been dialed while offhook */
3630  case AST_STATE_PRERING: /*!< Channel has detected an incoming call and is waiting for ring */
3631  default:
3632  if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
3633  ast_debug(1, "Ignoring Polarity switch on channel %d, state %u\n", p->channel, ast_channel_state(ast));
3634  }
3635  break;
3636  }
3637 
3638  } else {
3639  /* event is too soon after OffHook or Answer */
3640  switch (ast_channel_state(ast)) {
3641  case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */
3642  case AST_STATE_RINGING: /*!< Remote end is ringing */
3643  if (p->answeronpolarityswitch) {
3644  ast_debug(1, "Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %u\n", p->channel, ast_channel_state(ast));
3645  }
3646  break;
3647 
3648  case AST_STATE_UP: /*!< Line is up */
3649  case AST_STATE_RING: /*!< Line is ringing */
3650  if (p->hanguponpolarityswitch) {
3651  ast_debug(1, "Polarity switch detected but NOT hanging up (too close to Answer event) on channel %d, state %u\n", p->channel, ast_channel_state(ast));
3652  }
3653  break;
3654 
3655  default:
3656  if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
3657  ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %u\n", p->channel, ast_channel_state(ast));
3658  }
3659  break;
3660  }
3661  }
3662  }
3663 
3664  /* Added more log_debug information below to provide a better indication of what is going on */
3665  ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast_channel_state(ast), p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
3666  break;
3667  default:
3668  ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
3669  }
3670  return &p->subs[idx].f;
3671 }
enum analog_dialmode dialmode
Definition: sig_analog.h:321
#define POLARITY_IDLE
Definition: sig_analog.c:62
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
char chan_name[AST_CHANNEL_NAME]
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
unsigned int cshactive
Definition: sig_analog.h:334
ast_channel_state
ast_channel states
Definition: channelstate.h:35
char * str
Subscriber name (Malloced)
Definition: channel.h:264
unsigned int dialing
Definition: sig_analog.h:336
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
unsigned int transfertobusy
Definition: sig_analog.h:306
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
struct timeval flashtime
Definition: sig_analog.h:364
struct ast_frame_subclass subclass
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
struct ast_channel * owner
Definition: sig_analog.h:277
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:427
const char * src
void ast_callid_threadstorage_auto_clean(ast_callid callid, int callid_created)
Use in conjunction with ast_callid_threadstorage_auto. Cleans up the references and if the callid was...
Definition: logger.c:2378
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
#define ast_debug(level,...)
Log a DEBUG message.
analog_sub
Definition: sig_analog.h:108
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:433
char * origcid_num
Definition: sig_analog.h:367
union ast_frame::@224 data
int whichwink
Definition: sig_analog.h:365
#define AST_CHANNEL_NAME
Definition: channel.h:171
unsigned int dahditrcallerid
Definition: sig_analog.h:296
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
int msgstate
-1 = unknown, 0 = no messages, 1 = new messages available
Definition: sig_analog.h:284
char * origcid_name
Definition: sig_analog.h:368
struct ast_frame ast_null_frame
Definition: main/frame.c:79
int ast_callid_threadstorage_auto(ast_callid *callid)
Checks thread storage for a callid and stores a reference if it exists. If not, then a new one will b...
Definition: logger.c:2356
int cidrings
Definition: sig_analog.h:358
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
#define MIN_MS_SINCE_FLASH
Definition: sig_analog.c:64
Data structure associated with a single frame of data.
unsigned int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: sig_analog.h:348
struct ast_frame f
Definition: sig_analog.h:265
enum ast_frame_type frametype
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:279
struct analog_subchannel subs[3]
Definition: sig_analog.h:279
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2458
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:297
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
Definition: channel.c:4346
unsigned int calledsubscriberheld
Definition: sig_analog.h:292
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
void analog_delete ( struct analog_pvt doomed)

Delete the analog private structure.

Since
1.8
Parameters
doomedAnalog private structure to delete.

Definition at line 4104 of file sig_analog.c.

4105 {
4106  ast_free(doomed);
4107 }