Sat Mar 24 23:27:24 2007

Asterisk developer's documentation


chan_zap.c File Reference

Zaptel Pseudo TDM interface. More...

#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <zaptel.h>
#include <math.h>
#include <tonezone.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"

Include dependency graph for chan_zap.c:

Go to the source code of this file.

Data Structures

struct  distRingData
struct  ringContextData
struct  zt_distRings
struct  zt_pvt
struct  zt_subchannel

Defines

#define ASCII_BYTES_PER_CHAR   80
#define AST_LAW(p)   (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
#define CALLWAITING_REPEAT_SAMPLES   ( (10000 * 8) / READ_SIZE)
#define CALLWAITING_SILENT_SAMPLES   ( (300 * 8) / READ_SIZE)
#define CANBUSYDETECT(p)   (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
#define CANPROGRESSDETECT(p)   (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
#define CHAN_PSEUDO   -2
#define CHANNEL_PSEUDO   -12
#define CIDCW_EXPIRE_SAMPLES   ( (500 * 8) / READ_SIZE)
#define CONF_USER_REAL   (1 << 0)
#define CONF_USER_THIRDCALL   (1 << 1)
#define DCHAN_AVAILABLE   (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
#define DCHAN_NOTINALARM   (1 << 1)
#define DCHAN_PROVISIONED   (1 << 0)
#define DCHAN_UP   (1 << 2)
#define DEFAULT_CIDRINGS   1
 Typically, how many rings before we should send Caller*ID.
#define DEFAULT_RINGT   ( (8000 * 8) / READ_SIZE)
#define END_SILENCE_LEN   400
#define FORMAT   "%-40.40s %-10.10s %-10d %-10d %-10d\n"
#define FORMAT   "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
#define FORMAT2   "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
#define FORMAT2   "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
#define GET_CHANNEL(p)   ((p)->channel)
#define HANGUP   1
#define HEADER_LEN   ((HEADER_MS + TRAILER_MS) * 8)
#define HEADER_MS   50
#define ISTRUNK(p)
#define MASK_AVAIL   (1 << 0)
#define MASK_INUSE   (1 << 1)
#define MAX_CHANNELS   672
#define MAX_SLAVES   4
#define MIN_MS_SINCE_FLASH   ( (2000) )
#define NEED_MFDETECT(p)   (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FEATB))
 Signaling types that need to use MF detection should be placed in this macro.
#define NUM_CADENCE_MAX   25
#define NUM_DCHANS   4
#define NUM_SPANS   32
#define POLARITY_IDLE   0
#define POLARITY_REV   1
#define READ_SIZE   160
#define sig2str   zap_sig2str
#define SIG_E911   (0x1000000 | ZT_SIG_EM)
#define SIG_EM   ZT_SIG_EM
#define SIG_EM_E1   ZT_SIG_EM_E1
#define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
#define SIG_FEATB   (0x0800000 | ZT_SIG_EM)
#define SIG_FEATD   (0x0200000 | ZT_SIG_EM)
#define SIG_FEATDMF   (0x0400000 | ZT_SIG_EM)
#define SIG_FEATDMF_TA   (0x2000000 | ZT_SIG_EM)
#define SIG_FXOGS   ZT_SIG_FXOGS
#define SIG_FXOKS   ZT_SIG_FXOKS
#define SIG_FXOLS   ZT_SIG_FXOLS
#define SIG_FXSGS   ZT_SIG_FXSGS
#define SIG_FXSKS   ZT_SIG_FXSKS
#define SIG_FXSLS   ZT_SIG_FXSLS
#define SIG_GR303FXOKS   (0x0100000 | ZT_SIG_FXOKS)
#define SIG_GR303FXSKS   (0x0100000 | ZT_SIG_FXSKS)
#define SIG_PRI   ZT_SIG_CLEAR
#define SIG_R2   ZT_SIG_CAS
#define SIG_SF   ZT_SIG_SF
#define SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
#define SIG_SF_FEATD   (0x0200000 | ZT_SIG_SF)
#define SIG_SF_FEATDMF   (0x0400000 | ZT_SIG_SF)
#define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
#define SUB_CALLWAIT   1
#define SUB_REAL   0
#define SUB_THREEWAY   2
#define TRAILER_MS   5
#define TRANSFER   0
#define ZT_EVENT_DTMFDOWN   0
#define ZT_EVENT_DTMFUP   0

Functions

static int __unload_module (void)
static struct ast_frame__zt_exception (struct ast_channel *ast)
static int action_transfer (struct mansession *s, struct message *m)
static int action_transferhangup (struct mansession *s, struct message *m)
static int action_zapdialoffhook (struct mansession *s, struct message *m)
static int action_zapdndoff (struct mansession *s, struct message *m)
static int action_zapdndon (struct mansession *s, struct message *m)
static int action_zaprestart (struct mansession *s, struct message *m)
static int action_zapshowchannels (struct mansession *s, struct message *m)
static char * alarm2str (int alarm)
static int alloc_sub (struct zt_pvt *p, int x)
 AST_MUTEX_DEFINE_STATIC (monlock)
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
 AST_MUTEX_DEFINE_STATIC (iflock)
 Protect the interface list (of zt_pvt's).
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static int attempt_transfer (struct zt_pvt *p)
static int available (struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
static int bump_gains (struct zt_pvt *p)
static struct zt_pvtchandup (struct zt_pvt *src)
static int check_for_conference (struct zt_pvt *p)
static int conf_add (struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
static int conf_del (struct zt_pvt *p, struct zt_subchannel *c, int index)
char * description ()
 Provides a description of the module.
static int destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now)
static void destroy_zt_pvt (struct zt_pvt **pvt)
static void disable_dtmf_detect (struct zt_pvt *p)
static void * do_monitor (void *data)
static void enable_dtmf_detect (struct zt_pvt *p)
static char * event2str (int event)
static void fill_rxgain (struct zt_gains *g, float gain, int law)
static void fill_txgain (struct zt_gains *g, float gain, int law)
static struct zt_pvtfind_channel (int channel)
static int get_alarms (struct zt_pvt *p)
static int handle_init_event (struct zt_pvt *i, int event)
static int handle_zap_show_cadences (int fd, int argc, char *argv[])
static int has_voicemail (struct zt_pvt *p)
static int isourconf (struct zt_pvt *p, struct zt_subchannel *c)
static int isslavenative (struct zt_pvt *p, struct zt_pvt **out)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static struct zt_pvtmkintf (int channel, int signalling, int radio, struct zt_pri *pri, int reloading)
static int my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
static int my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
int reload (void)
 Reload stuff.
static int reset_conf (struct zt_pvt *p)
static int restart_monitor (void)
static int restore_conference (struct zt_pvt *p)
static int restore_gains (struct zt_pvt *p)
static int save_conference (struct zt_pvt *p)
static int send_callerid (struct zt_pvt *p)
int send_cwcidspill (struct zt_pvt *p)
int set_actual_gain (int fd, int chan, float rxgain, float txgain, int law)
int set_actual_rxgain (int fd, int chan, float gain, int law)
int set_actual_txgain (int fd, int chan, float gain, int law)
static int setup_zap (int reload)
static void * ss_thread (void *data)
static void swap_subs (struct zt_pvt *p, int a, int b)
static int unalloc_sub (struct zt_pvt *p, int x)
int unload_module ()
 Cleanup all module structures, sockets, etc.
static int update_conf (struct zt_pvt *p)
int usecount ()
 Provides a usecount.
static void wakeup_sub (struct zt_pvt *p, int a, void *pri)
static int zap_destroy_channel (int fd, int argc, char **argv)
static int zap_fake_event (struct zt_pvt *p, int mode)
static void zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *pri)
static int zap_restart (void)
static int zap_restart_cmd (int fd, int argc, char **argv)
static int zap_show_channel (int fd, int argc, char **argv)
static int zap_show_channels (int fd, int argc, char **argv)
static int zap_show_status (int fd, int argc, char *argv[])
static char * zap_sig2str (int sig)
static int zt_answer (struct ast_channel *ast)
static enum ast_bridge_result zt_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int zt_call (struct ast_channel *ast, char *rdest, int timeout)
static int zt_callwait (struct ast_channel *ast)
static void zt_close (int fd)
static int zt_confmute (struct zt_pvt *p, int muted)
static int zt_digit (struct ast_channel *ast, char digit)
static void zt_disable_ec (struct zt_pvt *p)
static void zt_enable_ec (struct zt_pvt *p)
ast_framezt_exception (struct ast_channel *ast)
static int zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static int zt_get_event (int fd)
 Avoid the silly zt_getevent which ignores a bunch of events.
static int zt_get_history (int fd, void *buf, int buf_size)
static int zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok)
static struct ast_framezt_handle_event (struct ast_channel *ast)
static int zt_hangup (struct ast_channel *ast)
static int zt_indicate (struct ast_channel *chan, int condition)
static void zt_link (struct zt_pvt *slave, struct zt_pvt *master)
static struct ast_channelzt_new (struct zt_pvt *, int, int, int, int, int)
static int zt_open (char *fn)
ast_framezt_read (struct ast_channel *ast)
static struct ast_channelzt_request (const char *type, int format, void *data, int *cause)
static int zt_ring_phone (struct zt_pvt *p)
static int zt_sendtext (struct ast_channel *c, const char *text)
static int zt_set_hook (int fd, int hs)
int zt_setlaw (int zfd, int law)
int zt_setlinear (int zfd, int linear)
static int zt_setoption (struct ast_channel *chan, int option, void *data, int datalen)
static void zt_train_ec (struct zt_pvt *p)
static void zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock)
static int zt_wait_event (int fd)
 Avoid the silly zt_waitevent which ignores a bunch of events.
static int zt_wink (struct zt_pvt *p, int index)
static int zt_write (struct ast_channel *ast, struct ast_frame *frame)

Variables

static char accountcode [AST_MAX_ACCOUNT_CODE] = ""
static int adsi = 0
struct {
   int   alarm
   char *   description
   unsigned int   event_log:1
   enum queue_result   id
   char *   name
   char *   name
   char *   name
   rtpPayloadType   payloadType
   unsigned int   queue_log:1
   char *   subtype
   char *   text
   char *   type
   int   val
alarms []
static int amaflags = 0
static int answeronpolarityswitch = 0
 Whether we answer on a Polarity Switch event.
static int busy_quietlength = 0
static int busy_tonelength = 0
static int busycount = 3
static int busydetect = 0
static struct zt_ring_cadence cadences [NUM_CADENCE_MAX]
static int callprogress = 0
static int callreturn = 0
static int callwaiting = 0
static int callwaitingcallerid = 0
static int cancallforward = 0
static int canpark = 0
static char cid_name [256] = ""
static char cid_num [256] = ""
static int cid_signalling = CID_SIG_BELL
static int cid_start = CID_START_RING
static int cidrings [NUM_CADENCE_MAX]
 cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.
static const char config [] = "zapata.conf"
static char context [AST_MAX_CONTEXT] = "default"
static ast_group_t cur_callergroup = 0
static int cur_debounce = -1
static int cur_flash = -1
static ast_group_t cur_group = 0
static ast_group_t cur_pickupgroup = 0
static int cur_preflash = -1
static int cur_prewink = -1
static int cur_priexclusive = 0
static int cur_rxflash = -1
static int cur_rxwink = -1
static int cur_signalling = -1
static int cur_start = -1
static int cur_wink = -1
static char defaultcic [64] = ""
static char defaultozz [64] = ""
static const char desc [] = "Zapata Telephony"
static char destroy_channel_usage []
static struct zt_distRings drings
static int echocanbridged = 0
static int echocancel
static int echotraining
static char * events []
static int firstdigittimeout = 16000
 Wait up to 16 seconds for first digit (FXO logic).
static int gendigittimeout = 8000
 How long to wait for following digits (FXO logic).
static int hanguponpolarityswitch = 0
 Whether we hang up on a Polarity Switch event.
static int hidecallerid = 0
static int ifcount = 0
static struct zt_pvtifend
static struct zt_pvtiflist
static int immediate = 0
static char language [MAX_LANGUAGE] = ""
static char mailbox [AST_MAX_EXTENSION]
static int matchdigittimeout = 3000
 How long to wait for an extra digit, if there is an ambiguous match.
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static char musicclass [MAX_MUSICCLASS] = ""
static int num_cadence = 4
static int numbufs = 4
static int polarityonanswerdelay = 600
 How long (ms) to ignore Polarity Switch events after we answer a call.
static int priindication_oob = 0
static char progzone [10] = ""
static int pulse
int receivedRingT
static int relaxdtmf = 0
static int restrictcid = 0
static int ringt_base = DEFAULT_RINGT
zt_pvtround_robin [32]
static float rxgain = 0.0
static int sendcalleridafter = DEFAULT_CIDRINGS
 When to send the CallerID signals (rings).
static char show_channel_usage []
static char show_channels_usage []
static int stripmsd = 0
static char * subnames []
static const char tdesc [] = "Zapata Telephony Driver"
static int threewaycalling = 0
static int tonezone = -1
static int transfer = 0
static int transfertobusy = 1
static float txgain = 0.0
static const char type [] = "Zap"
static int use_callerid = 1
static int use_callingpres = 0
static int usecnt = 0
static int usedistinctiveringdetection = 0
static int user_has_defined_cadences = 0
static struct ast_cli_entry zap_cli []
static char zap_restart_usage []
static char zap_show_cadences_help []
static char zap_show_status_usage []
static const struct ast_channel_tech zap_tech
static int zaptrcallerid = 0


Detailed Description

Zaptel Pseudo TDM interface.

Connects to the zaptel telephony library as well as libpri. Libpri is optional and needed only if you are going to use ISDN connections.

You need to install libraries before you attempt to compile and install the zaptel channel.

See also

Definition in file chan_zap.c.


Define Documentation

#define ASCII_BYTES_PER_CHAR   80
 

Referenced by zt_sendtext().

#define AST_LAW  )     (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
 

Definition at line 136 of file chan_zap.c.

Referenced by send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_sendtext().

#define CALLWAITING_REPEAT_SAMPLES   ( (10000 * 8) / READ_SIZE)
 

300 ms

Definition at line 385 of file chan_zap.c.

Referenced by zt_callwait().

#define CALLWAITING_SILENT_SAMPLES   ( (300 * 8) / READ_SIZE)
 

300 ms

Definition at line 384 of file chan_zap.c.

#define CANBUSYDETECT  )     (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
 

Definition at line 779 of file chan_zap.c.

Referenced by zt_new().

#define CANPROGRESSDETECT  )     (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
 

Definition at line 780 of file chan_zap.c.

Referenced by zt_handle_event(), and zt_new().

#define CHAN_PSEUDO   -2
 

Definition at line 190 of file chan_zap.c.

Referenced by enable_dtmf_detect(), mkintf(), zt_new(), and zt_request().

#define CHANNEL_PSEUDO   -12
 

Definition at line 134 of file chan_zap.c.

#define CIDCW_EXPIRE_SAMPLES   ( (500 * 8) / READ_SIZE)
 

500 ms

Definition at line 386 of file chan_zap.c.

Referenced by send_callerid().

#define CONF_USER_REAL   (1 << 0)
 

Definition at line 518 of file chan_zap.c.

#define CONF_USER_THIRDCALL   (1 << 1)
 

Definition at line 519 of file chan_zap.c.

#define DCHAN_AVAILABLE   (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
 

Definition at line 196 of file chan_zap.c.

#define DCHAN_NOTINALARM   (1 << 1)
 

Definition at line 193 of file chan_zap.c.

#define DCHAN_PROVISIONED   (1 << 0)
 

Definition at line 192 of file chan_zap.c.

#define DCHAN_UP   (1 << 2)
 

Definition at line 194 of file chan_zap.c.

#define DEFAULT_CIDRINGS   1
 

Typically, how many rings before we should send Caller*ID.

Definition at line 132 of file chan_zap.c.

#define DEFAULT_RINGT   ( (8000 * 8) / READ_SIZE)
 

Definition at line 388 of file chan_zap.c.

#define END_SILENCE_LEN   400
 

Referenced by zt_sendtext().

#define FORMAT   "%-40.40s %-10.10s %-10d %-10d %-10d\n"
 

#define FORMAT   "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
 

#define FORMAT2   "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
 

#define FORMAT2   "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
 

#define GET_CHANNEL  )     ((p)->channel)
 

Definition at line 727 of file chan_zap.c.

#define HANGUP   1
 

Definition at line 10028 of file chan_zap.c.

Referenced by action_transferhangup(), and zap_fake_event().

#define HEADER_LEN   ((HEADER_MS + TRAILER_MS) * 8)
 

Referenced by zt_sendtext().

#define HEADER_MS   50
 

Referenced by zt_sendtext().

#define ISTRUNK  ) 
 

Value:

((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
         (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))

Definition at line 776 of file chan_zap.c.

Referenced by ss_thread(), and zt_indicate().

#define MASK_AVAIL   (1 << 0)
 

Channel available for PRI use

Definition at line 381 of file chan_zap.c.

#define MASK_INUSE   (1 << 1)
 

Channel currently in use

Definition at line 382 of file chan_zap.c.

#define MAX_CHANNELS   672
 

No more than a DS3 per trunk group

Definition at line 188 of file chan_zap.c.

#define MAX_SLAVES   4
 

Definition at line 521 of file chan_zap.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )
 

2000 ms

Definition at line 387 of file chan_zap.c.

Referenced by zt_handle_event().

#define NEED_MFDETECT  )     (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FEATB))
 

Signaling types that need to use MF detection should be placed in this macro.

Definition at line 139 of file chan_zap.c.

Referenced by ss_thread(), and zt_new().

#define NUM_CADENCE_MAX   25
 

Definition at line 752 of file chan_zap.c.

#define NUM_DCHANS   4
 

No more than 4 d-channels

Definition at line 187 of file chan_zap.c.

#define NUM_SPANS   32
 

Definition at line 186 of file chan_zap.c.

#define POLARITY_IDLE   0
 

Definition at line 478 of file chan_zap.c.

Referenced by unalloc_sub(), zt_handle_event(), and zt_hangup().

#define POLARITY_REV   1
 

Definition at line 479 of file chan_zap.c.

Referenced by handle_init_event(), and zt_handle_event().

#define READ_SIZE   160
 

Chunk size to read -- we use 20ms chunks to make things happy.

Definition at line 379 of file chan_zap.c.

Referenced by my_zt_write(), send_cwcidspill(), zt_callwait(), zt_read(), and zt_setoption().

#define sig2str   zap_sig2str
 

Definition at line 1200 of file chan_zap.c.

Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().

#define SIG_E911   (0x1000000 | ZT_SIG_EM)
 

Definition at line 167 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_EM   ZT_SIG_EM
 

Definition at line 162 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_EM_E1   ZT_SIG_EM_E1
 

Definition at line 182 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
 

Definition at line 163 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_FEATB   (0x0800000 | ZT_SIG_EM)
 

Definition at line 166 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_FEATD   (0x0200000 | ZT_SIG_EM)
 

Definition at line 164 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_FEATDMF   (0x0400000 | ZT_SIG_EM)
 

Definition at line 165 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_FEATDMF_TA   (0x2000000 | ZT_SIG_EM)
 

Definition at line 168 of file chan_zap.c.

Referenced by zap_sig2str(), zt_call(), and zt_handle_event().

#define SIG_FXOGS   ZT_SIG_FXOGS
 

Definition at line 173 of file chan_zap.c.

Referenced by available(), handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().

#define SIG_FXOKS   ZT_SIG_FXOKS
 

Definition at line 174 of file chan_zap.c.

Referenced by available(), handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().

#define SIG_FXOLS   ZT_SIG_FXOLS
 

Definition at line 172 of file chan_zap.c.

Referenced by available(), handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().

#define SIG_FXSGS   ZT_SIG_FXSGS
 

Definition at line 170 of file chan_zap.c.

Referenced by available(), handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().

#define SIG_FXSKS   ZT_SIG_FXSKS
 

Definition at line 171 of file chan_zap.c.

Referenced by available(), handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_new().

#define SIG_FXSLS   ZT_SIG_FXSLS
 

Definition at line 169 of file chan_zap.c.

Referenced by available(), handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().

#define SIG_GR303FXOKS   (0x0100000 | ZT_SIG_FXOKS)
 

Definition at line 183 of file chan_zap.c.

Referenced by handle_init_event(), and zap_sig2str().

#define SIG_GR303FXSKS   (0x0100000 | ZT_SIG_FXSKS)
 

Definition at line 184 of file chan_zap.c.

Referenced by handle_init_event(), and zap_sig2str().

#define SIG_PRI   ZT_SIG_CLEAR
 

Definition at line 175 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().

#define SIG_R2   ZT_SIG_CAS
 

Definition at line 176 of file chan_zap.c.

Referenced by zap_sig2str(), zt_answer(), zt_handle_event(), and zt_hangup().

#define SIG_SF   ZT_SIG_SF
 

Definition at line 177 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
 

Definition at line 181 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_SF_FEATD   (0x0200000 | ZT_SIG_SF)
 

Definition at line 179 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_SF_FEATDMF   (0x0400000 | ZT_SIG_SF)
 

Definition at line 180 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
 

Definition at line 178 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().

#define SUB_CALLWAIT   1
 

Call-Waiting call on hold

Definition at line 474 of file chan_zap.c.

#define SUB_REAL   0
 

Active call

Definition at line 473 of file chan_zap.c.

#define SUB_THREEWAY   2
 

Three-way call

Definition at line 475 of file chan_zap.c.

#define TRAILER_MS   5
 

#define TRANSFER   0
 

Definition at line 10027 of file chan_zap.c.

Referenced by action_transfer(), and zap_fake_event().

#define ZT_EVENT_DTMFDOWN   0
 

Definition at line 106 of file chan_zap.c.

Referenced by zt_handle_event().

#define ZT_EVENT_DTMFUP   0
 

Definition at line 107 of file chan_zap.c.

Referenced by zt_handle_event().


Function Documentation

static int __unload_module void   )  [static]
 

Definition at line 10204 of file chan_zap.c.

References AST_PTHREADT_NULL.

10205 {
10206    int x = 0;
10207    struct zt_pvt *p, *pl;
10208 #ifdef ZAPATA_PRI
10209    int i;
10210    for(i=0;i<NUM_SPANS;i++) {
10211       if (pris[i].master != AST_PTHREADT_NULL) 
10212          pthread_cancel(pris[i].master);
10213    }
10214    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
10215 #endif
10216 #ifdef ZAPATA_R2
10217    ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
10218 #endif
10219    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
10220    ast_manager_unregister( "ZapDialOffhook" );
10221    ast_manager_unregister( "ZapHangup" );
10222    ast_manager_unregister( "ZapTransfer" );
10223    ast_manager_unregister( "ZapDNDoff" );
10224    ast_manager_unregister( "ZapDNDon" );
10225    ast_manager_unregister("ZapShowChannels");
10226    ast_channel_unregister(&zap_tech);
10227    if (!ast_mutex_lock(&iflock)) {
10228       /* Hangup all interfaces if they have an owner */
10229       p = iflist;
10230       while(p) {
10231          if (p->owner)
10232             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10233          p = p->next;
10234       }
10235       ast_mutex_unlock(&iflock);
10236    } else {
10237       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10238       return -1;
10239    }
10240    if (!ast_mutex_lock(&monlock)) {
10241       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10242          pthread_cancel(monitor_thread);
10243          pthread_kill(monitor_thread, SIGURG);
10244          pthread_join(monitor_thread, NULL);
10245       }
10246       monitor_thread = AST_PTHREADT_STOP;
10247       ast_mutex_unlock(&monlock);
10248    } else {
10249       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10250       return -1;
10251    }
10252 
10253    if (!ast_mutex_lock(&iflock)) {
10254       /* Destroy all the interfaces and free their memory */
10255       p = iflist;
10256       while(p) {
10257          /* Free any callerid */
10258          if (p->cidspill)
10259             free(p->cidspill);
10260          /* Close the zapata thingy */
10261          if (p->subs[SUB_REAL].zfd > -1)
10262             zt_close(p->subs[SUB_REAL].zfd);
10263          pl = p;
10264          p = p->next;
10265          x++;
10266          /* Free associated memory */
10267          if(pl)
10268             destroy_zt_pvt(&pl);
10269          ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10270       }
10271       iflist = NULL;
10272       ifcount = 0;
10273       ast_mutex_unlock(&iflock);
10274    } else {
10275       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10276       return -1;
10277    }
10278 #ifdef ZAPATA_PRI    
10279    for(i=0;i<NUM_SPANS;i++) {
10280       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10281          pthread_join(pris[i].master, NULL);
10282       zt_close(pris[i].fds[i]);
10283    }
10284 #endif
10285    return 0;
10286 }

static struct ast_frame* __zt_exception struct ast_channel ast  )  [static]
 

Definition at line 4266 of file chan_zap.c.

References ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_moh_stop(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, event2str(), zt_subchannel::f, zt_pvt::fake_event, ast_channel::fds, ast_frame::frametype, LOG_DEBUG, ast_frame::mallocd, ast_channel::name, ast_frame::offset, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_disable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().

Referenced by zt_exception(), and zt_read().

04267 {
04268    struct zt_pvt *p = ast->tech_pvt;
04269    int res;
04270    int usedindex=-1;
04271    int index;
04272    struct ast_frame *f;
04273 
04274 
04275    index = zt_get_index(ast, p, 1);
04276    
04277    p->subs[index].f.frametype = AST_FRAME_NULL;
04278    p->subs[index].f.datalen = 0;
04279    p->subs[index].f.samples = 0;
04280    p->subs[index].f.mallocd = 0;
04281    p->subs[index].f.offset = 0;
04282    p->subs[index].f.subclass = 0;
04283    p->subs[index].f.delivery = ast_tv(0,0);
04284    p->subs[index].f.src = "zt_exception";
04285    p->subs[index].f.data = NULL;
04286    
04287    
04288    if ((!p->owner) && (!p->radio)) {
04289       /* If nobody owns us, absorb the event appropriately, otherwise
04290          we loop indefinitely.  This occurs when, during call waiting, the
04291          other end hangs up our channel so that it no longer exists, but we
04292          have neither FLASH'd nor ONHOOK'd to signify our desire to
04293          change to the other channel. */
04294       if (p->fake_event) {
04295          res = p->fake_event;
04296          p->fake_event = 0;
04297       } else
04298          res = zt_get_event(p->subs[SUB_REAL].zfd);
04299       /* Switch to real if there is one and this isn't something really silly... */
04300       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04301          (res != ZT_EVENT_HOOKCOMPLETE)) {
04302          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04303          p->owner = p->subs[SUB_REAL].owner;
04304          if (p->owner && ast_bridged_channel(p->owner))
04305             ast_moh_stop(ast_bridged_channel(p->owner));
04306       }
04307       switch(res) {
04308       case ZT_EVENT_ONHOOK:
04309          zt_disable_ec(p);
04310          if (p->owner) {
04311             if (option_verbose > 2) 
04312                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04313             zt_ring_phone(p);
04314             p->callwaitingrepeat = 0;
04315             p->cidcwexpire = 0;
04316          } else
04317             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04318          update_conf(p);
04319          break;
04320       case ZT_EVENT_RINGOFFHOOK:
04321          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04322          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04323             p->subs[SUB_REAL].needanswer = 1;
04324             p->dialing = 0;
04325          }
04326          break;
04327       case ZT_EVENT_HOOKCOMPLETE:
04328       case ZT_EVENT_RINGERON:
04329       case ZT_EVENT_RINGEROFF:
04330          /* Do nothing */
04331          break;
04332       case ZT_EVENT_WINKFLASH:
04333          gettimeofday(&p->flashtime, NULL);
04334          if (p->owner) {
04335             if (option_verbose > 2) 
04336                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04337             if (p->owner->_state != AST_STATE_UP) {
04338                /* Answer if necessary */
04339                usedindex = zt_get_index(p->owner, p, 0);
04340                if (usedindex > -1) {
04341                   p->subs[usedindex].needanswer = 1;
04342                }
04343                ast_setstate(p->owner, AST_STATE_UP);
04344             }
04345             p->callwaitingrepeat = 0;
04346             p->cidcwexpire = 0;
04347             if (ast_bridged_channel(p->owner))
04348                ast_moh_stop(ast_bridged_channel(p->owner));
04349          } else
04350             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04351          update_conf(p);
04352          break;
04353       default:
04354          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04355       }
04356       f = &p->subs[index].f;
04357       return f;
04358    }
04359    if (!p->radio) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04360    /* If it's not us, return NULL immediately */
04361    if (ast != p->owner) {
04362       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04363       f = &p->subs[index].f;
04364       return f;
04365    }
04366    f = zt_handle_event(ast);
04367    return f;
04368 }

static int action_transfer struct mansession s,
struct message m
[static]
 

Definition at line 10094 of file chan_zap.c.

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), s, TRANSFER, and zap_fake_event().

10095 {
10096    struct zt_pvt *p = NULL;
10097    char *channel = astman_get_header(m, "ZapChannel");
10098    if (ast_strlen_zero(channel)) {
10099       astman_send_error(s, m, "No channel specified");
10100       return 0;
10101    }
10102    p = find_channel(atoi(channel));
10103    if (!p) {
10104       astman_send_error(s, m, "No such channel");
10105       return 0;
10106    }
10107    zap_fake_event(p,TRANSFER);
10108    astman_send_ack(s, m, "ZapTransfer");
10109    return 0;
10110 }

static int action_transferhangup struct mansession s,
struct message m
[static]
 

Definition at line 10112 of file chan_zap.c.

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, s, and zap_fake_event().

10113 {
10114    struct zt_pvt *p = NULL;
10115    char *channel = astman_get_header(m, "ZapChannel");
10116    if (ast_strlen_zero(channel)) {
10117       astman_send_error(s, m, "No channel specified");
10118       return 0;
10119    }
10120    p = find_channel(atoi(channel));
10121    if (!p) {
10122       astman_send_error(s, m, "No such channel");
10123       return 0;
10124    }
10125    zap_fake_event(p,HANGUP);
10126    astman_send_ack(s, m, "ZapHangup");
10127    return 0;
10128 }

static int action_zapdialoffhook struct mansession s,
struct message m
[static]
 

Definition at line 10130 of file chan_zap.c.

References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_error(), find_channel(), zt_pvt::owner, s, and zap_queue_frame().

10131 {
10132    struct zt_pvt *p = NULL;
10133    char *channel = astman_get_header(m, "ZapChannel");
10134    char *number = astman_get_header(m, "Number");
10135    int i;
10136    if (ast_strlen_zero(channel)) {
10137       astman_send_error(s, m, "No channel specified");
10138       return 0;
10139    }
10140    if (ast_strlen_zero(number)) {
10141       astman_send_error(s, m, "No number specified");
10142       return 0;
10143    }
10144    p = find_channel(atoi(channel));
10145    if (!p) {
10146       astman_send_error(s, m, "No such channel");
10147       return 0;
10148    }
10149    if (!p->owner) {
10150       astman_send_error(s, m, "Channel does not have it's owner");
10151       return 0;
10152    }
10153    for (i=0; i<strlen(number); i++) {
10154       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10155       zap_queue_frame(p, &f, NULL); 
10156    }
10157    astman_send_ack(s, m, "ZapDialOffhook");
10158    return 0;
10159 }

static int action_zapdndoff struct mansession s,
struct message m
[static]
 

Definition at line 10076 of file chan_zap.c.

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.

10077 {
10078     struct zt_pvt *p = NULL;
10079     char *channel = astman_get_header(m, "ZapChannel");
10080     if (ast_strlen_zero(channel)) {
10081         astman_send_error(s, m, "No channel specified");
10082         return 0;
10083     }
10084     p = find_channel(atoi(channel));
10085     if (!p) {
10086         astman_send_error(s, m, "No such channel");
10087         return 0;
10088     }
10089     p->dnd = 0;
10090     astman_send_ack(s, m, "DND Disabled");
10091     return 0;
10092 }

static int action_zapdndon struct mansession s,
struct message m
[static]
 

Definition at line 10058 of file chan_zap.c.

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.

10059 {
10060     struct zt_pvt *p = NULL;
10061     char *channel = astman_get_header(m, "ZapChannel");
10062     if (ast_strlen_zero(channel)) {
10063         astman_send_error(s, m, "No channel specified");
10064         return 0;
10065     }
10066     p = find_channel(atoi(channel));
10067     if (!p) {
10068         astman_send_error(s, m, "No such channel");
10069         return 0;
10070     }
10071     p->dnd = 1;
10072     astman_send_ack(s, m, "DND Enabled");
10073     return 0;
10074 }

static int action_zaprestart struct mansession s,
struct message m
[static]
 

Definition at line 9689 of file chan_zap.c.

References astman_send_ack(), astman_send_error(), s, and zap_restart().

09690 {
09691    if (zap_restart() != 0) {
09692       astman_send_error(s, m, "Failed rereading zaptel configuration");
09693       return 1;
09694    }
09695    astman_send_ack(s, m, "ZapRestart: Success");
09696    return 0;
09697 }

static int action_zapshowchannels struct mansession s,
struct message m
[static]
 

Definition at line 10161 of file chan_zap.c.

References alarm, alarm2str(), ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, s, zt_pvt::sig, and sig2str.

10162 {
10163    struct zt_pvt *tmp = NULL;
10164    char *id = astman_get_header(m, "ActionID");
10165    char idText[256] = "";
10166 
10167    astman_send_ack(s, m, "Zapata channel status will follow");
10168    if (!ast_strlen_zero(id))
10169       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10170 
10171    ast_mutex_lock(&iflock);
10172    
10173    tmp = iflist;
10174    while (tmp) {
10175       if (tmp->channel > 0) {
10176          int alarm = get_alarms(tmp);
10177          ast_cli(s->fd,
10178             "Event: ZapShowChannels\r\n"
10179             "Channel: %d\r\n"
10180             "Signalling: %s\r\n"
10181             "Context: %s\r\n"
10182             "DND: %s\r\n"
10183             "Alarm: %s\r\n"
10184             "%s"
10185             "\r\n",
10186             tmp->channel, sig2str(tmp->sig), tmp->context, 
10187             tmp->dnd ? "Enabled" : "Disabled",
10188             alarm2str(alarm), idText);
10189       } 
10190 
10191       tmp = tmp->next;
10192    }
10193 
10194    ast_mutex_unlock(&iflock);
10195    
10196    ast_cli(s->fd, 
10197       "Event: ZapShowChannelsComplete\r\n"
10198       "%s"
10199       "\r\n", 
10200       idText);
10201    return 0;
10202 }

static char* alarm2str int  alarm  )  [static]
 

Definition at line 1097 of file chan_zap.c.

References alarms, and name.

Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().

01098 {
01099    int x;
01100    for (x=0;x<sizeof(alarms) / sizeof(alarms[0]); x++) {
01101       if (alarms[x].alarm & alarm)
01102          return alarms[x].name;
01103    }
01104    return alarm ? "Unknown Alarm" : "No Alarm";
01105 }

static int alloc_sub struct zt_pvt p,
int  x
[static]
 

Definition at line 965 of file chan_zap.c.

References ast_log(), zt_subchannel::chan, zt_pvt::channel, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().

Referenced by ss_thread(), and zt_handle_event().

00966 {
00967    ZT_BUFFERINFO bi;
00968    int res;
00969    if (p->subs[x].zfd < 0) {
00970       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00971       if (p->subs[x].zfd > -1) {
00972          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00973          if (!res) {
00974             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00975             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00976             bi.numbufs = numbufs;
00977             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
00978             if (res < 0) {
00979                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
00980             }
00981          } else 
00982             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
00983          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
00984             ast_log(LOG_WARNING,"Unable to get channel number for pseudo channel on FD %d\n",p->subs[x].zfd);
00985             zt_close(p->subs[x].zfd);
00986             p->subs[x].zfd = -1;
00987             return -1;
00988          }
00989          if (option_debug)
00990             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
00991          return 0;
00992       } else
00993          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
00994       return -1;
00995    }
00996    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
00997    return -1;
00998 }

AST_MUTEX_DEFINE_STATIC monlock   ) 
 

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

AST_MUTEX_DEFINE_STATIC iflock   ) 
 

Protect the interface list (of zt_pvt's).

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

static int attempt_transfer struct zt_pvt p  )  [static]
 

Definition at line 3340 of file chan_zap.c.

References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, ast_indicate(), ast_log(), ast_moh_stop(), ast_mutex_unlock(), AST_SOFTHANGUP_DEV, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, ast_channel::name, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), and unalloc_sub().

03341 {
03342    /* In order to transfer, we need at least one of the channels to
03343       actually be in a call bridge.  We can't conference two applications
03344       together (but then, why would we want to?) */
03345    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03346       /* The three-way person we're about to transfer to could still be in MOH, so
03347          stop if now if appropriate */
03348       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03349          ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
03350       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03351          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03352       }
03353       if (p->subs[SUB_REAL].owner->cdr) {
03354          /* Move CDR from second channel to current one */
03355          p->subs[SUB_THREEWAY].owner->cdr =
03356             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03357          p->subs[SUB_REAL].owner->cdr = NULL;
03358       }
03359       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03360          /* Move CDR from second channel's bridge to current one */
03361          p->subs[SUB_THREEWAY].owner->cdr =
03362             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03363          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03364       }
03365        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03366          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03367                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03368          return -1;
03369       }
03370       /* Orphan the channel after releasing the lock */
03371       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03372       unalloc_sub(p, SUB_THREEWAY);
03373    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03374       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03375          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03376       }
03377       ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
03378       if (p->subs[SUB_THREEWAY].owner->cdr) {
03379          /* Move CDR from second channel to current one */
03380          p->subs[SUB_REAL].owner->cdr = 
03381             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03382          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03383       }
03384       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03385          /* Move CDR from second channel's bridge to current one */
03386          p->subs[SUB_REAL].owner->cdr = 
03387             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03388          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03389       }
03390       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03391          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03392                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03393          return -1;
03394       }
03395       /* Three-way is now the REAL */
03396       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03397       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03398       unalloc_sub(p, SUB_THREEWAY);
03399       /* Tell the caller not to hangup */
03400       return 1;
03401    } else {
03402       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03403                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03404       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03405       return -1;
03406    }
03407    return 0;
03408 }

static int available struct zt_pvt p,
int  channelmatch,
int  groupmatch,
int *  busy,
int *  channelmatched,
int *  groupmatched
[inline, static]
 

Definition at line 7392 of file chan_zap.c.

References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, LOG_DEBUG, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and zt_pvt::subs.

07393 {
07394    int res;
07395    ZT_PARAMS par;
07396 
07397    /* First, check group matching */
07398    if (groupmatch) {
07399       if ((p->group & groupmatch) != groupmatch)
07400          return 0;
07401       *groupmatched = 1;
07402    }
07403    /* Check to see if we have a channel match */
07404    if (channelmatch != -1) {
07405       if (p->channel != channelmatch)
07406          return 0;
07407       *channelmatched = 1;
07408    }
07409    /* We're at least busy at this point */
07410    if (busy) {
07411       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07412          *busy = 1;
07413    }
07414    /* If do not disturb, definitely not */
07415    if (p->dnd)
07416       return 0;
07417    /* If guard time, definitely not */
07418    if (p->guardtime && (time(NULL) < p->guardtime)) 
07419       return 0;
07420       
07421    /* If no owner definitely available */
07422    if (!p->owner) {
07423 #ifdef ZAPATA_PRI
07424       /* Trust PRI */
07425       if (p->pri) {
07426          if (p->resetting || p->call)
07427             return 0;
07428          else
07429             return 1;
07430       }
07431 #endif
07432 #ifdef ZAPATA_R2
07433       /* Trust R2 as well */
07434       if (p->r2) {
07435          if (p->hasr2call || p->r2blocked)
07436             return 0;
07437          else
07438             return 1;
07439       }
07440 #endif
07441       if (!p->radio)
07442       {
07443          if (!p->sig || (p->sig == SIG_FXSLS))
07444             return 1;
07445          /* Check hook state */
07446          if (p->subs[SUB_REAL].zfd > -1)
07447             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07448          else {
07449             /* Assume not off hook on CVRS */
07450             res = 0;
07451             par.rxisoffhook = 0;
07452          }
07453          if (res) {
07454             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07455          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07456             /* When "onhook" that means no battery on the line, and thus
07457               it is out of service..., if it's on a TDM card... If it's a channel
07458               bank, there is no telling... */
07459             if (par.rxbits > -1)
07460                return 1;
07461             if (par.rxisoffhook)
07462                return 1;
07463             else
07464 #ifdef ZAP_CHECK_HOOKSTATE
07465                return 0;
07466 #else
07467                return 1;
07468 #endif
07469          } else if (par.rxisoffhook) {
07470             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07471             /* Not available when the other end is off hook */
07472             return 0;
07473          }
07474       }
07475       return 1;
07476    }
07477 
07478    /* If it's not an FXO, forget about call wait */
07479    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07480       return 0;
07481 
07482    if (!p->callwaiting) {
07483       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07484       return 0;
07485    }
07486 
07487    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07488       /* If there is already a call waiting call, then we can't take a second one */
07489       return 0;
07490    }
07491    
07492    if ((p->owner->_state != AST_STATE_UP) &&
07493        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07494       /* If the current call is not up, then don't allow the call */
07495       return 0;
07496    }
07497    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07498       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07499       return 0;
07500    }
07501    /* We're cool */
07502    return 1;
07503 }

static int bump_gains struct zt_pvt p  )  [static]
 

Definition at line 1559 of file chan_zap.c.

References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, and zt_pvt::txgain.

Referenced by ss_thread().

01560 {
01561    int res;
01562 
01563    /* Bump receive gain by 5.0db */
01564    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01565    if (res) {
01566       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01567       return -1;
01568    }
01569 
01570    return 0;
01571 }

static struct zt_pvt* chandup struct zt_pvt src  )  [static]
 

Definition at line 7505 of file chan_zap.c.

References ast_log(), ast_mutex_init(), zt_pvt::destroy, destroy_zt_pvt(), iflist, malloc, zt_pvt::next, SUB_REAL, and zt_open().

07506 {
07507    struct zt_pvt *p;
07508    ZT_BUFFERINFO bi;
07509    int res;
07510    p = malloc(sizeof(struct zt_pvt));
07511    if (p) {
07512       memcpy(p, src, sizeof(struct zt_pvt));
07513       ast_mutex_init(&p->lock);
07514       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07515       /* Allocate a zapata structure */
07516       if (p->subs[SUB_REAL].zfd < 0) {
07517          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07518          destroy_zt_pvt(&p);
07519          return NULL;
07520       }
07521       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07522       if (!res) {
07523          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07524          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07525          bi.numbufs = numbufs;
07526          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07527          if (res < 0) {
07528             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07529          }
07530       } else
07531          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07532    }
07533    p->destroy = 1;
07534    p->next = iflist;
07535    iflist = p;
07536    return p;
07537 }

static int check_for_conference struct zt_pvt p  )  [static]
 

Definition at line 3482 of file chan_zap.c.

References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, and VERBOSE_PREFIX_3.

Referenced by zt_handle_event().

03483 {
03484    ZT_CONFINFO ci;
03485    /* Fine if we already have a master, etc */
03486    if (p->master || (p->confno > -1))
03487       return 0;
03488    memset(&ci, 0, sizeof(ci));
03489    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03490       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03491       return 0;
03492    }
03493    /* If we have no master and don't have a confno, then 
03494       if we're in a conference, it's probably a MeetMe room or
03495       some such, so don't let us 3-way out! */
03496    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03497       if (option_verbose > 2) 
03498          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03499       return 1;
03500    }
03501    return 0;
03502 }

static int conf_add struct zt_pvt p,
struct zt_subchannel c,
int  index,
int  slavechannel
[static]
 

Definition at line 1202 of file chan_zap.c.

References ast_log(), zt_pvt::confno, zt_subchannel::curconf, LOG_DEBUG, LOG_WARNING, and zt_subchannel::zfd.

Referenced by update_conf().

01203 {
01204    /* If the conference already exists, and we're already in it
01205       don't bother doing anything */
01206    ZT_CONFINFO zi;
01207    
01208    memset(&zi, 0, sizeof(zi));
01209    zi.chan = 0;
01210 
01211    if (slavechannel > 0) {
01212       /* If we have only one slave, do a digital mon */
01213       zi.confmode = ZT_CONF_DIGITALMON;
01214       zi.confno = slavechannel;
01215    } else {
01216       if (!index) {
01217          /* Real-side and pseudo-side both participate in conference */
01218          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01219                         ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01220       } else
01221          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01222       zi.confno = p->confno;
01223    }
01224    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01225       return 0;
01226    if (c->zfd < 0)
01227       return 0;
01228    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01229       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01230       return -1;
01231    }
01232    if (slavechannel < 1) {
01233       p->confno = zi.confno;
01234    }
01235    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01236    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01237    return 0;
01238 }

static int conf_del struct zt_pvt p,
struct zt_subchannel c,
int  index
[static]
 

Definition at line 1251 of file chan_zap.c.

References ast_log(), zt_subchannel::curconf, isourconf(), LOG_DEBUG, LOG_WARNING, and zt_subchannel::zfd.

Referenced by zt_unlink().

01252 {
01253    ZT_CONFINFO zi;
01254    if (/* Can't delete if there's no zfd */
01255       (c->zfd < 0) ||
01256       /* Don't delete from the conference if it's not our conference */
01257       !isourconf(p, c)
01258       /* Don't delete if we don't think it's conferenced at all (implied) */
01259       ) return 0;
01260    memset(&zi, 0, sizeof(zi));
01261    zi.chan = 0;
01262    zi.confno = 0;
01263    zi.confmode = 0;
01264    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01265       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01266       return -1;
01267    }
01268    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01269    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01270    return 0;
01271 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 11254 of file chan_zap.c.

11255 {
11256    return (char *) desc;
11257 }

static int destroy_channel struct zt_pvt prev,
struct zt_pvt cur,
int  now
[static]
 

Definition at line 2173 of file chan_zap.c.

References zt_subchannel::owner, zt_pvt::owner, and zt_pvt::subs.

Referenced by zap_destroy_channel(), zap_restart(), and zt_hangup().

02174 {
02175    int owned = 0;
02176    int i = 0;
02177 
02178    if (!now) {
02179       if (cur->owner) {
02180          owned = 1;
02181       }
02182 
02183       for (i = 0; i < 3; i++) {
02184          if (cur->subs[i].owner) {
02185             owned = 1;
02186          }
02187       }
02188       if (!owned) {
02189          if (prev) {
02190             prev->next = cur->next;
02191             if (prev->next)
02192                prev->next->prev = prev;
02193             else
02194                ifend = prev;
02195          } else {
02196             iflist = cur->next;
02197             if (iflist)
02198                iflist->prev = NULL;
02199             else
02200                ifend = NULL;
02201          }
02202          if (cur->subs[SUB_REAL].zfd > -1) {
02203             zt_close(cur->subs[SUB_REAL].zfd);
02204          }
02205          destroy_zt_pvt(&cur);
02206       }
02207    } else {
02208       if (prev) {
02209          prev->next = cur->next;
02210          if (prev->next)
02211             prev->next->prev = prev;
02212          else
02213             ifend = prev;
02214       } else {
02215          iflist = cur->next;
02216          if (iflist)
02217             iflist->prev = NULL;
02218          else
02219             ifend = NULL;
02220       }
02221       if (cur->subs[SUB_REAL].zfd > -1) {
02222          zt_close(cur->subs[SUB_REAL].zfd);
02223       }
02224       destroy_zt_pvt(&cur);
02225    }
02226    return 0;
02227 }

static void destroy_zt_pvt struct zt_pvt **  pvt  )  [static]
 

Definition at line 2160 of file chan_zap.c.

References ast_mutex_destroy(), free, zt_pvt::lock, zt_pvt::next, and zt_pvt::prev.

Referenced by chandup(), and mkintf().

02161 {
02162    struct zt_pvt *p = *pvt;
02163    /* Remove channel from the list */
02164    if(p->prev)
02165       p->prev->next = p->next;
02166    if(p->next)
02167       p->next->prev = p->prev;
02168    ast_mutex_destroy(&p->lock);
02169    free(p);
02170    *pvt = NULL;
02171 }

static void disable_dtmf_detect struct zt_pvt p  )  [static]
 

Definition at line 2965 of file chan_zap.c.

References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, and zt_pvt::subs.

Referenced by zt_bridge().

02966 {
02967 #ifdef ZT_TONEDETECT
02968    int val;
02969 #endif
02970 
02971    p->ignoredtmf = 1;
02972 
02973 #ifdef ZT_TONEDETECT
02974    val = 0;
02975    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
02976 #endif      
02977    if (!p->hardwaredtmf && p->dsp) {
02978       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
02979       ast_dsp_set_features(p->dsp, p->dsp_features);
02980    }
02981 }

static void* do_monitor void *  data  )  [static]
 

Definition at line 6542 of file chan_zap.c.

References ast_log(), ast_mutex_lock(), last, LOG_DEBUG, and LOG_ERROR.

06543 {
06544    int count, res, res2, spoint, pollres=0;
06545    struct zt_pvt *i;
06546    struct zt_pvt *last = NULL;
06547    time_t thispass = 0, lastpass = 0;
06548    int found;
06549    char buf[1024];
06550    struct pollfd *pfds=NULL;
06551    int lastalloc = -1;
06552    /* This thread monitors all the frame relay interfaces which are not yet in use
06553       (and thus do not have a separate thread) indefinitely */
06554    /* From here on out, we die whenever asked */
06555 #if 0
06556    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06557       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06558       return NULL;
06559    }
06560    ast_log(LOG_DEBUG, "Monitor starting...\n");
06561 #endif
06562    for(;;) {
06563       /* Lock the interface list */
06564       if (ast_mutex_lock(&iflock)) {
06565          ast_log(LOG_ERROR, "Unable to grab interface lock\n");
06566          return NULL;
06567       }
06568       if (!pfds || (lastalloc != ifcount)) {
06569          if (pfds)
06570             free(pfds);
06571          if (ifcount) {
06572             pfds = malloc(ifcount * sizeof(struct pollfd));
06573             if (!pfds) {
06574                ast_log(LOG_WARNING, "Critical memory error.  Zap dies.\n");
06575                ast_mutex_unlock(&iflock);
06576                return NULL;
06577             }
06578          }
06579          lastalloc = ifcount;
06580       }
06581       /* Build the stuff we're going to poll on, that is the socket of every
06582          zt_pvt that does not have an associated owner channel */
06583       count = 0;
06584       i = iflist;
06585       while(i) {
06586          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06587             if (!i->owner && !i->subs[SUB_REAL].owner) {
06588                /* This needs to be watched, as it lacks an owner */
06589                pfds[count].fd = i->subs[SUB_REAL].zfd;
06590                pfds[count].events = POLLPRI;
06591                pfds[count].revents = 0;
06592                /* Message waiting or r2 channels also get watched for reading */
06593 #ifdef ZAPATA_R2
06594                if (i->cidspill || i->r2)
06595 #else             
06596                if (i->cidspill)
06597 #endif               
06598                   pfds[count].events |= POLLIN;
06599                count++;
06600             }
06601          }
06602          i = i->next;
06603       }
06604       /* Okay, now that we know what to do, release the interface lock */
06605       ast_mutex_unlock(&iflock);
06606       
06607       pthread_testcancel();
06608       /* Wait at least a second for something to happen */
06609       res = poll(pfds, count, 1000);
06610       pthread_testcancel();
06611       /* Okay, poll has finished.  Let's see what happened.  */
06612       if (res < 0) {
06613          if ((errno != EAGAIN) && (errno != EINTR))
06614             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06615          continue;
06616       }
06617       /* Alright, lock the interface list again, and let's look and see what has
06618          happened */
06619       if (ast_mutex_lock(&iflock)) {
06620          ast_log(LOG_WARNING, "Unable to lock the interface list\n");
06621          continue;
06622       }
06623       found = 0;
06624       spoint = 0;
06625       lastpass = thispass;
06626       thispass = time(NULL);
06627       i = iflist;
06628       while(i) {
06629          if (thispass != lastpass) {
06630             if (!found && ((i == last) || ((i == iflist) && !last))) {
06631                last = i;
06632                if (last) {
06633 #if 0
06634                   printf("Checking channel %d\n", last->channel);
06635 #endif                  
06636                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06637                      (last->sig & __ZT_SIG_FXO)) {
06638 #if 0
06639                      printf("Channel %d has mailbox %s\n", last->channel, last->mailbox);
06640 #endif                     
06641                      res = ast_app_has_voicemail(last->mailbox, NULL);
06642                      if (last->msgstate != res) {
06643                         int x;
06644                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06645                         x = ZT_FLUSH_BOTH;
06646                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06647                         if (res2)
06648                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06649                         last->cidspill = malloc(MAX_CALLERID_SIZE);
06650                         if (last->cidspill) {
06651                            /* Turn on on hook transfer for 4 seconds */
06652                            x = 4000;
06653                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06654                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06655                            last->cidpos = 0;
06656 #if 0
06657                            printf("Made %d bytes of message waiting for %d\n", last->cidlen, res);
06658 #endif                           
06659                            last->msgstate = res;
06660                            last->onhooktime = thispass;
06661                         }
06662                         found ++;
06663                      }
06664                   }
06665                   last = last->next;
06666                }
06667             }
06668          }
06669          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06670             if (i->radio && !i->owner)
06671             {
06672                res = zt_get_event(i->subs[SUB_REAL].zfd);
06673                if (res)
06674                {
06675                   if (option_debug)
06676                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06677                   /* Don't hold iflock while handling init events */
06678                   ast_mutex_unlock(&iflock);
06679                   handle_init_event(i, res);
06680                   ast_mutex_lock(&iflock);   
06681                }
06682                i = i->next;
06683                continue;
06684             }              
06685             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06686             if (pollres & POLLIN) {
06687                if (i->owner || i->subs[SUB_REAL].owner) {
06688 #ifdef ZAPATA_PRI
06689                   if (!i->pri)
06690 #endif                  
06691                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06692                   i = i->next;
06693                   continue;
06694                }
06695 #ifdef ZAPATA_R2
06696                if (i->r2) {
06697                   /* If it's R2 signalled, we always have to check for events */
06698                   mfcr2_event_t *e;
06699                   e = mfcr2_check_event(i->r2);
06700                   if (e)
06701                      handle_init_r2_event(i, e);
06702                   else {
06703                      e = mfcr2_schedule_run(i->r2);
06704                      if (e)
06705                         handle_init_r2_event(i, e);
06706                   }
06707                   i = i->next;
06708                   continue;
06709                }
06710 #endif
06711                if (!i->cidspill) {
06712                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06713                   i = i->next;
06714                   continue;
06715                }
06716                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06717                if (res > 0) {
06718                   /* We read some number of bytes.  Write an equal amount of data */
06719                   if (res > i->cidlen - i->cidpos) 
06720                      res = i->cidlen - i->cidpos;
06721                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06722                   if (res2 > 0) {
06723                      i->cidpos += res2;
06724                      if (i->cidpos >= i->cidlen) {
06725                         free(i->cidspill);
06726                         i->cidspill = 0;
06727                         i->cidpos = 0;
06728                         i->cidlen = 0;
06729                      }
06730                   } else {
06731                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06732                      i->msgstate = -1;
06733                   }
06734                } else {
06735                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06736                }
06737                if (option_debug)
06738                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06739                /* Don't hold iflock while handling init events -- race with chlock */
06740                ast_mutex_unlock(&iflock);
06741                handle_init_event(i, res);
06742                ast_mutex_lock(&iflock);   
06743             }
06744 #ifdef ZAPATA_R2
06745             if ((pollres & POLLPRI) || (i->r2 && !i->sigchecked)) 
06746 #else          
06747             if (pollres & POLLPRI) 
06748 #endif            
06749             {
06750                if (i->owner || i->subs[SUB_REAL].owner) {
06751 #ifdef ZAPATA_PRI
06752                   if (!i->pri)
06753 #endif                  
06754                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
06755                   i = i->next;
06756                   continue;
06757                }
06758                res = zt_get_event(i->subs[SUB_REAL].zfd);
06759                if (option_debug)
06760                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06761                /* Don't hold iflock while handling init events */
06762                ast_mutex_unlock(&iflock);
06763                handle_init_event(i, res);
06764                ast_mutex_lock(&iflock);   
06765             }
06766          }
06767          i=i->next;
06768       }
06769       ast_mutex_unlock(&iflock);
06770    }
06771    /* Never reached */
06772    return NULL;
06773    
06774 }

static void enable_dtmf_detect struct zt_pvt p  )  [static]
 

Definition at line 2983 of file chan_zap.c.

References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, and zt_pvt::subs.

02984 {
02985 #ifdef ZT_TONEDETECT
02986    int val;
02987 #endif
02988 
02989    if (p->channel == CHAN_PSEUDO)
02990       return;
02991 
02992    p->ignoredtmf = 0;
02993 
02994 #ifdef ZT_TONEDETECT
02995    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
02996    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
02997 #endif      
02998    if (!p->hardwaredtmf && p->dsp) {
02999       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03000       ast_dsp_set_features(p->dsp, p->dsp_features);
03001    }
03002 }

static char* event2str int  event  )  [static]
 

Definition at line 1107 of file chan_zap.c.

References events.

Referenced by __zt_exception(), ss_thread(), and zt_handle_event().

01108 {
01109         static char buf[256];
01110         if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01111                 return events[event];
01112         sprintf(buf, "Event %d", event); /* safe */
01113         return buf;
01114 }

static void fill_rxgain struct zt_gains *  g,
float  gain,
int  law
[static]
 

Definition at line 1484 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_rxgain().

01485 {
01486    int j;
01487    int k;
01488    float linear_gain = pow(10.0, gain / 20.0);
01489 
01490    switch (law) {
01491    case ZT_LAW_ALAW:
01492       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01493          if (gain) {
01494             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01495             if (k > 32767) k = 32767;
01496             if (k < -32767) k = -32767;
01497             g->rxgain[j] = AST_LIN2A(k);
01498          } else {
01499             g->rxgain[j] = j;
01500          }
01501       }
01502       break;
01503    case ZT_LAW_MULAW:
01504       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01505          if (gain) {
01506             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01507             if (k > 32767) k = 32767;
01508             if (k < -32767) k = -32767;
01509             g->rxgain[j] = AST_LIN2MU(k);
01510          } else {
01511             g->rxgain[j] = j;
01512          }
01513       }
01514       break;
01515    }
01516 }

static void fill_txgain struct zt_gains *  g,
float  gain,
int  law
[static]
 

Definition at line 1450 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_txgain().

01451 {
01452    int j;
01453    int k;
01454    float linear_gain = pow(10.0, gain / 20.0);
01455 
01456    switch (law) {
01457    case ZT_LAW_ALAW:
01458       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01459          if (gain) {
01460             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01461             if (k > 32767) k = 32767;
01462             if (k < -32767) k = -32767;
01463             g->txgain[j] = AST_LIN2A(k);
01464          } else {
01465             g->txgain[j] = j;
01466          }
01467       }
01468       break;
01469    case ZT_LAW_MULAW:
01470       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01471          if (gain) {
01472             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01473             if (k > 32767) k = 32767;
01474             if (k < -32767) k = -32767;
01475             g->txgain[j] = AST_LIN2MU(k);
01476          } else {
01477             g->txgain[j] = j;
01478          }
01479       }
01480       break;
01481    }
01482 }

static struct zt_pvt* find_channel int  channel  )  [static]
 

Definition at line 10046 of file chan_zap.c.

References zt_pvt::channel, iflist, and zt_pvt::next.

10047 {
10048    struct zt_pvt *p = iflist;
10049    while(p) {
10050       if (p->channel == channel) {
10051          break;
10052       }
10053       p = p->next;
10054    }
10055    return p;
10056 }

static int get_alarms struct zt_pvt p  )  [static]
 

Definition at line 3504 of file chan_zap.c.

References ast_log(), zt_pvt::channel, zt_pvt::span, SUB_REAL, and zt_pvt::subs.

Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().

03505 {
03506    int res;
03507    ZT_SPANINFO zi;
03508    memset(&zi, 0, sizeof(zi));
03509    zi.spanno = p->span;
03510    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03511    if (res < 0) {
03512       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03513       return 0;
03514    }
03515    return zi.alarms;
03516 }

static int handle_init_event struct zt_pvt i,
int  event
[static]
 

Definition at line 6348 of file chan_zap.c.

References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().

06349 {
06350    int res;
06351    pthread_t threadid;
06352    pthread_attr_t attr;
06353    struct ast_channel *chan;
06354    pthread_attr_init(&attr);
06355    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06356    /* Handle an event on a given channel for the monitor thread. */
06357    switch(event) {
06358    case ZT_EVENT_NONE:
06359    case ZT_EVENT_BITSCHANGED:
06360       if (i->radio) break;
06361 #ifdef ZAPATA_R2
06362       if (i->r2) {
06363          mfcr2_event_t *e;
06364          e = r2_get_event_bits(i);
06365          i->sigchecked = 1;
06366          if (e)
06367             handle_init_r2_event(i, e);
06368       }
06369 #endif      
06370       break;
06371    case ZT_EVENT_WINKFLASH:
06372    case ZT_EVENT_RINGOFFHOOK:
06373       if (i->inalarm) break;
06374       if (i->radio) break;
06375       /* Got a ring/answer.  What kind of channel are we? */
06376       switch(i->sig) {
06377       case SIG_FXOLS:
06378       case SIG_FXOGS:
06379       case SIG_FXOKS:
06380               zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06381          if (i->cidspill) {
06382             /* Cancel VMWI spill */
06383             free(i->cidspill);
06384             i->cidspill = NULL;
06385          }
06386          if (i->immediate) {
06387             zt_enable_ec(i);
06388             /* The channel is immediately up.  Start right away */
06389             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06390             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06391             if (!chan) {
06392                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06393                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06394                if (res < 0)
06395                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06396             }
06397          } else {
06398             /* Check for callerid, digits, etc */
06399             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06400             if (chan) {
06401                if (has_voicemail(i))
06402                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06403                else
06404                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06405                if (res < 0) 
06406                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
06407                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06408                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06409                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06410                   if (res < 0)
06411                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06412                   ast_hangup(chan);
06413                }
06414             } else
06415                ast_log(LOG_WARNING, "Unable to create channel\n");
06416 #if 0
06417             printf("Created thread %ld detached in switch\n", threadid);
06418 #endif
06419          }
06420          break;
06421       case SIG_FXSLS:
06422       case SIG_FXSGS:
06423       case SIG_FXSKS:
06424             i->ringt = i->ringt_base;
06425             /* Fall through */
06426       case SIG_EMWINK:
06427       case SIG_FEATD:
06428       case SIG_FEATDMF:
06429       case SIG_E911:
06430       case SIG_FEATB:
06431       case SIG_EM:
06432       case SIG_EM_E1:
06433       case SIG_SFWINK:
06434       case SIG_SF_FEATD:
06435       case SIG_SF_FEATDMF:
06436       case SIG_SF_FEATB:
06437       case SIG_SF:
06438             /* Check for callerid, digits, etc */
06439             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06440             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06441                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06442                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06443                if (res < 0)
06444                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06445                ast_hangup(chan);
06446             } else if (!chan) {
06447                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06448             }
06449 #if 0
06450             printf("Created thread %ld detached in switch(2)\n", threadid);
06451 #endif
06452             break;
06453       default:
06454          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06455          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06456          if (res < 0)
06457                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06458          return -1;
06459       }
06460       break;
06461    case ZT_EVENT_NOALARM:
06462       i->inalarm = 0;
06463       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06464       break;
06465    case ZT_EVENT_ALARM:
06466       i->inalarm = 1;
06467       res = get_alarms(i);
06468       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06469       /* fall thru intentionally */
06470    case ZT_EVENT_ONHOOK:
06471       if (i->radio) break;
06472       /* Back on hook.  Hang up. */
06473       switch(i->sig) {
06474       case SIG_FXOLS:
06475       case SIG_FXOGS:
06476       case SIG_FEATD:
06477       case SIG_FEATDMF:
06478       case SIG_E911:
06479       case SIG_FEATB:
06480       case SIG_EM:
06481       case SIG_EM_E1:
06482       case SIG_EMWINK:
06483       case SIG_SF_FEATD:
06484       case SIG_SF_FEATDMF:
06485       case SIG_SF_FEATB:
06486       case SIG_SF:
06487       case SIG_SFWINK:
06488       case SIG_FXSLS:
06489       case SIG_FXSGS:
06490       case SIG_FXSKS:
06491       case SIG_GR303FXSKS:
06492          zt_disable_ec(i);
06493          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06494          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06495          break;
06496       case SIG_GR303FXOKS:
06497       case SIG_FXOKS:
06498          zt_disable_ec(i);
06499          /* Diddle the battery for the zhone */
06500 #ifdef ZHONE_HACK
06501          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06502          usleep(1);
06503 #endif         
06504          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06505          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06506          break;
06507       case SIG_PRI:
06508          zt_disable_ec(i);
06509          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06510          break;
06511       default:
06512          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06513          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06514          return -1;
06515       }
06516       break;
06517    case ZT_EVENT_POLARITY:
06518       switch(i->sig) {
06519       case SIG_FXSLS:
06520       case SIG_FXSKS:
06521       case SIG_FXSGS:
06522          if (i->cid_start == CID_START_POLARITY) {
06523             i->polarity = POLARITY_REV;
06524             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06525                    "CID detection on channel %d\n",
06526                    i->channel);
06527             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06528             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06529                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06530             }
06531          }
06532          break;
06533       default:
06534          ast_log(LOG_WARNING, "handle_init_event detected "
06535             "polarity reversal on non-FXO (SIG_FXS) "
06536             "interface %d\n", i->channel);
06537       }
06538    }
06539    return 0;
06540 }

static int handle_zap_show_cadences int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 9904 of file chan_zap.c.

References COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().

09905 {
09906    int i, j;
09907    for (i=0;i<num_cadence;i++) {
09908       char output[1024];
09909       char tmp[16], tmp2[64];
09910       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
09911       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
09912 
09913       for (j=0;j<16;j++) {
09914          if (cadences[i].ringcadence[j] == 0)
09915             break;
09916          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
09917          if (cidrings[i] * 2 - 1 == j)
09918             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
09919          else
09920             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
09921          if (j != 0)
09922             strncat(output, ",", sizeof(output) - strlen(output) - 1);
09923          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
09924       }
09925       ast_cli(fd,"%s\n",output);
09926    }
09927    return 0;
09928 }

static int has_voicemail struct zt_pvt p  )  [static]
 

Definition at line 1679 of file chan_zap.c.

References ast_app_has_voicemail(), and zt_pvt::mailbox.

01680 {
01681 
01682    return ast_app_has_voicemail(p->mailbox, NULL);
01683 }

static int isourconf struct zt_pvt p,
struct zt_subchannel c
[static]
 

Definition at line 1240 of file chan_zap.c.

References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.

Referenced by conf_del().

01241 {
01242    /* If they're listening to our channel, they're ours */  
01243    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01244       return 1;
01245    /* If they're a talker on our (allocated) conference, they're ours */
01246    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01247       return 1;
01248    return 0;
01249 }

static int isslavenative struct zt_pvt p,
struct zt_pvt **  out
[static]
 

Definition at line 1273 of file chan_zap.c.

References zt_subchannel::inthreeway, zt_pvt::subs, and zt_subchannel::zfd.

Referenced by update_conf().

01274 {
01275    int x;
01276    int useslavenative;
01277    struct zt_pvt *slave = NULL;
01278    /* Start out optimistic */
01279    useslavenative = 1;
01280    /* Update conference state in a stateless fashion */
01281    for (x=0;x<3;x++) {
01282       /* Any three-way calling makes slave native mode *definitely* out
01283          of the question */
01284       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01285          useslavenative = 0;
01286    }
01287    /* If we don't have any 3-way calls, check to see if we have
01288       precisely one slave */
01289    if (useslavenative) {
01290       for (x=0;x<MAX_SLAVES;x++) {
01291          if (p->slaves[x]) {
01292             if (slave) {
01293                /* Whoops already have a slave!  No 
01294                   slave native and stop right away */
01295                slave = NULL;
01296                useslavenative = 0;
01297                break;
01298             } else {
01299                /* We have one slave so far */
01300                slave = p->slaves[x];
01301             }
01302          }
01303       }
01304    }
01305    /* If no slave, slave native definitely out */
01306    if (!slave)
01307       useslavenative = 0;
01308    else if (slave->law != p->law) {
01309       useslavenative = 0;
01310       slave = NULL;
01311    }
01312    if (out)
01313       *out = slave;
01314    return useslavenative;
01315 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 11259 of file chan_zap.c.

References ASTERISK_GPL_KEY.

11260 {
11261    return ASTERISK_GPL_KEY;
11262 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 11090 of file chan_zap.c.

References ast_mutex_init(), AST_PTHREADT_NULL, and lock.

11091 {
11092    int res;
11093 
11094 #ifdef ZAPATA_PRI
11095    int y,i;
11096    memset(pris, 0, sizeof(pris));
11097    for (y=0;y<NUM_SPANS;y++) {
11098       ast_mutex_init(&pris[y].lock);
11099       pris[y].offset = -1;
11100       pris[y].master = AST_PTHREADT_NULL;
11101       for (i=0;i<NUM_DCHANS;i++)
11102          pris[y].fds[i] = -1;
11103    }
11104    pri_set_error(zt_pri_error);
11105    pri_set_message(zt_pri_message);
11106 #endif
11107    res = setup_zap(0);
11108    /* Make sure we can register our Zap channel type */
11109    if(res) {
11110      return -1;
11111    }
11112    if (ast_channel_register(&zap_tech)) {
11113       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
11114       __unload_module();
11115       return -1;
11116    }
11117 #ifdef ZAPATA_PRI
11118    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
11119 #endif   
11120 #ifdef ZAPATA_R2
11121    ast_cli_register_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
11122 #endif   
11123    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
11124    
11125    memset(round_robin, 0, sizeof(round_robin));
11126    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11127    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11128    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11129    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11130    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11131    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11132 
11133    return res;
11134 }

static struct zt_pvt* mkintf int  channel,
int  signalling,
int  radio,
struct zt_pri *  pri,
int  reloading
[static]
 

Definition at line 6931 of file chan_zap.c.

References ast_log(), ast_mutex_init(), CHAN_PSEUDO, zt_pvt::channel, destroy_zt_pvt(), iflist, zt_pvt::lock, LOG_ERROR, malloc, zt_pvt::next, SUB_REAL, channel::subs, zt_pvt::subs, zt_subchannel::zfd, and zt_open().

06932 {
06933    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
06934    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
06935    char fn[80];
06936 #if 1
06937    struct zt_bufferinfo bi;
06938 #endif
06939    struct zt_spaninfo si;
06940    int res;
06941    int span=0;
06942    int here = 0;
06943    int x;
06944    struct zt_pvt **wlist;
06945    struct zt_pvt **wend;
06946    ZT_PARAMS p;
06947 
06948    wlist = &iflist;
06949    wend = &ifend;
06950 
06951 #ifdef ZAPATA_PRI
06952    if (pri) {
06953       wlist = &pri->crvs;
06954       wend = &pri->crvend;
06955    }
06956 #endif
06957 
06958    tmp2 = *wlist;
06959    prev = NULL;
06960 
06961    while (tmp2) {
06962       if (!tmp2->destroy) {
06963          if (tmp2->channel == channel) {
06964             tmp = tmp2;
06965             here = 1;
06966             break;
06967          }
06968          if (tmp2->channel > channel) {
06969             break;
06970          }
06971       }
06972       prev = tmp2;
06973       tmp2 = tmp2->next;
06974    }
06975 
06976    if (!here && !reloading) {
06977       tmp = (struct zt_pvt*)malloc(sizeof(struct zt_pvt));
06978       if (!tmp) {
06979          ast_log(LOG_ERROR, "MALLOC FAILED\n");
06980          destroy_zt_pvt(&tmp);
06981          return NULL;
06982       }
06983       memset(tmp, 0, sizeof(struct zt_pvt));
06984       ast_mutex_init(&tmp->lock);
06985       ifcount++;
06986       for (x=0;x<3;x++)
06987          tmp->subs[x].zfd = -1;
06988       tmp->channel = channel;
06989    }
06990 
06991    if (tmp) {
06992       if (!here) {
06993          if ((channel != CHAN_PSEUDO) && !pri) {
06994             snprintf(fn, sizeof(fn), "%d", channel);
06995             /* Open non-blocking */
06996             if (!here)
06997                tmp->subs[SUB_REAL].zfd = zt_open(fn);
06998             /* Allocate a zapata structure */
06999             if (tmp->subs[SUB_REAL].zfd < 0) {
07000                ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
07001                destroy_zt_pvt(&tmp);
07002                return NULL;
07003             }
07004             memset(&p, 0, sizeof(p));
07005             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07006             if (res < 0) {
07007                ast_log(LOG_ERROR, "Unable to get parameters\n");
07008                destroy_zt_pvt(&tmp);
07009                return NULL;
07010             }
07011             if (p.sigtype != (signalling & 0x3ffff)) {
07012                ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(signalling), sig2str(p.sigtype));
07013                destroy_zt_pvt(&tmp);
07014                return tmp;
07015             }
07016             tmp->law = p.curlaw;
07017             tmp->span = p.spanno;
07018             span = p.spanno - 1;
07019          } else {
07020             if (channel == CHAN_PSEUDO)
07021                signalling = 0;
07022             else if ((signalling != SIG_FXOKS) && (signalling != SIG_FXSKS)) {
07023                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07024                return NULL;
07025             }
07026          }
07027 #ifdef ZAPATA_PRI
07028          if ((signalling == SIG_PRI) || (signalling == SIG_GR303FXOKS) || (signalling == SIG_GR303FXSKS)) {
07029             int offset;
07030             int myswitchtype;
07031             int matchesdchan;
07032             int x,y;
07033             offset = 0;
07034             if ((signalling == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07035                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07036                destroy_zt_pvt(&tmp);
07037                return NULL;
07038             }
07039             if (span >= NUM_SPANS) {
07040                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07041                destroy_zt_pvt(&tmp);
07042                return NULL;
07043             } else {
07044                si.spanno = 0;
07045                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07046                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07047                   destroy_zt_pvt(&tmp);
07048                   return NULL;
07049                }
07050                /* Store the logical span first based upon the real span */
07051                tmp->logicalspan = pris[span].prilogicalspan;
07052                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07053                if (span < 0) {
07054                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07055                   destroy_zt_pvt(&tmp);
07056                   return NULL;
07057                }
07058                if (signalling == SIG_PRI)
07059                   myswitchtype = switchtype;
07060                else
07061                   myswitchtype = PRI_SWITCH_GR303_TMC;
07062                /* Make sure this isn't a d-channel */
07063                matchesdchan=0;
07064                for (x=0;x<NUM_SPANS;x++) {
07065                   for (y=0;y<NUM_DCHANS;y++) {
07066                      if (pris[x].dchannels[y] == tmp->channel) {
07067                         matchesdchan = 1;
07068                         break;
07069                      }
07070                   }
07071                }
07072                offset = p.chanpos;
07073                if (!matchesdchan) {
07074                   if (pris[span].nodetype && (pris[span].nodetype != pritype)) {
07075                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07076                      destroy_zt_pvt(&tmp);
07077                      return NULL;
07078                   }
07079                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07080                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07081                      destroy_zt_pvt(&tmp);
07082                      return NULL;
07083                   }
07084                   if ((pris[span].dialplan) && (pris[span].dialplan != dialplan)) {
07085                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07086                      destroy_zt_pvt(&tmp);
07087                      return NULL;
07088                   }
07089                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, idledial)) {
07090                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, idledial);
07091                      destroy_zt_pvt(&tmp);
07092                      return NULL;
07093                   }
07094                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, idleext)) {
07095                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, idleext);
07096                      destroy_zt_pvt(&tmp);
07097                      return NULL;
07098                   }
07099                   if (pris[span].minunused && (pris[span].minunused != minunused)) {
07100                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, minunused);
07101                      destroy_zt_pvt(&tmp);
07102                      return NULL;
07103                   }
07104                   if (pris[span].minidle && (pris[span].minidle != minidle)) {
07105                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, minidle);
07106                      destroy_zt_pvt(&tmp);
07107                      return NULL;
07108                   }
07109                   if (pris[span].numchans >= MAX_CHANNELS) {
07110                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07111                         pris[span].trunkgroup);
07112                      destroy_zt_pvt(&tmp);
07113                      return NULL;
07114                   }
07115                   pris[span].nodetype = pritype;
07116                   pris[span].switchtype = myswitchtype;
07117                   pris[span].nsf = nsf;
07118                   pris[span].dialplan = dialplan;
07119                   pris[span].localdialplan = localdialplan;
07120                   pris[span].pvts[pris[span].numchans++] = tmp;
07121                   pris[span].minunused = minunused;
07122                   pris[span].minidle = minidle;
07123                   pris[span].overlapdial = overlapdial;
07124                   pris[span].facilityenable = facilityenable;
07125                   ast_copy_string(pris[span].idledial, idledial, sizeof(pris[span].idledial));
07126                   ast_copy_string(pris[span].idleext, idleext, sizeof(pris[span].idleext));
07127                   ast_copy_string(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix));
07128                   ast_copy_string(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix));
07129                   ast_copy_string(pris[span].localprefix, localprefix, sizeof(pris[span].localprefix));
07130                   ast_copy_string(pris[span].privateprefix, privateprefix, sizeof(pris[span].privateprefix));
07131                   ast_copy_string(pris[span].unknownprefix, unknownprefix, sizeof(pris[span].unknownprefix));
07132                   pris[span].resetinterval = resetinterval;
07133                   
07134                   tmp->pri = &pris[span];
07135                   tmp->prioffset = offset;
07136                   tmp->call = NULL;
07137                } else {
07138                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07139                   destroy_zt_pvt(&tmp);
07140                   return NULL;
07141                }
07142             }
07143          } else {
07144             tmp->prioffset = 0;
07145          }
07146 #endif
07147 #ifdef ZAPATA_R2
07148          if (signalling == SIG_R2) {
07149             if (r2prot < 0) {
07150                ast_log(LOG_WARNING, "R2 Country not specified for channel %d -- Assuming China\n", tmp->channel);
07151                tmp->r2prot = MFCR2_PROT_CHINA;
07152             } else
07153                tmp->r2prot = r2prot;
07154             tmp->r2 = mfcr2_new(tmp->subs[SUB_REAL].zfd, tmp->r2prot, 1);
07155             if (!tmp->r2) {
07156                ast_log(LOG_WARNING, "Unable to create r2 call :(\n");
07157                zt_close(tmp->subs[SUB_REAL].zfd);
07158                destroy_zt_pvt(&tmp);
07159                return NULL;
07160             }
07161          } else {
07162             if (tmp->r2) 
07163                mfcr2_free(tmp->r2);
07164             tmp->r2 = NULL;
07165          }
07166 #endif
07167       } else {
07168          signalling = tmp->sig;
07169          radio = tmp->radio;
07170          memset(&p, 0, sizeof(p));
07171          if (tmp->subs[SUB_REAL].zfd > -1)
07172             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07173       }
07174       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07175       if ((signalling == SIG_FXSKS) || (signalling == SIG_FXSLS) ||
07176           (signalling == SIG_EM) || (signalling == SIG_EM_E1) ||  (signalling == SIG_EMWINK) ||
07177          (signalling == SIG_FEATD) || (signalling == SIG_FEATDMF) || (signalling == SIG_FEATDMF_TA) ||
07178            (signalling == SIG_FEATB) || (signalling == SIG_E911) ||
07179           (signalling == SIG_SF) || (signalling == SIG_SFWINK) ||
07180          (signalling == SIG_SF_FEATD) || (signalling == SIG_SF_FEATDMF) ||
07181            (signalling == SIG_SF_FEATB)) {
07182          p.starttime = 250;
07183       }
07184       if (radio) {
07185          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07186          p.channo = channel;
07187          p.rxwinktime = 1;
07188          p.rxflashtime = 1;
07189          p.starttime = 1;
07190          p.debouncetime = 5;
07191       }
07192       if (!radio) {
07193          p.channo = channel;
07194          /* Override timing settings based on config file */
07195          if (cur_prewink >= 0)
07196             p.prewinktime = cur_prewink;
07197          if (cur_preflash >= 0)
07198             p.preflashtime = cur_preflash;
07199          if (cur_wink >= 0)
07200             p.winktime = cur_wink;
07201          if (cur_flash >= 0)
07202             p.flashtime = cur_flash;
07203          if (cur_start >= 0)
07204             p.starttime = cur_start;
07205          if (cur_rxwink >= 0)
07206             p.rxwinktime = cur_rxwink;
07207          if (cur_rxflash >= 0)
07208             p.rxflashtime = cur_rxflash;
07209          if (cur_debounce >= 0)
07210             p.debouncetime = cur_debounce;
07211       }
07212       
07213       /* dont set parms on a pseudo-channel (or CRV) */
07214       if (tmp->subs[SUB_REAL].zfd >= 0)
07215       {
07216          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07217          if (res < 0) {
07218             ast_log(LOG_ERROR, "Unable to set parameters\n");
07219             destroy_zt_pvt(&tmp);
07220             return NULL;
07221          }
07222       }
07223 #if 1
07224       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07225          memset(&bi, 0, sizeof(bi));
07226          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07227          if (!res) {
07228             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07229             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07230             bi.numbufs = numbufs;
07231             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07232             if (res < 0) {
07233                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07234             }
07235          } else
07236             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07237       }
07238 #endif
07239       tmp->immediate = immediate;
07240       tmp->transfertobusy = transfertobusy;
07241       tmp->sig = signalling;
07242       tmp->radio = radio;
07243       tmp->ringt_base = ringt_base;
07244       tmp->firstradio = 0;
07245       if ((signalling == SIG_FXOKS) || (signalling == SIG_FXOLS) || (signalling == SIG_FXOGS))
07246          tmp->permcallwaiting = callwaiting;
07247       else
07248          tmp->permcallwaiting = 0;
07249       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07250       tmp->destroy = 0;
07251       tmp->drings = drings;
07252       tmp->usedistinctiveringdetection = usedistinctiveringdetection;
07253       tmp->callwaitingcallerid = callwaitingcallerid;
07254       tmp->threewaycalling = threewaycalling;
07255       tmp->adsi = adsi;
07256       tmp->permhidecallerid = hidecallerid;
07257       tmp->callreturn = callreturn;
07258       tmp->echocancel = echocancel;
07259       tmp->echotraining = echotraining;
07260       tmp->pulse = pulse;
07261       tmp->echocanbridged = echocanbridged;
07262       tmp->busydetect = busydetect;
07263       tmp->busycount = busycount;
07264       tmp->busy_tonelength = busy_tonelength;
07265       tmp->busy_quietlength = busy_quietlength;
07266       tmp->callprogress = callprogress;
07267       tmp->cancallforward = cancallforward;
07268       tmp->dtmfrelax = relaxdtmf;
07269       tmp->callwaiting = tmp->permcallwaiting;
07270       tmp->hidecallerid = tmp->permhidecallerid;
07271       tmp->channel = channel;
07272       tmp->stripmsd = stripmsd;
07273       tmp->use_callerid = use_callerid;
07274       tmp->cid_signalling = cid_signalling;
07275       tmp->cid_start = cid_start;
07276       tmp->zaptrcallerid = zaptrcallerid;
07277       tmp->restrictcid = restrictcid;
07278       tmp->use_callingpres = use_callingpres;
07279       tmp->priindication_oob = priindication_oob;
07280       tmp->priexclusive = cur_priexclusive;
07281       if (tmp->usedistinctiveringdetection) {
07282          if (!tmp->use_callerid) {
07283             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07284             tmp->use_callerid = 1;
07285          }
07286       }
07287 
07288       ast_copy_string(tmp->accountcode, accountcode, sizeof(tmp->accountcode));
07289       tmp->amaflags = amaflags;
07290       if (!here) {
07291          tmp->confno = -1;
07292          tmp->propconfno = -1;
07293       }
07294       tmp->canpark = canpark;
07295       tmp->transfer = transfer;
07296       ast_copy_string(tmp->defcontext,context,sizeof(tmp->defcontext));
07297       ast_copy_string(tmp->language, language, sizeof(tmp->language));
07298       ast_copy_string(tmp->musicclass, musicclass, sizeof(tmp->musicclass));
07299       ast_copy_string(tmp->context, context, sizeof(tmp->context));
07300       ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
07301       tmp->cid_ton = 0;
07302       ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));
07303       ast_copy_string(tmp->mailbox, mailbox, sizeof(tmp->mailbox));
07304       tmp->msgstate = -1;
07305       tmp->group = cur_group;
07306       tmp->callgroup=cur_callergroup;
07307       tmp->pickupgroup=cur_pickupgroup;
07308       tmp->rxgain = rxgain;
07309       tmp->txgain = txgain;
07310       tmp->tonezone = tonezone;
07311       tmp->onhooktime = time(NULL);
07312       if (tmp->subs[SUB_REAL].zfd > -1) {
07313          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07314          if (tmp->dsp)
07315             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07316          update_conf(tmp);
07317          if (!here) {
07318             if ((signalling != SIG_PRI) && (signalling != SIG_R2))
07319                /* Hang it up to be sure it's good */
07320                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07321          }
07322          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07323 #ifdef ZAPATA_PRI
07324          /* the dchannel is down so put the channel in alarm */
07325          if (tmp->pri && !pri_is_up(tmp->pri))
07326             tmp->inalarm = 1;
07327          else
07328             tmp->inalarm = 0;
07329 #endif            
07330          memset(&si, 0, sizeof(si));
07331          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07332             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07333             destroy_zt_pvt(&tmp);
07334             return NULL;
07335          }
07336          if (si.alarms) tmp->inalarm = 1;
07337       }
07338 
07339       tmp->polarityonanswerdelay = polarityonanswerdelay;
07340       tmp->answeronpolarityswitch = answeronpolarityswitch;
07341       tmp->hanguponpolarityswitch = hanguponpolarityswitch;
07342       tmp->sendcalleridafter = sendcalleridafter;
07343 
07344    }
07345    if (tmp && !here) {
07346       /* nothing on the iflist */
07347       if (!*wlist) {
07348          *wlist = tmp;
07349          tmp->prev = NULL;
07350          tmp->next = NULL;
07351          *wend = tmp;
07352       } else {
07353          /* at least one member on the iflist */
07354          struct zt_pvt *working = *wlist;
07355 
07356          /* check if we maybe have to put it on the begining */
07357          if (working->channel > tmp->channel) {
07358             tmp->next = *wlist;
07359             tmp->prev = NULL;
07360             (*wlist)->prev = tmp;
07361             *wlist = tmp;
07362          } else {
07363          /* go through all the members and put the member in the right place */
07364             while (working) {
07365                /* in the middle */
07366                if (working->next) {
07367                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07368                      tmp->next = working->next;
07369                      tmp->prev = working;
07370                      working->next->prev = tmp;
07371                      working->next = tmp;
07372                      break;
07373                   }
07374                } else {
07375                /* the last */
07376                   if (working->channel < tmp->channel) {
07377                      working->next = tmp;
07378                      tmp->next = NULL;
07379                      tmp->prev = working;
07380                      *wend = tmp;
07381                      break;
07382                   }
07383                }
07384                working = working->next;
07385             }
07386          }
07387       }
07388    }
07389    return tmp;
07390 }

static int my_getsigstr struct ast_channel chan,
char *  str,
const char *  term,
int  ms
[static]
 

Definition at line 5165 of file chan_zap.c.

References ast_waitfordigit().

Referenced by ss_thread().

05166 {
05167    char c;
05168 
05169    *str = 0; /* start with empty output buffer */
05170    for (;;)
05171    {
05172       /* Wait for the first digit (up to specified ms). */
05173       c = ast_waitfordigit(chan, ms);
05174       /* if timeout, hangup or error, return as such */
05175       if (c < 1)
05176          return c;
05177       *str++ = c;
05178       *str = 0;
05179       if (strchr(term, c))
05180          return 1;
05181    }
05182 }

static int my_zt_write struct zt_pvt p,
unsigned char *  buf,
int  len,
int  index,
int  linear
[static]
 

Definition at line 4706 of file chan_zap.c.

References ast_log(), zt_pvt::channel, LOG_DEBUG, option_debug, READ_SIZE, zt_pvt::subs, and zt_subchannel::zfd.

Referenced by zt_write().

04707 {
04708    int sent=0;
04709    int size;
04710    int res;
04711    int fd;
04712    fd = p->subs[index].zfd;
04713    while(len) {
04714       size = len;
04715       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
04716          size = (linear ? READ_SIZE * 2 : READ_SIZE);
04717       res = write(fd, buf, size);
04718       if (res != size) {
04719          if (option_debug)
04720             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04721          return sent;
04722       }
04723       len -= size;
04724       buf += size;
04725    }
04726    return sent;
04727 }

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 11237 of file chan_zap.c.

References ast_log(), and setup_zap().

11238 {
11239    int res = 0;
11240 
11241    res = setup_zap(1);
11242    if (res) {
11243       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11244       return -1;
11245    }
11246    return 0;
11247 }

static int reset_conf struct zt_pvt p  )  [static]
 

Definition at line 1317 of file chan_zap.c.

References ast_log(), zt_pvt::channel, zt_pvt::confno, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.

Referenced by zt_hangup().

01318 {
01319    ZT_CONFINFO zi;
01320    memset(&zi, 0, sizeof(zi));
01321    p->confno = -1;
01322    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01323    if (p->subs[SUB_REAL].zfd > -1) {
01324       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01325          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01326    }
01327    return 0;
01328 }

static int restart_monitor void   )  [static]
 

Definition at line 6776 of file chan_zap.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), and LOG_ERROR.

06777 {
06778    pthread_attr_t attr;
06779    pthread_attr_init(&attr);
06780    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06781    /* If we're supposed to be stopped -- stay stopped */
06782    if (monitor_thread == AST_PTHREADT_STOP)
06783       return 0;
06784    if (ast_mutex_lock(&monlock)) {
06785       ast_log(LOG_WARNING, "Unable to lock monitor\n");
06786       return -1;
06787    }
06788    if (monitor_thread == pthread_self()) {
06789       ast_mutex_unlock(&monlock);
06790       ast_log(LOG_WARNING, "Cannot kill myself\n");
06791       return -1;
06792    }
06793    if (monitor_thread != AST_PTHREADT_NULL) {
06794       /* Just signal it to be sure it wakes up */
06795 #if 0
06796       pthread_cancel(monitor_thread);
06797 #endif
06798       pthread_kill(monitor_thread, SIGURG);
06799 #if 0
06800       pthread_join(monitor_thread, NULL);
06801 #endif
06802    } else {
06803       /* Start a new monitor */
06804       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
06805          ast_mutex_unlock(&monlock);
06806          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
06807          return -1;
06808       }
06809    }
06810 #if 0
06811    printf("Created thread %ld detached in restart monitor\n", monitor_thread);
06812 #endif
06813    ast_mutex_unlock(&monlock);
06814    return 0;
06815 }

static int restore_conference struct zt_pvt p  )  [static]
 

Definition at line 1643 of file chan_zap.c.

References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, and zt_pvt::subs.

Referenced by send_callerid(), and zt_read().

01644 {
01645    int res;
01646    if (p->saveconf.confmode) {
01647       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01648       p->saveconf.confmode = 0;
01649       if (res) {
01650          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01651          return -1;
01652       }
01653    }
01654    if (option_debug)
01655       ast_log(LOG_DEBUG, "Restored conferencing\n");
01656    return 0;
01657 }

static int restore_gains struct zt_pvt p  )  [static]
 

Definition at line 1573 of file chan_zap.c.

References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, and zt_pvt::txgain.

Referenced by zt_hangup().

01574 {
01575    int res;
01576 
01577    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01578    if (res) {
01579       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01580       return -1;
01581    }
01582 
01583    return 0;
01584 }

static int save_conference struct zt_pvt p  )  [static]
 

Definition at line 1615 of file chan_zap.c.

References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, and zt_pvt::subs.

Referenced by zt_callwait().

01616 {
01617    struct zt_confinfo c;
01618    int res;
01619    if (p->saveconf.confmode) {
01620       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01621       return -1;
01622    }
01623    p->saveconf.chan = 0;
01624    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01625    if (res) {
01626       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01627       p->saveconf.confmode = 0;
01628       return -1;
01629    }
01630    c.chan = 0;
01631    c.confno = 0;
01632    c.confmode = ZT_CONF_NORMAL;
01633    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01634    if (res) {
01635       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01636       return -1;
01637    }
01638    if (option_debug)
01639       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01640    return 0;
01641 }

static int send_callerid struct zt_pvt p  )  [static]
 

Definition at line 1685 of file chan_zap.c.

References ast_log(), zt_pvt::callwaitcas, CIDCW_EXPIRE_SAMPLES, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, and zt_setlinear().

Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().

01686 {
01687    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01688    int res;
01689    /* Take out of linear mode if necessary */
01690    if (p->subs[SUB_REAL].linear) {
01691       p->subs[SUB_REAL].linear = 0;
01692       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01693    }
01694    while(p->cidpos < p->cidlen) {
01695       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01696       if (res < 0) {
01697          if (errno == EAGAIN)
01698             return 0;
01699          else {
01700             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01701             return -1;
01702          }
01703       }
01704       if (!res)
01705          return 0;
01706       p->cidpos += res;
01707    }
01708    free(p->cidspill);
01709    p->cidspill = NULL;
01710    if (p->callwaitcas) {
01711       /* Wait for CID/CW to expire */
01712       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01713    } else
01714       restore_conference(p);
01715    return 0;
01716 }

int send_cwcidspill struct zt_pvt p  ) 
 

Definition at line 1661 of file chan_zap.c.

References ast_callerid_callwaiting_generate(), AST_LAW, ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, malloc, MAX_CALLERID_SIZE, option_verbose, READ_SIZE, send_callerid(), and VERBOSE_PREFIX_3.

Referenced by zt_read().

01662 {
01663    p->callwaitcas = 0;
01664    p->cidcwexpire = 0;
01665    p->cidspill = malloc(MAX_CALLERID_SIZE);
01666    if (p->cidspill) {
01667       memset(p->cidspill, 0x7f, MAX_CALLERID_SIZE);
01668       p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01669       /* Make sure we account for the end */
01670       p->cidlen += READ_SIZE * 4;
01671       p->cidpos = 0;
01672       send_callerid(p);
01673       if (option_verbose > 2)
01674          ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01675    } else return -1;
01676    return 0;
01677 }

int set_actual_gain int  fd,
int  chan,
float  rxgain,
float  txgain,
int  law
 

Definition at line 1554 of file chan_zap.c.

References set_actual_rxgain(), and set_actual_txgain().

Referenced by bump_gains(), restore_gains(), and zt_call().

01555 {
01556    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01557 }

int set_actual_rxgain int  fd,
int  chan,
float  gain,
int  law
 

Definition at line 1536 of file chan_zap.c.

References ast_log(), fill_rxgain(), and LOG_DEBUG.

Referenced by set_actual_gain(), and zt_setoption().

01537 {
01538    struct zt_gains g;
01539    int res;
01540 
01541    memset(&g, 0, sizeof(g));
01542    g.chan = chan;
01543    res = ioctl(fd, ZT_GETGAINS, &g);
01544    if (res) {
01545       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01546       return res;
01547    }
01548 
01549    fill_rxgain(&g, gain, law);
01550 
01551    return ioctl(fd, ZT_SETGAINS, &g);
01552 }

int set_actual_txgain int  fd,
int  chan,
float  gain,
int  law
 

Definition at line 1518 of file chan_zap.c.

References ast_log(), fill_txgain(), and LOG_DEBUG.

Referenced by set_actual_gain(), and zt_setoption().

01519 {
01520    struct zt_gains g;
01521    int res;
01522 
01523    memset(&g, 0, sizeof(g));
01524    g.chan = chan;
01525    res = ioctl(fd, ZT_GETGAINS, &g);
01526    if (res) {
01527       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01528       return res;
01529    }
01530 
01531    fill_txgain(&g, gain, law);
01532 
01533    return ioctl(fd, ZT_SETGAINS, &g);
01534 }

static int setup_zap int  reload  )  [static]
 

Definition at line 10298 of file chan_zap.c.

References ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), ast_verbose(), cfg, ast_variable::lineno, ast_variable::name, ast_variable::next, option_verbose, ast_variable::value, and VERBOSE_PREFIX_2.

Referenced by reload(), and zap_restart().

10299 {
10300    struct ast_config *cfg;
10301    struct ast_variable *v;
10302    struct zt_pvt *tmp;
10303    char *chan;
10304    char *c;
10305    char *ringc;
10306    int start, finish,x;
10307    int y;
10308    int found_pseudo = 0;
10309    int cur_radio = 0;
10310 #ifdef ZAPATA_PRI
10311    int spanno;
10312    int i;
10313    int logicalspan;
10314    int trunkgroup;
10315    int dchannels[NUM_DCHANS];
10316    struct zt_pri *pri;
10317 #endif
10318 
10319    cfg = ast_config_load(config);
10320 
10321    /* We *must* have a config file otherwise stop immediately */
10322    if (!cfg) {
10323       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
10324       return -1;
10325    }
10326    
10327 
10328    if (ast_mutex_lock(&iflock)) {
10329       /* It's a little silly to lock it, but we mind as well just to be sure */
10330       ast_log(LOG_ERROR, "Unable to lock interface list???\n");
10331       return -1;
10332    }
10333 #ifdef ZAPATA_PRI
10334    if (!reload) {
10335       /* Process trunkgroups first */
10336       v = ast_variable_browse(cfg, "trunkgroups");
10337       while(v) {
10338          if (!strcasecmp(v->name, "trunkgroup")) {
10339             trunkgroup = atoi(v->value);
10340             if (trunkgroup > 0) {
10341                if ((c = strchr(v->value, ','))) {
10342                   i = 0;
10343                   memset(dchannels, 0, sizeof(dchannels));
10344                   while(c && (i < NUM_DCHANS)) {
10345                      dchannels[i] = atoi(c + 1);
10346                      if (dchannels[i] < 0) {
10347                         ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of zapata.conf\n", trunkgroup, v->lineno);
10348                      } else
10349                         i++;
10350                      c = strchr(c + 1, ',');
10351                   }
10352                   if (i) {
10353                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
10354                         ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of zapata.conf\n", trunkgroup, dchannels[0], v->lineno);
10355                      } else if (option_verbose > 1)
10356                         ast_verbose(VERBOSE_PREFIX_2 "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
10357                   } else
10358                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
10359                } else
10360                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
10361             } else
10362                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
10363          } else if (!strcasecmp(v->name, "spanmap")) {
10364             spanno = atoi(v->value);
10365             if (spanno > 0) {
10366                if ((c = strchr(v->value, ','))) {
10367                   trunkgroup = atoi(c + 1);
10368                   if (trunkgroup > 0) {
10369                      if ((c = strchr(c + 1, ','))) 
10370                         logicalspan = atoi(c + 1);
10371                      else
10372                         logicalspan = 0;
10373                      if (logicalspan >= 0) {
10374                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
10375                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
10376                         } else if (option_verbose > 1) 
10377                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
10378                      } else
10379                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
10380                   } else
10381                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
10382                } else
10383                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
10384             } else
10385                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
10386          } else {
10387             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
10388          }
10389          v = v->next;
10390       }
10391    }
10392 #endif
10393    v = ast_variable_browse(cfg, "channels");
10394    while(v) {
10395       /* Create the interface list */
10396       if (!strcasecmp(v->name, "channel")
10397 #ifdef ZAPATA_PRI
10398          || !strcasecmp(v->name, "crv")
10399 #endif         
10400                ) {
10401          if (reload == 0) {
10402             if (cur_signalling < 0) {
10403                ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
10404                ast_config_destroy(cfg);
10405                ast_mutex_unlock(&iflock);
10406                return -1;
10407             }
10408          }
10409          c = v->value;
10410 
10411 #ifdef ZAPATA_PRI
10412          pri = NULL;
10413          if (!strcasecmp(v->name, "crv")) {
10414             if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
10415                ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", v->lineno);
10416                ast_config_destroy(cfg);
10417                ast_mutex_unlock(&iflock);
10418                return -1;
10419             }
10420             if (trunkgroup < 1) {
10421                ast_log(LOG_WARNING, "CRV trunk group must be a postive number at line %d\n", v->lineno);
10422                ast_config_destroy(cfg);
10423                ast_mutex_unlock(&iflock);
10424                return -1;
10425             }
10426             c+=y;
10427             for (y=0;y<NUM_SPANS;y++) {
10428                if (pris[y].trunkgroup == trunkgroup) {
10429                   pri = pris + y;
10430                   break;
10431                }
10432             }
10433             if (!pri) {
10434                ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, v->lineno);
10435                ast_config_destroy(cfg);
10436                ast_mutex_unlock(&iflock);
10437                return -1;
10438             }
10439          }
10440 #endif         
10441          chan = strsep(&c, ",");
10442          while(chan) {
10443             if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
10444                /* Range */
10445             } else if (sscanf(chan, "%d", &start)) {
10446                /* Just one */
10447                finish = start;
10448             } else if (!strcasecmp(chan, "pseudo")) {
10449                finish = start = CHAN_PSEUDO;
10450                found_pseudo = 1;
10451             } else {
10452                ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", v->value, chan);
10453                ast_config_destroy(cfg);
10454                ast_mutex_unlock(&iflock);
10455                return -1;
10456             }
10457             if (finish < start) {
10458                ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
10459                x = finish;
10460                finish = start;
10461                start = x;
10462             }
10463             for (x=start;x<=finish;x++) {
10464 #ifdef ZAPATA_PRI
10465                tmp = mkintf(x, cur_signalling, cur_radio, pri, reload);
10466 #else             
10467                tmp = mkintf(x, cur_signalling, cur_radio, NULL, reload);
10468 #endif               
10469 
10470                if (tmp) {
10471                   if (option_verbose > 2) {
10472 #ifdef ZAPATA_PRI
10473                      if (pri)
10474                         ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup,x, sig2str(tmp->sig));
10475                      else
10476 #endif
10477                         ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
10478                   }
10479                } else {
10480                   if (reload == 1)
10481                      ast_log(LOG_ERROR, "Unable to reconfigure channel '%s'\n", v->value);
10482                   else
10483                      ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
10484                   ast_config_destroy(cfg);
10485                   ast_mutex_unlock(&iflock);
10486                   return -1;
10487                }
10488             }
10489             chan = strsep(&c, ",");
10490          }
10491       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
10492          if (ast_true(v->value))
10493             usedistinctiveringdetection = 1;
10494       } else if (!strcasecmp(v->name, "dring1context")) {
10495          ast_copy_string(drings.ringContext[0].contextData,v->value,sizeof(drings.ringContext[0].contextData));
10496       } else if (!strcasecmp(v->name, "dring2context")) {
10497          ast_copy_string(drings.ringContext[1].contextData,v->value,sizeof(drings.ringContext[1].contextData));
10498       } else if (!strcasecmp(v->name, "dring3context")) {
10499          ast_copy_string(drings.ringContext[2].contextData,v->value,sizeof(drings.ringContext[2].contextData));
10500       } else if (!strcasecmp(v->name, "dring1")) {
10501          ringc = v->value;
10502          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
10503       } else if (!strcasecmp(v->name, "dring2")) {
10504          ringc = v->value;
10505          sscanf(ringc,"%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
10506       } else if (!strcasecmp(v->name, "dring3")) {
10507          ringc = v->value;
10508          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
10509       } else if (!strcasecmp(v->name, "usecallerid")) {
10510          use_callerid = ast_true(v->value);
10511       } else if (!strcasecmp(v->name, "cidsignalling")) {
10512          if (!strcasecmp(v->value, "bell"))
10513             cid_signalling = CID_SIG_BELL;
10514          else if (!strcasecmp(v->value, "v23"))
10515             cid_signalling = CID_SIG_V23;
10516          else if (!strcasecmp(v->value, "dtmf"))
10517             cid_signalling = CID_SIG_DTMF;
10518          else if (ast_true(v->value))
10519             cid_signalling = CID_SIG_BELL;
10520       } else if (!strcasecmp(v->name, "cidstart")) {
10521          if (!strcasecmp(v->value, "ring"))
10522             cid_start = CID_START_RING;
10523          else if (!strcasecmp(v->value, "polarity"))
10524             cid_start = CID_START_POLARITY;
10525          else if (!strcasecmp(v->value, "usehist"))
10526             cid_start = CID_START_USEHIST;
10527          else if (ast_true(v->value))
10528             cid_start = CID_START_RING;
10529       } else if (!strcasecmp(v->name, "threewaycalling")) {
10530          threewaycalling = ast_true(v->value);
10531       } else if (!strcasecmp(v->name, "cancallforward")) {
10532          cancallforward = ast_true(v->value);
10533       } else if (!strcasecmp(v->name, "relaxdtmf")) {
10534          if (ast_true(v->value)) 
10535             relaxdtmf = DSP_DIGITMODE_RELAXDTMF;
10536          else
10537             relaxdtmf = 0;
10538       } else if (!strcasecmp(v->name, "mailbox")) {
10539          ast_copy_string(mailbox, v->value, sizeof(mailbox));
10540       } else if (!strcasecmp(v->name, "adsi")) {
10541          adsi = ast_true(v->value);
10542       } else if (!strcasecmp(v->name, "transfer")) {
10543          transfer = ast_true(v->value);
10544       } else if (!strcasecmp(v->name, "canpark")) {
10545          canpark = ast_true(v->value);
10546       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
10547          echocanbridged = ast_true(v->value);
10548       } else if (!strcasecmp(v->name, "busydetect")) {
10549          busydetect = ast_true(v->value);
10550       } else if (!strcasecmp(v->name, "busycount")) {
10551          busycount = atoi(v->value);
10552       } else if (!strcasecmp(v->name, "busypattern")) {
10553          if (sscanf(v->value, "%d,%d", &busy_tonelength, &busy_quietlength) != 2) {
10554             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
10555          }
10556       } else if (!strcasecmp(v->name, "callprogress")) {
10557          if (ast_true(v->value))
10558             callprogress |= 1;
10559          else
10560             callprogress &= ~1;
10561       } else if (!strcasecmp(v->name, "faxdetect")) {
10562          if (!strcasecmp(v->value, "incoming")) {
10563             callprogress |= 4;
10564             callprogress &= ~2;
10565          } else if (!strcasecmp(v->value, "outgoing")) {
10566             callprogress &= ~4;
10567             callprogress |= 2;
10568          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
10569             callprogress |= 6;
10570          else
10571             callprogress &= ~6;
10572       } else if (!strcasecmp(v->name, "echocancel")) {
10573          if (!ast_strlen_zero(v->value)) {
10574             y = atoi(v->value);
10575          } else
10576             y = 0;
10577          if ((y == 32) || (y == 64) || (y == 128) || (y == 256))
10578             echocancel = y;
10579          else {
10580             echocancel = ast_true(v->value);
10581             if (echocancel)
10582                echocancel=128;
10583          }
10584       } else if (!strcasecmp(v->name, "echotraining")) {
10585          if (sscanf(v->value, "%d", &y) == 1) {
10586             if ((y < 10) || (y > 4000)) {
10587                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 2000 ms at line %d\n", v->lineno);              
10588             } else {
10589                echotraining = y;
10590             }
10591          } else if (ast_true(v->value)) {
10592             echotraining = 400;
10593          } else
10594             echotraining = 0;
10595       } else if (!strcasecmp(v->name, "hidecallerid")) {
10596          hidecallerid = ast_true(v->value);
10597       } else if (!strcasecmp(v->name, "pulsedial")) {
10598          pulse = ast_true(v->value);
10599       } else if (!strcasecmp(v->name, "callreturn")) {
10600          callreturn = ast_true(v->value);
10601       } else if (!strcasecmp(v->name, "callwaiting")) {
10602          callwaiting = ast_true(v->value);
10603       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
10604          callwaitingcallerid = ast_true(v->value);
10605       } else if (!strcasecmp(v->name, "context")) {
10606          ast_copy_string(context, v->value, sizeof(context));
10607       } else if (!strcasecmp(v->name, "language")) {
10608          ast_copy_string(language, v->value, sizeof(language));
10609       } else if (!strcasecmp(v->name, "progzone")) {
10610          ast_copy_string(progzone, v->value, sizeof(progzone));
10611       } else if (!strcasecmp(v->name, "musiconhold")) {
10612          ast_copy_string(musicclass, v->value, sizeof(musicclass));
10613       } else if (!strcasecmp(v->name, "stripmsd")) {
10614          stripmsd = atoi(v->value);
10615       } else if (!strcasecmp(v->name, "jitterbuffers")) {
10616          numbufs = atoi(v->value);
10617       } else if (!strcasecmp(v->name, "group")) {
10618          cur_group = ast_get_group(v->value);
10619       } else if (!strcasecmp(v->name, "callgroup")) {
10620          cur_callergroup = ast_get_group(v->value);
10621       } else if (!strcasecmp(v->name, "pickupgroup")) {
10622          cur_pickupgroup = ast_get_group(v->value);
10623       } else if (!strcasecmp(v->name, "immediate")) {
10624          immediate = ast_true(v->value);
10625       } else if (!strcasecmp(v->name, "transfertobusy")) {
10626          transfertobusy = ast_true(v->value);
10627       } else if (!strcasecmp(v->name, "rxgain")) {
10628          if (sscanf(v->value, "%f", &rxgain) != 1) {
10629             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
10630          }
10631       } else if (!strcasecmp(v->name, "txgain")) {
10632          if (sscanf(v->value, "%f", &txgain) != 1) {
10633             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
10634          }
10635       } else if (!strcasecmp(v->name, "tonezone")) {
10636          if (sscanf(v->value, "%d", &tonezone) != 1) {
10637             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
10638          }
10639       } else if (!strcasecmp(v->name, "callerid")) {
10640          if (!strcasecmp(v->value, "asreceived")) {
10641             cid_num[0] = '\0';
10642             cid_name[0] = '\0';
10643          } else {
10644             ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
10645          }
10646       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
10647          zaptrcallerid = ast_true(v->value);
10648       } else if (!strcasecmp(v->name, "restrictcid")) {
10649          restrictcid = ast_true(v->value);
10650       } else if (!strcasecmp(v->name, "usecallingpres")) {
10651          use_callingpres = ast_true(v->value);
10652       } else if (!strcasecmp(v->name, "accountcode")) {
10653          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10654       } else if (!strcasecmp(v->name, "amaflags")) {
10655          y = ast_cdr_amaflags2int(v->value);
10656          if (y < 0) 
10657             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
10658          else
10659             amaflags = y;
10660       } else if(!reload){ 
10661           if (!strcasecmp(v->name, "signalling")) {
10662             if (!strcasecmp(v->value, "em")) {
10663                cur_signalling = SIG_EM;
10664             } else if (!strcasecmp(v->value, "em_e1")) {
10665                cur_signalling = SIG_EM_E1;
10666             } else if (!strcasecmp(v->value, "em_w")) {
10667                cur_signalling = SIG_EMWINK;
10668                cur_radio = 0;
10669             } else if (!strcasecmp(v->value, "fxs_ls")) {
10670                cur_signalling = SIG_FXSLS;
10671                cur_radio = 0;
10672             } else if (!strcasecmp(v->value, "fxs_gs")) {
10673                cur_signalling = SIG_FXSGS;
10674                cur_radio = 0;
10675             } else if (!strcasecmp(v->value, "fxs_ks")) {
10676                cur_signalling = SIG_FXSKS;
10677                cur_radio = 0;
10678             } else if (!strcasecmp(v->value, "fxo_ls")) {
10679                cur_signalling = SIG_FXOLS;
10680                cur_radio = 0;
10681             } else if (!strcasecmp(v->value, "fxo_gs")) {
10682                cur_signalling = SIG_FXOGS;
10683                cur_radio = 0;
10684             } else if (!strcasecmp(v->value, "fxo_ks")) {
10685                cur_signalling = SIG_FXOKS;
10686                cur_radio = 0;
10687             } else if (!strcasecmp(v->value, "fxs_rx")) {
10688                cur_signalling = SIG_FXSKS;
10689                cur_radio = 1;
10690             } else if (!strcasecmp(v->value, "fxo_rx")) {
10691                cur_signalling = SIG_FXOLS;
10692                cur_radio = 1;
10693             } else if (!strcasecmp(v->value, "fxs_tx")) {
10694                cur_signalling = SIG_FXSLS;
10695                cur_radio = 1;
10696             } else if (!strcasecmp(v->value, "fxo_tx")) {
10697                cur_signalling = SIG_FXOGS;
10698                cur_radio = 1;
10699             } else if (!strcasecmp(v->value, "em_rx")) {
10700                cur_signalling = SIG_EM;
10701                cur_radio = 1;
10702             } else if (!strcasecmp(v->value, "em_tx")) {
10703                cur_signalling = SIG_EM;
10704                cur_radio = 1;
10705             } else if (!strcasecmp(v->value, "em_rxtx")) {
10706                cur_signalling = SIG_EM;
10707                cur_radio = 2;
10708             } else if (!strcasecmp(v->value, "em_txrx")) {
10709                cur_signalling = SIG_EM;
10710                cur_radio = 2;
10711             } else if (!strcasecmp(v->value, "sf")) {
10712                cur_signalling = SIG_SF;
10713                cur_radio = 0;
10714             } else if (!strcasecmp(v->value, "sf_w")) {
10715                cur_signalling = SIG_SFWINK;
10716                cur_radio = 0;
10717             } else if (!strcasecmp(v->value, "sf_featd")) {
10718                cur_signalling = SIG_FEATD;
10719                cur_radio = 0;
10720             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10721                cur_signalling = SIG_FEATDMF;
10722                cur_radio = 0;
10723             } else if (!strcasecmp(v->value, "sf_featb")) {
10724                cur_signalling = SIG_SF_FEATB;
10725                cur_radio = 0;
10726             } else if (!strcasecmp(v->value, "sf")) {
10727                cur_signalling = SIG_SF;
10728                cur_radio = 0;
10729             } else if (!strcasecmp(v->value, "sf_rx")) {
10730                cur_signalling = SIG_SF;
10731                cur_radio = 1;
10732             } else if (!strcasecmp(v->value, "sf_tx")) {
10733                cur_signalling = SIG_SF;
10734                cur_radio = 1;
10735             } else if (!strcasecmp(v->value, "sf_rxtx")) {
10736                cur_signalling = SIG_SF;
10737                cur_radio = 2;
10738             } else if (!strcasecmp(v->value, "sf_txrx")) {
10739                cur_signalling = SIG_SF;
10740                cur_radio = 2;
10741             } else if (!strcasecmp(v->value, "featd")) {
10742                cur_signalling = SIG_FEATD;
10743                cur_radio = 0;
10744             } else if (!strcasecmp(v->value, "featdmf")) {
10745                cur_signalling = SIG_FEATDMF;
10746                cur_radio = 0;
10747             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10748                cur_signalling = SIG_FEATDMF_TA;
10749                cur_radio = 0;
10750             } else if (!strcasecmp(v->value, "e911")) {
10751                cur_signalling = SIG_E911;
10752                cur_radio = 0;
10753             } else if (!strcasecmp(v->value, "featb")) {
10754                cur_signalling = SIG_FEATB;
10755                cur_radio = 0;
10756 #ifdef ZAPATA_PRI
10757             } else if (!strcasecmp(v->value, "pri_net")) {
10758                cur_radio = 0;
10759                cur_signalling = SIG_PRI;
10760                pritype = PRI_NETWORK;
10761             } else if (!strcasecmp(v->value, "pri_cpe")) {
10762                cur_signalling = SIG_PRI;
10763                cur_radio = 0;
10764                pritype = PRI_CPE;
10765             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
10766                cur_signalling = SIG_GR303FXOKS;
10767                cur_radio = 0;
10768                pritype = PRI_NETWORK;
10769             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
10770                cur_signalling = SIG_GR303FXSKS;
10771                cur_radio = 0;
10772                pritype = PRI_CPE;
10773 #endif
10774 #ifdef ZAPATA_R2
10775             } else if (!strcasecmp(v->value, "r2")) {
10776                cur_signalling = SIG_R2;
10777                cur_radio = 0;
10778 #endif         
10779             } else {
10780                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10781             }
10782 #ifdef ZAPATA_R2
10783          } else if (!strcasecmp(v->name, "r2country")) {
10784             r2prot = str2r2prot(v->value);
10785             if (r2prot < 0) {
10786                ast_log(LOG_WARNING, "Unknown R2 Country '%s' at line %d.\n", v->value, v->lineno);
10787             }
10788 #endif
10789 #ifdef ZAPATA_PRI
10790          } else if (!strcasecmp(v->name, "pridialplan")) {
10791             if (!strcasecmp(v->value, "national")) {
10792                dialplan = PRI_NATIONAL_ISDN + 1;
10793             } else if (!strcasecmp(v->value, "unknown")) {
10794                dialplan = PRI_UNKNOWN + 1;
10795             } else if (!strcasecmp(v->value, "private")) {
10796                dialplan = PRI_PRIVATE + 1;
10797             } else if (!strcasecmp(v->value, "international")) {
10798                dialplan = PRI_INTERNATIONAL_ISDN + 1;
10799             } else if (!strcasecmp(v->value, "local")) {
10800                dialplan = PRI_LOCAL_ISDN + 1;
10801             } else if (!strcasecmp(v->value, "dynamic")) {
10802                dialplan = -1;
10803             } else {
10804                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10805             }
10806          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
10807             if (!strcasecmp(v->value, "national")) {
10808                localdialplan = PRI_NATIONAL_ISDN + 1;
10809             } else if (!strcasecmp(v->value, "unknown")) {
10810                localdialplan = PRI_UNKNOWN + 1;
10811             } else if (!strcasecmp(v->value, "private")) {
10812                localdialplan = PRI_PRIVATE + 1;
10813             } else if (!strcasecmp(v->value, "international")) {
10814                localdialplan = PRI_INTERNATIONAL_ISDN + 1;
10815             } else if (!strcasecmp(v->value, "local")) {
10816                localdialplan = PRI_LOCAL_ISDN + 1;
10817             } else if (!strcasecmp(v->value, "dynamic")) {
10818                localdialplan = -1;
10819             } else {
10820                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10821             }
10822          } else if (!strcasecmp(v->name, "switchtype")) {
10823             if (!strcasecmp(v->value, "national")) 
10824                switchtype = PRI_SWITCH_NI2;
10825             else if (!strcasecmp(v->value, "ni1"))
10826                switchtype = PRI_SWITCH_NI1;
10827             else if (!strcasecmp(v->value, "dms100"))
10828                switchtype = PRI_SWITCH_DMS100;
10829             else if (!strcasecmp(v->value, "4ess"))
10830                switchtype = PRI_SWITCH_ATT4ESS;
10831             else if (!strcasecmp(v->value, "5ess"))
10832                switchtype = PRI_SWITCH_LUCENT5E;
10833             else if (!strcasecmp(v->value, "euroisdn"))
10834                switchtype = PRI_SWITCH_EUROISDN_E1;
10835             else if (!strcasecmp(v->value, "qsig"))
10836                switchtype = PRI_SWITCH_QSIG;
10837             else {
10838                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
10839                ast_config_destroy(cfg);
10840                ast_mutex_unlock(&iflock);
10841                return -1;
10842             }
10843          } else if (!strcasecmp(v->name, "nsf")) {
10844             if (!strcasecmp(v->value, "sdn"))
10845                nsf = PRI_NSF_SDN;
10846             else if (!strcasecmp(v->value, "megacom"))
10847                nsf = PRI_NSF_MEGACOM;
10848             else if (!strcasecmp(v->value, "accunet"))
10849                nsf = PRI_NSF_ACCUNET;
10850             else if (!strcasecmp(v->value, "none"))
10851                nsf = PRI_NSF_NONE;
10852             else {
10853                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
10854                nsf = PRI_NSF_NONE;
10855             }
10856          } else if (!strcasecmp(v->name, "priindication")) {
10857             if (!strcasecmp(v->value, "outofband"))
10858                priindication_oob = 1;
10859             else if (!strcasecmp(v->value, "inband"))
10860                priindication_oob = 0;
10861             else
10862                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
10863                   v->value, v->lineno);
10864          } else if (!strcasecmp(v->name, "priexclusive")) {
10865             cur_priexclusive = ast_true(v->value);
10866          } else if (!strcasecmp(v->name, "internationalprefix")) {
10867             ast_copy_string(internationalprefix, v->value, sizeof(internationalprefix));
10868          } else if (!strcasecmp(v->name, "nationalprefix")) {
10869             ast_copy_string(nationalprefix, v->value, sizeof(nationalprefix));
10870          } else if (!strcasecmp(v->name, "localprefix")) {
10871             ast_copy_string(localprefix, v->value, sizeof(localprefix));
10872          } else if (!strcasecmp(v->name, "privateprefix")) {
10873             ast_copy_string(privateprefix, v->value, sizeof(privateprefix));
10874          } else if (!strcasecmp(v->name, "unknownprefix")) {
10875             ast_copy_string(unknownprefix, v->value, sizeof(unknownprefix));
10876          } else if (!strcasecmp(v->name, "resetinterval")) {
10877             if (!strcasecmp(v->value, "never"))
10878                resetinterval = -1;
10879             else if( atoi(v->value) >= 60 )
10880                resetinterval = atoi(v->value);
10881             else
10882                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
10883                   v->value, v->lineno);
10884          } else if (!strcasecmp(v->name, "minunused")) {
10885             minunused = atoi(v->value);
10886          } else if (!strcasecmp(v->name, "idleext")) {
10887             ast_copy_string(idleext, v->value, sizeof(idleext));
10888          } else if (!strcasecmp(v->name, "idledial")) {
10889             ast_copy_string(idledial, v->value, sizeof(idledial));
10890          } else if (!strcasecmp(v->name, "overlapdial")) {
10891             overlapdial = ast_true(v->value);
10892          } else if (!strcasecmp(v->name, "pritimer")) {
10893 #ifdef PRI_GETSET_TIMERS
10894             char *timerc;
10895             int timer, timeridx;
10896             c = v->value;
10897             timerc = strsep(&c, ",");
10898             if (timerc) {
10899                timer = atoi(c);
10900                if (!timer)
10901                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
10902                else {
10903                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
10904                      pritimers[timeridx] = timer;
10905                   else
10906                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
10907                }
10908             } else
10909                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
10910 
10911          } else if (!strcasecmp(v->name, "facilityenable")) {
10912             facilityenable = ast_true(v->value);
10913 #endif /* PRI_GETSET_TIMERS */
10914 #endif /* ZAPATA_PRI */
10915          } else if (!strcasecmp(v->name, "cadence")) {
10916             /* setup to scan our argument */
10917             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
10918             int i;
10919             struct zt_ring_cadence new_cadence;
10920             int cid_location = -1;
10921                      int firstcadencepos = 0;
10922             char original_args[80];
10923             int cadence_is_ok = 1;
10924 
10925             ast_copy_string(original_args, v->value, sizeof(original_args));
10926             /* 16 cadences allowed (8 pairs) */
10927             element_count = sscanf(v->value, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
10928    
10929             /* Cadence must be even (on/off) */
10930             if (element_count % 2 == 1) {
10931                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
10932                cadence_is_ok = 0;
10933             }
10934    
10935             /* Ring cadences cannot be negative */
10936             for (i=0;i<element_count;i++) {
10937                     if (c[i] == 0) {
10938                        ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
10939                   cadence_is_ok = 0;
10940                   break;
10941                } else if (c[i] < 0) {
10942                   if (i % 2 == 1) {
10943                           /* Silence duration, negative possibly okay */
10944                      if (cid_location == -1) {
10945                              cid_location = i;
10946                         c[i] *= -1;
10947                      } else {
10948                              ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
10949                         cadence_is_ok = 0;
10950                         break;
10951                      }
10952                   } else {
10953                      if (firstcadencepos == 0) {
10954                              firstcadencepos = i; /* only recorded to avoid duplicate specification */
10955                                              /* duration will be passed negative to the zaptel driver */
10956                      } else {
10957                              ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
10958                         cadence_is_ok = 0;
10959                         break;
10960                      }
10961                   }
10962                }
10963             }
10964    
10965             /* Substitute our scanned cadence */
10966             for (i=0;i<16;i++) {
10967                new_cadence.ringcadence[i] = c[i];
10968             }
10969    
10970             if (cadence_is_ok) {
10971                /* ---we scanned it without getting annoyed; now some sanity checks--- */
10972                if (element_count < 2) {
10973                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
10974                } else {
10975                   if (cid_location == -1) {
10976                      /* user didn't say; default to first pause */
10977                      cid_location = 1;
10978                   } else {
10979                      /* convert element_index to cidrings value */
10980                      cid_location = (cid_location + 1) / 2;
10981                   }
10982                   /* ---we like their cadence; try to install it--- */
10983                   if (!user_has_defined_cadences++)
10984                      /* this is the first user-defined cadence; clear the default user cadences */
10985                      num_cadence = 0;
10986                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
10987                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
10988                   else {
10989                      cadences[num_cadence] = new_cadence;
10990                      cidrings[num_cadence++] = cid_location;
10991                      if (option_verbose > 2)
10992                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
10993                   }
10994                }
10995             }
10996          } else if (!strcasecmp(v->name, "ringtimeout")) {
10997             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
10998          } else if (!strcasecmp(v->name, "prewink")) {
10999             cur_prewink = atoi(v->value);
11000          } else if (!strcasecmp(v->name, "preflash")) {
11001             cur_preflash = atoi(v->value);
11002          } else if (!strcasecmp(v->name, "wink")) {
11003             cur_wink = atoi(v->value);
11004          } else if (!strcasecmp(v->name, "flash")) {
11005             cur_flash = atoi(v->value);
11006          } else if (!strcasecmp(v->name, "start")) {
11007             cur_start = atoi(v->value);
11008          } else if (!strcasecmp(v->name, "rxwink")) {
11009             cur_rxwink = atoi(v->value);
11010          } else if (!strcasecmp(v->name, "rxflash")) {
11011             cur_rxflash = atoi(v->value);
11012          } else if (!strcasecmp(v->name, "debounce")) {
11013             cur_debounce = atoi(v->value);
11014          } else if (!strcasecmp(v->name, "toneduration")) {
11015             int toneduration;
11016             int ctlfd;
11017             int res;
11018             struct zt_dialparams dps;
11019 
11020             ctlfd = open("/dev/zap/ctl", O_RDWR);
11021             if (ctlfd == -1) {
11022                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
11023                return -1;
11024             }
11025 
11026             toneduration = atoi(v->value);
11027             if (toneduration > -1) {
11028                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
11029                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
11030                if (res < 0) {
11031                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
11032                   return -1;
11033                }
11034             }
11035             close(ctlfd);
11036          } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
11037             polarityonanswerdelay = atoi(v->value);
11038          } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
11039             answeronpolarityswitch = ast_true(v->value);
11040          } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
11041             hanguponpolarityswitch = ast_true(v->value);
11042          } else if (!strcasecmp(v->name, "sendcalleridafter")) {
11043             sendcalleridafter = atoi(v->value);
11044          } else if (!strcasecmp(v->name, "defaultcic")) {
11045             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
11046          } else if (!strcasecmp(v->name, "defaultozz")) {
11047             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
11048          } 
11049       } else 
11050          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11051       v = v->next;
11052    }
11053    if (!found_pseudo && reload == 0) {
11054    
11055       /* Make sure pseudo isn't a member of any groups if
11056          we're automatically making it. */   
11057       cur_group = 0;
11058       cur_callergroup = 0;
11059       cur_pickupgroup = 0;
11060    
11061       tmp = mkintf(CHAN_PSEUDO, cur_signalling, cur_radio, NULL, reload);
11062 
11063       if (tmp) {
11064          if (option_verbose > 2)
11065             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
11066       } else {
11067          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
11068       }
11069    }
11070    ast_mutex_unlock(&iflock);
11071    ast_config_destroy(cfg);
11072 #ifdef ZAPATA_PRI
11073    if (!reload) {
11074       for (x=0;x<NUM_SPANS;x++) {
11075          if (pris[x].pvts[0]) {
11076             if (start_pri(pris + x)) {
11077                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
11078                return -1;
11079             } else if (option_verbose > 1)
11080                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
11081          }
11082       }
11083    }
11084 #endif
11085    /* And start the monitor for the first time */
11086    restart_monitor();
11087    return 0;
11088 }

static void * ss_thread void *  data  )  [static]
 

Definition at line 5202 of file chan_zap.c.

References alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_moh_stop(), ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_read(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_free(), callerid_get(), callerid_new(), zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, zt_pvt::cid_start, CID_START_USEHIST, zt_pvt::context, ast_channel::context, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, callerid_state::flags, ast_frame::frametype, free, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, ast_channel::language, zt_pvt::lastcid_num, callerid_state::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, manager_event(), my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, callerid_state::number, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::transfer, ast_channel::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_history(), zt_get_index(), zt_set_hook(), zt_wait_event(), and zt_wink().

Referenced by handle_init_event(), and zt_handle_event().

05203 {
05204    struct ast_channel *chan = data;
05205    struct zt_pvt *p = chan->tech_pvt;
05206    char exten[AST_MAX_EXTENSION]="";
05207    char exten2[AST_MAX_EXTENSION]="";
05208    unsigned char buf[256];
05209    char dtmfcid[300];
05210    char dtmfbuf[300];
05211    struct callerid_state *cs;
05212    char *name=NULL, *number=NULL;
05213    int distMatches;
05214    int curRingData[3];
05215    int receivedRingT;
05216    int counter1;
05217    int counter;
05218    int samples = 0;
05219 
05220    int flags;
05221    int i;
05222    int timeout;
05223    int getforward=0;
05224    char *s1, *s2;
05225    int len = 0;
05226    int res;
05227    int index;
05228    if (option_verbose > 2) 
05229       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05230    index = zt_get_index(chan, p, 1);
05231    if (index < 0) {
05232       ast_log(LOG_WARNING, "Huh?\n");
05233       ast_hangup(chan);
05234       return NULL;
05235    }
05236    if (p->dsp)
05237       ast_dsp_digitreset(p->dsp);
05238    switch(p->sig) {
05239 #ifdef ZAPATA_PRI
05240    case SIG_PRI:
05241       /* Now loop looking for an extension */
05242       ast_copy_string(exten, p->exten, sizeof(exten));
05243       len = strlen(exten);
05244       res = 0;
05245       while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05246          if (len && !ast_ignore_pattern(chan->context, exten))
05247             tone_zone_play_tone(p->subs[index].zfd, -1);
05248          else
05249             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05250          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05251             timeout = matchdigittimeout;
05252          else
05253             timeout = gendigittimeout;
05254          res = ast_waitfordigit(chan, timeout);
05255          if (res < 0) {
05256             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05257             ast_hangup(chan);
05258             return NULL;
05259          } else if (res) {
05260             exten[len++] = res;
05261             exten[len] = '\0';
05262          } else
05263             break;
05264       }
05265       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05266       if (ast_strlen_zero(exten)) {
05267          if (option_verbose > 2)
05268             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05269          exten[0] = 's';
05270          exten[1] = '\0';
05271       }
05272       tone_zone_play_tone(p->subs[index].zfd, -1);
05273       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05274          /* Start the real PBX */
05275          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05276          if (p->dsp) ast_dsp_digitreset(p->dsp);
05277          zt_enable_ec(p);
05278          ast_setstate(chan, AST_STATE_RING);
05279          res = ast_pbx_run(chan);
05280          if (res) {
05281             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05282          }
05283       } else {
05284          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05285          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05286          ast_hangup(chan);
05287          p->exten[0] = '\0';
05288          /* Since we send release complete here, we won't get one */
05289          p->call = NULL;
05290       }
05291       return NULL;
05292       break;
05293 #endif
05294    case SIG_FEATD:
05295    case SIG_FEATDMF:
05296    case SIG_E911:
05297    case SIG_FEATB:
05298    case SIG_EMWINK:
05299    case SIG_SF_FEATD:
05300    case SIG_SF_FEATDMF:
05301    case SIG_SF_FEATB:
05302    case SIG_SFWINK:
05303       if (zt_wink(p, index))  
05304          return NULL;
05305       /* Fall through */
05306    case SIG_EM:
05307    case SIG_EM_E1:
05308    case SIG_SF:
05309       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05310       if (p->dsp)
05311          ast_dsp_digitreset(p->dsp);
05312       /* set digit mode appropriately */
05313       if (p->dsp) {
05314          if (NEED_MFDETECT(p))
05315             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05316          else 
05317             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05318       }
05319       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05320       /* Wait for the first digit only if immediate=no */
05321       if (!p->immediate)
05322          /* Wait for the first digit (up to 5 seconds). */
05323          res = ast_waitfordigit(chan, 5000);
05324       else res = 0;
05325       if (res > 0) {
05326          /* save first char */
05327          dtmfbuf[0] = res;
05328          switch(p->sig) {
05329          case SIG_FEATD:
05330          case SIG_SF_FEATD:
05331             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05332             if (res > 0)
05333                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05334             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05335             break;
05336          case SIG_FEATDMF:
05337          case SIG_E911:
05338          case SIG_SF_FEATDMF:
05339             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05340             if (res > 0) {
05341                /* if E911, take off hook */
05342                if (p->sig == SIG_E911)
05343                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05344                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05345             }
05346             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05347             break;
05348          case SIG_FEATB:
05349          case SIG_SF_FEATB:
05350             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05351             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05352             break;
05353          case SIG_EMWINK:
05354             /* if we received a '*', we are actually receiving Feature Group D
05355                dial syntax, so use that mode; otherwise, fall through to normal
05356                mode
05357             */
05358             if (res == '*') {
05359                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05360                if (res > 0)
05361                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05362                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05363                break;
05364             }
05365          default:
05366             /* If we got the first digit, get the rest */
05367             len = 1;
05368             dtmfbuf[len] = '\0';
05369             while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05370                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05371                   timeout = matchdigittimeout;
05372                } else {
05373                   timeout = gendigittimeout;
05374                }
05375                res = ast_waitfordigit(chan, timeout);
05376                if (res < 0) {
05377                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05378                   ast_hangup(chan);
05379                   return NULL;
05380                } else if (res) {
05381                   dtmfbuf[len++] = res;
05382                   dtmfbuf[len] = '\0';
05383                } else {
05384                   break;
05385                }
05386             }
05387             break;
05388          }
05389       }
05390       if (res == -1) {
05391          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05392          ast_hangup(chan);
05393          return NULL;
05394       } else if (res < 0) {
05395          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05396          ast_hangup(chan);
05397          return NULL;
05398       }
05399       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05400       if (ast_strlen_zero(exten))
05401          ast_copy_string(exten, "s", sizeof(exten));
05402       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05403          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05404          if (exten[0] == '*') {
05405             char *stringp=NULL;
05406             ast_copy_string(exten2, exten, sizeof(exten2));
05407             /* Parse out extension and callerid */
05408             stringp=exten2 +1;
05409             s1 = strsep(&stringp, "*");
05410             s2 = strsep(&stringp, "*");
05411             if (s2) {
05412                if (!ast_strlen_zero(p->cid_num))
05413                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05414                else
05415                   ast_set_callerid(chan, s1, NULL, s1);
05416                ast_copy_string(exten, s2, sizeof(exten));
05417             } else
05418                ast_copy_string(exten, s1, sizeof(exten));
05419          } else if (p->sig == SIG_FEATD)
05420             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05421       }
05422       if (p->sig == SIG_FEATDMF) {
05423          if (exten[0] == '*') {
05424             char *stringp=NULL;
05425             ast_copy_string(exten2, exten, sizeof(exten2));
05426             /* Parse out extension and callerid */
05427             stringp=exten2 +1;
05428             s1 = strsep(&stringp, "#");
05429             s2 = strsep(&stringp, "#");
05430             if (s2) {
05431                if (!ast_strlen_zero(p->cid_num))
05432                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05433                else
05434                   if(*(s1 + 2))
05435                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05436                ast_copy_string(exten, s2 + 1, sizeof(exten));
05437             } else
05438                ast_copy_string(exten, s1 + 2, sizeof(exten));
05439          } else
05440             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05441       }
05442       if (p->sig == SIG_E911) {
05443          if (exten[0] == '*') {
05444             char *stringp=NULL;
05445             ast_copy_string(exten2, exten, sizeof(exten2));
05446             /* Parse out extension and callerid */
05447             stringp=exten2 +1;
05448             s1 = strsep(&stringp, "#");
05449             s2 = strsep(&stringp, "#");
05450             if (s2 && (*(s2 + 1) == '0')) {
05451                if(*(s2 + 2))
05452                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05453             }
05454             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05455             else ast_copy_string(exten, "911", sizeof(exten));
05456             printf("E911: exten: %s, ANI: %s\n",exten, chan->cid.cid_ani);
05457          } else
05458             ast_log(LOG_WARNING, "Got a non-E911 input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05459       }
05460       if (p->sig == SIG_FEATB) {
05461          if (exten[0] == '*') {
05462             char *stringp=NULL;
05463             ast_copy_string(exten2, exten, sizeof(exten2));
05464             /* Parse out extension and callerid */
05465             stringp=exten2 +1;
05466             s1 = strsep(&stringp, "#");
05467             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05468          } else
05469             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05470       }
05471       if (p->sig == SIG_FEATDMF) {
05472          zt_wink(p, index);
05473       }
05474       zt_enable_ec(p);
05475       if (NEED_MFDETECT(p)) {
05476          if (p->dsp) {
05477             if (!p->hardwaredtmf)
05478                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05479             else {
05480                ast_dsp_free(p->dsp);
05481                p->dsp = NULL;
05482             }
05483          }
05484       }
05485 
05486       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05487          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05488          if (p->dsp) ast_dsp_digitreset(p->dsp);
05489          res = ast_pbx_run(chan);
05490          if (res) {
05491             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05492             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05493          }
05494          return NULL;
05495       } else {
05496          if (option_verbose > 2)
05497             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05498          sleep(2);
05499          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05500          if (res < 0)
05501             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05502          else
05503             sleep(1);
05504          res = ast_streamfile(chan, "ss-noservice", chan->language);
05505          if (res >= 0)
05506             ast_waitstream(chan, "");
05507          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05508          ast_hangup(chan);
05509          return NULL;
05510       }
05511       break;
05512    case SIG_FXOLS:
05513    case SIG_FXOGS:
05514    case SIG_FXOKS:
05515       /* Read the first digit */
05516       timeout = firstdigittimeout;
05517       /* If starting a threeway call, never timeout on the first digit so someone
05518          can use flash-hook as a "hold" feature */
05519       if (p->subs[SUB_THREEWAY].owner) 
05520          timeout = 999999;
05521       while(len < AST_MAX_EXTENSION-1) {
05522          /* Read digit unless it's supposed to be immediate, in which case the
05523             only answer is 's' */
05524          if (p->immediate) 
05525             res = 's';
05526          else
05527             res = ast_waitfordigit(chan, timeout);
05528          timeout = 0;
05529          if (res < 0) {
05530             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05531             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05532             ast_hangup(chan);
05533             return NULL;
05534          } else if (res)  {
05535             exten[len++]=res;
05536             exten[len] = '\0';
05537          }
05538          if (!ast_ignore_pattern(chan->context, exten))
05539             tone_zone_play_tone(p->subs[index].zfd, -1);
05540          else
05541             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05542          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05543             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05544                if (getforward) {
05545                   /* Record this as the forwarding extension */
05546                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05547                   if (option_verbose > 2)
05548                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05549                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05550                   if (res)
05551                      break;
05552                   usleep(500000);
05553                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05554                   sleep(1);
05555                   memset(exten, 0, sizeof(exten));
05556                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05557                   len = 0;
05558                   getforward = 0;
05559                } else  {
05560                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05561                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05562                   if (!ast_strlen_zero(p->cid_num)) {
05563                      if (!p->hidecallerid)
05564                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
05565                      else
05566                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
05567                   }
05568                   if (!ast_strlen_zero(p->cid_name)) {
05569                      if (!p->hidecallerid)
05570                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
05571                   }
05572                   ast_setstate(chan, AST_STATE_RING);
05573                   zt_enable_ec(p);
05574                   res = ast_pbx_run(chan);
05575                   if (res) {
05576                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
05577                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05578                   }
05579                   return NULL;
05580                }
05581             } else {
05582                /* It's a match, but they just typed a digit, and there is an ambiguous match,
05583                   so just set the timeout to matchdigittimeout and wait some more */
05584                timeout = matchdigittimeout;
05585             }
05586          } else if (res == 0) {
05587             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
05588             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05589             zt_wait_event(p->subs[index].zfd);
05590             ast_hangup(chan);
05591             return NULL;
05592          } else if (p->callwaiting && !strcmp(exten, "*70")) {
05593             if (option_verbose > 2) 
05594                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
05595             /* Disable call waiting if enabled */
05596             p->callwaiting = 0;
05597             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05598             if (res) {
05599                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05600                   chan->name, strerror(errno));
05601             }
05602             len = 0;
05603             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
05604             memset(exten, 0, sizeof(exten));
05605             timeout = firstdigittimeout;
05606                
05607          } else if (!strcmp(exten,ast_pickup_ext())) {
05608             /* Scan all channels and see if any there
05609              * ringing channqels with that have call groups
05610              * that equal this channels pickup group  
05611              */
05612             if (index == SUB_REAL) {
05613                /* Switch us from Third call to Call Wait */
05614                if (p->subs[SUB_THREEWAY].owner) {
05615                   /* If you make a threeway call and the *8# a call, it should actually 
05616                      look like a callwait */
05617                   alloc_sub(p, SUB_CALLWAIT);   
05618                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
05619                   unalloc_sub(p, SUB_THREEWAY);
05620                }
05621                zt_enable_ec(p);
05622                if (ast_pickup_call(chan)) {
05623                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
05624                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05625                   zt_wait_event(p->subs[index].zfd);
05626                }
05627                ast_hangup(chan);
05628                return NULL;
05629             } else {
05630                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
05631                ast_hangup(chan);
05632                return NULL;
05633             }
05634             
05635          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
05636             if (option_verbose > 2) 
05637                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
05638             /* Disable Caller*ID if enabled */
05639             p->hidecallerid = 1;
05640             if (chan->cid.cid_num)
05641                free(chan->cid.cid_num);
05642             chan->cid.cid_num = NULL;
05643             if (chan->cid.cid_name)
05644                free(chan->cid.cid_name);
05645             chan->cid.cid_name = NULL;
05646             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05647             if (res) {
05648                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05649                   chan->name, strerror(errno));
05650             }
05651             len = 0;
05652             memset(exten, 0, sizeof(exten));
05653             timeout = firstdigittimeout;
05654          } else if (p->callreturn && !strcmp(exten, "*69")) {
05655             res = 0;
05656             if (!ast_strlen_zero(p->lastcid_num)) {
05657                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
05658             }
05659             if (!res)
05660                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05661             break;
05662          } else if (!strcmp(exten, "*78")) {
05663             /* Do not disturb */
05664             if (option_verbose > 2) {
05665                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
05666             }
05667             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05668                      "Channel: Zap/%d\r\n"
05669                      "Status: enabled\r\n", p->channel);
05670             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05671             p->dnd = 1;
05672             getforward = 0;
05673             memset(exten, 0, sizeof(exten));
05674             len = 0;
05675          } else if (!strcmp(exten, "*79")) {
05676             /* Do not disturb */
05677             if (option_verbose > 2)
05678                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
05679             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05680                         "Channel: Zap/%d\r\n"
05681                         "Status: disabled\r\n", p->channel);
05682             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05683             p->dnd = 0;
05684             getforward = 0;
05685             memset(exten, 0, sizeof(exten));
05686             len = 0;
05687          } else if (p->cancallforward && !strcmp(exten, "*72")) {
05688             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05689             getforward = 1;
05690             memset(exten, 0, sizeof(exten));
05691             len = 0;
05692          } else if (p->cancallforward && !strcmp(exten, "*73")) {
05693             if (option_verbose > 2)
05694                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
05695             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05696             memset(p->call_forward, 0, sizeof(p->call_forward));
05697             getforward = 0;
05698             memset(exten, 0, sizeof(exten));
05699             len = 0;
05700          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
05701                   p->subs[SUB_THREEWAY].owner &&
05702                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05703             /* This is a three way call, the main call being a real channel, 
05704                and we're parking the first call. */
05705             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
05706             if (option_verbose > 2)
05707                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
05708             break;
05709          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
05710             if (option_verbose > 2)
05711                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
05712             res = ast_db_put("blacklist", p->lastcid_num, "1");
05713             if (!res) {
05714                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05715                memset(exten, 0, sizeof(exten));
05716                len = 0;
05717             }
05718          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
05719             if (option_verbose > 2) 
05720                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
05721             /* Enable Caller*ID if enabled */
05722             p->hidecallerid = 0;
05723             if (chan->cid.cid_num)
05724                free(chan->cid.cid_num);
05725             chan->cid.cid_num = NULL;
05726             if (chan->cid.cid_name)
05727                free(chan->cid.cid_name);
05728             chan->cid.cid_name = NULL;
05729             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
05730             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05731             if (res) {
05732                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05733                   chan->name, strerror(errno));
05734             }
05735             len = 0;
05736             memset(exten, 0, sizeof(exten));
05737             timeout = firstdigittimeout;
05738          } else if (!strcmp(exten, "*0")) {
05739             struct ast_channel *nbridge = 
05740                p->subs[SUB_THREEWAY].owner;
05741             struct zt_pvt *pbridge = NULL;
05742               /* set up the private struct of the bridged one, if any */
05743             if (nbridge && ast_bridged_channel(nbridge)) 
05744                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
05745             if (nbridge && pbridge && 
05746                 (!strcmp(nbridge->type,"Zap")) && 
05747                (!strcmp(ast_bridged_channel(nbridge)->type, "Zap")) &&
05748                 ISTRUNK(pbridge)) {
05749                int func = ZT_FLASH;
05750                /* Clear out the dial buffer */
05751                p->dop.dialstr[0] = '\0';
05752                /* flash hookswitch */
05753                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05754                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05755                      nbridge->name, strerror(errno));
05756                }
05757                swap_subs(p, SUB_REAL, SUB_THREEWAY);
05758                unalloc_sub(p, SUB_THREEWAY);
05759                p->owner = p->subs[SUB_REAL].owner;
05760                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
05761                   ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
05762                ast_hangup(chan);
05763                return NULL;
05764             } else {
05765                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05766                zt_wait_event(p->subs[index].zfd);
05767                tone_zone_play_tone(p->subs[index].zfd, -1);
05768                swap_subs(p, SUB_REAL, SUB_THREEWAY);
05769                unalloc_sub(p, SUB_THREEWAY);
05770                p->owner = p->subs[SUB_REAL].owner;
05771                ast_hangup(chan);
05772                return NULL;
05773             }              
05774          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
05775                      ((exten[0] != '*') || (strlen(exten) > 2))) {
05776             if (option_debug)
05777                ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
05778             break;
05779          }
05780          if (!timeout)
05781             timeout = gendigittimeout;
05782          if (len && !ast_ignore_pattern(chan->context, exten))
05783             tone_zone_play_tone(p->subs[index].zfd, -1);
05784       }
05785       break;
05786    case SIG_FXSLS:
05787    case SIG_FXSGS:
05788    case SIG_FXSKS:
05789 #ifdef ZAPATA_PRI
05790       if (p->pri) {
05791          /* This is a GR-303 trunk actually.  Wait for the first ring... */
05792          struct ast_frame *f;
05793          int res;
05794          time_t start;
05795 
05796          time(&start);
05797          ast_setstate(chan, AST_STATE_RING);
05798          while(time(NULL) < start + 3) {
05799             res = ast_waitfor(chan, 1000);
05800             if (res) {
05801                f = ast_read(chan);
05802                if (!f) {
05803                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
05804                   ast_hangup(chan);
05805                   return NULL;
05806                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
05807                   res = 1;
05808                } else
05809                   res = 0;
05810                ast_frfree(f);
05811                if (res) {
05812                   ast_log(LOG_DEBUG, "Got ring!\n");
05813                   res = 0;
05814                   break;
05815                }
05816             }
05817          }
05818       }
05819 #endif
05820       /* If we're using an X100P in the UK, caller ID needs to be extracted from
05821        * the history buffer */
05822       if (p->use_callerid && p->cid_start == CID_START_USEHIST) {
05823          ast_log(LOG_DEBUG,"Using history buffer to extract UK caller ID\n");
05824          cs = callerid_new(cid_signalling);
05825          if (cs) {
05826             unsigned char cidbuf[16384];
05827             res=0;
05828 
05829             res = zt_get_history(p->subs[index].zfd,cidbuf,sizeof(cidbuf));
05830             if(res<0) {
05831                ast_log(LOG_ERROR,"zt_get_history failed: %s\n", strerror(errno));
05832             } else {
05833                res=callerid_feed(cs,cidbuf,sizeof(cidbuf),AST_LAW(p));
05834                if (res < 0) {
05835                   ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
05836                }
05837             }
05838 
05839             if(res==1) {
05840                callerid_get(cs, &name, &number, &flags);
05841                if (option_debug)
05842                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
05843             }
05844          }
05845          if (p->usedistinctiveringdetection == 1) {
05846 #if 1
05847             bump_gains(p);
05848 #endif            
05849             len = 0;
05850             distMatches = 0;
05851             /* Clear the current ring data array so we dont have old data in it. */
05852             for (receivedRingT=0; receivedRingT < 3; receivedRingT++) {
05853                curRingData[receivedRingT] = 0;
05854             }
05855             receivedRingT = 0;
05856             counter = 0;
05857             counter1 = 0;
05858             /* Check to see if context is what it should be, if not set to be. */
05859             if (strcmp(p->context,p->defcontext) != 0) {
05860                strncpy(p->context, p->defcontext, sizeof(p->context)-1);
05861                strncpy(chan->context,p->defcontext,sizeof(chan->context)-1);
05862             }
05863 
05864             for(;;) {   
05865                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
05866                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
05867                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
05868                   callerid_free(cs);
05869                   ast_hangup(chan);
05870                   return NULL;
05871                }
05872                if (i & ZT_IOMUX_SIGEVENT) {
05873                   res = zt_get_event(p->subs[index].zfd);
05874                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
05875                   res = 0;
05876                   /* Let us detect distinctive ring */
05877 
05878                   curRingData[receivedRingT] = p->ringt;
05879 
05880                   if (p->ringt < ringt_base/2)
05881                      break;
05882                   ++receivedRingT; /* Increment the ringT counter so we can match it against
05883                         values in zapata.conf for distinctive ring */
05884                } else if (i & ZT_IOMUX_READ) {
05885                   res = read(p->subs[index].zfd, buf, sizeof(buf));
05886                   if (res < 0) {
05887                      if (errno != ELAST) {
05888                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
05889                         callerid_free(cs);
05890                         ast_hangup(chan);
05891                         return NULL;
05892                      }
05893                      break;
05894                   }
05895                   if (p->ringt) 
05896                      p->ringt--;
05897                   if (p->ringt == 1) {
05898                      res = -1;
05899                      break;
05900                   }
05901                }
05902             }
05903             if(option_verbose > 2)
05904                /* this only shows up if you have n of the dring patterns filled in */
05905                ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
05906 
05907             for (counter=0; counter < 3; counter++) {
05908                /* Check to see if the rings we received match any of the ones in zapata.conf for this
05909                channel */
05910                distMatches = 0;
05911                for (counter1=0; counter1 < 3; counter1++) {
05912                   if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
05913                   (p->drings.ringnum[counter].ring[counter1]-10)) {
05914                      distMatches++;
05915                   }
05916                }
05917                if (distMatches == 3) {
05918                   /* The ring matches, set the context to whatever is for distinctive ring.. */
05919                   strncpy(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)-1);
05920                   strncpy(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)-1);
05921                   if(option_verbose > 2)
05922                      ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
05923                   break;
05924                }
05925             }
05926          }
05927          /* Restore linear mode (if appropriate) for Caller*ID processing */
05928          zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05929 #if 1
05930          restore_gains(p);
05931 #endif   
05932       }
05933 
05934       /* If we want caller id, we're in a prering state due to a polarity reversal
05935        * and we're set to use a polarity reversal to trigger the start of caller id,
05936        * grab the caller id and wait for ringing to start... */
05937       if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
05938          /* If set to use DTMF CID signalling, listen for DTMF */
05939          if (p->cid_signalling == CID_SIG_DTMF) {
05940             int i = 0;
05941             cs = NULL;
05942             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
05943                "channel %s\n", chan->name);
05944             zt_setlinear(p->subs[index].zfd, 0);
05945             res = 2000;
05946             for (;;) {
05947                struct ast_frame *f;
05948                res = ast_waitfor(chan, res);
05949                if (res <= 0) {
05950                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
05951                      "Exiting simple switch\n");
05952                   ast_hangup(chan);
05953                   return NULL;
05954                } 
05955                f = ast_read(chan);
05956                if (f->frametype == AST_FRAME_DTMF) {
05957                   dtmfbuf[i++] = f->subclass;
05958                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
05959                   res = 2000;
05960                }
05961                ast_frfree(f);
05962                if (chan->_state == AST_STATE_RING ||
05963                    chan->_state == AST_STATE_RINGING) 
05964                   break; /* Got ring */
05965             }
05966             dtmfbuf[i] = 0;
05967             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05968             /* Got cid and ring. */
05969             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
05970             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
05971             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
05972                dtmfcid, flags);
05973             /* If first byte is NULL, we have no cid */
05974             if (dtmfcid[0]) 
05975                number = dtmfcid;
05976             else
05977                number = 0;
05978          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
05979          } else if (p->cid_signalling == CID_SIG_V23) {
05980             cs = callerid_new(p->cid_signalling);
05981             if (cs) {
05982                samples = 0;
05983 #if 1
05984                bump_gains(p);
05985 #endif            
05986                /* Take out of linear mode for Caller*ID processing */
05987                zt_setlinear(p->subs[index].zfd, 0);
05988                
05989                /* First we wait and listen for the Caller*ID */
05990                for(;;) {   
05991                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
05992                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
05993                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
05994                      callerid_free(cs);
05995                      ast_hangup(chan);
05996                      return NULL;
05997                   }
05998                   if (i & ZT_IOMUX_SIGEVENT) {
05999                      res = zt_get_event(p->subs[index].zfd);
06000                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06001                      res = 0;
06002                      break;
06003                   } else if (i & ZT_IOMUX_READ) {
06004                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06005                      if (res < 0) {
06006                         if (errno != ELAST) {
06007                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06008                            callerid_free(cs);
06009                            ast_hangup(chan);
06010                            return NULL;
06011                         }
06012                         break;
06013                      }
06014                      samples += res;
06015                      res = callerid_feed(cs, buf, res, AST_LAW(p));
06016                      if (res < 0) {
06017                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06018                         break;
06019                      } else if (res)
06020                         break;
06021                      else if (samples > (8000 * 10))
06022                         break;
06023                   }
06024                }
06025                if (res == 1) {
06026                   callerid_get(cs, &name, &number, &flags);
06027                   if (option_debug)
06028                      ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06029                }
06030                if (res < 0) {
06031                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06032                }
06033 
06034                /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06035                res = 2000;
06036                for (;;) {
06037                   struct ast_frame *f;
06038                   res = ast_waitfor(chan, res);
06039                   if (res <= 0) {
06040                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06041                         "Exiting simple switch\n");
06042                      ast_hangup(chan);
06043                      return NULL;
06044                   } 
06045                   f = ast_read(chan);
06046                   ast_frfree(f);
06047                   if (chan->_state == AST_STATE_RING ||
06048                       chan->_state == AST_STATE_RINGING) 
06049                      break; /* Got ring */
06050                }
06051    
06052                /* We must have a ring by now, so, if configured, lets try to listen for
06053                 * distinctive ringing */ 
06054                if (p->usedistinctiveringdetection == 1) {
06055                   len = 0;
06056                   distMatches = 0;
06057                   /* Clear the current ring data array so we dont have old data in it. */
06058                   for (receivedRingT=0; receivedRingT < 3; receivedRingT++) {
06059                      curRingData[receivedRingT] = 0;
06060                   }
06061                   receivedRingT = 0;
06062                   counter = 0;
06063                   counter1 = 0;
06064                   /* Check to see if context is what it should be, if not set to be. */
06065                   if (strcmp(p->context,p->defcontext) != 0) {
06066                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06067                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06068                   }
06069       
06070                   for(;;) {   
06071                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06072                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06073                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06074                         callerid_free(cs);
06075                         ast_hangup(chan);
06076                         return NULL;
06077                      }
06078                      if (i & ZT_IOMUX_SIGEVENT) {
06079                         res = zt_get_event(p->subs[index].zfd);
06080                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06081                         res = 0;
06082                         /* Let us detect distinctive ring */
06083       
06084                         curRingData[receivedRingT] = p->ringt;
06085       
06086                         if (p->ringt < p->ringt_base/2)
06087                            break;
06088                         ++receivedRingT; /* Increment the ringT counter so we can match it against
06089                               values in zapata.conf for distinctive ring */
06090                      } else if (i & ZT_IOMUX_READ) {
06091                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06092                         if (res < 0) {
06093                            if (errno != ELAST) {
06094                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06095                               callerid_free(cs);
06096                               ast_hangup(chan);
06097                               return NULL;
06098                            }
06099                            break;
06100                         }
06101                         if (p->ringt) 
06102                            p->ringt--;
06103                         if (p->ringt == 1) {
06104                            res = -1;
06105                            break;
06106                         }
06107                      }
06108                   }
06109                   if(option_verbose > 2)
06110                      /* this only shows up if you have n of the dring patterns filled in */
06111                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06112    
06113                   for (counter=0; counter < 3; counter++) {
06114                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06115                      channel */
06116                      distMatches = 0;
06117                      for (counter1=0; counter1 < 3; counter1++) {
06118                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06119                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06120                            distMatches++;
06121                         }
06122                      }
06123                      if (distMatches == 3) {
06124                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06125                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06126                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06127                         if(option_verbose > 2)
06128                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06129                         break;
06130                      }
06131                   }
06132                }
06133                /* Restore linear mode (if appropriate) for Caller*ID processing */
06134                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06135 #if 1
06136                restore_gains(p);
06137 #endif            
06138             } else
06139                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06140          } else {
06141             ast_log(LOG_WARNING, "Channel %s in prering "
06142                "state, but I have nothing to do. "
06143                "Terminating simple switch, should be "
06144                "restarted by the actual ring.\n", 
06145                chan->name);
06146             ast_hangup(chan);
06147             return NULL;
06148          }
06149       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06150          /* FSK Bell202 callerID */
06151          cs = callerid_new(p->cid_signalling);
06152          if (cs) {
06153 #if 1
06154             bump_gains(p);
06155 #endif            
06156             samples = 0;
06157             len = 0;
06158             distMatches = 0;
06159             /* Clear the current ring data array so we dont have old data in it. */
06160             for (receivedRingT=0; receivedRingT < 3; receivedRingT++) {
06161                curRingData[receivedRingT] = 0;
06162             }
06163             receivedRingT = 0;
06164             counter = 0;
06165             counter1 = 0;
06166             /* Check to see if context is what it should be, if not set to be. */
06167             if (strcmp(p->context,p->defcontext) != 0) {
06168                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06169                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06170             }
06171 
06172             /* Take out of linear mode for Caller*ID processing */
06173             zt_setlinear(p->subs[index].zfd, 0);
06174             for(;;) {   
06175                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06176                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06177                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06178                   callerid_free(cs);
06179                   ast_hangup(chan);
06180                   return NULL;
06181                }
06182                if (i & ZT_IOMUX_SIGEVENT) {
06183                   res = zt_get_event(p->subs[index].zfd);
06184                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06185                   res = 0;
06186                   /* Let us detect callerid when the telco uses distinctive ring */
06187 
06188                   curRingData[receivedRingT] = p->ringt;
06189 
06190                   if (p->ringt < p->ringt_base/2)
06191                      break;
06192                   ++receivedRingT; /* Increment the ringT counter so we can match it against
06193                         values in zapata.conf for distinctive ring */
06194                } else if (i & ZT_IOMUX_READ) {
06195                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06196                   if (res < 0) {
06197                      if (errno != ELAST) {
06198                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06199                         callerid_free(cs);
06200                         ast_hangup(chan);
06201                         return NULL;
06202                      }
06203                      break;
06204                   }
06205                   if (p->ringt) 
06206                      p->ringt--;
06207                   if (p->ringt == 1) {
06208                      res = -1;
06209                      break;
06210                   }
06211                   samples += res;
06212                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06213                   if (res < 0) {
06214                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06215                      break;
06216                   } else if (res)
06217                      break;
06218                   else if (samples > (8000 * 10))
06219                      break;
06220                }
06221             }
06222             if (p->usedistinctiveringdetection == 1) {
06223                if(option_verbose > 2)
06224                   /* this only shows up if you have n of the dring patterns filled in */
06225                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06226 
06227                for (counter=0; counter < 3; counter++) {
06228                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06229                   channel */
06230                   distMatches = 0;
06231                   for (counter1=0; counter1 < 3; counter1++) {
06232                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06233                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06234                         distMatches++;
06235                      }
06236                   }
06237                   if (distMatches == 3) {
06238                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06239                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06240                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06241                      if(option_verbose > 2)
06242                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06243                      break;
06244                   }
06245                }
06246             }
06247             if (res == 1) {
06248                callerid_get(cs, &name, &number, &flags);
06249                if (option_debug)
06250                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06251             }
06252             /* Restore linear mode (if appropriate) for Caller*ID processing */
06253             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06254 #if 1
06255             restore_gains(p);
06256 #endif            
06257             if (res < 0) {
06258                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06259             }
06260          } else
06261             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06262       }
06263       else
06264          cs = NULL;
06265       if (number || name) {
06266           if (chan->cid.cid_num) {
06267          free(chan->cid.cid_num);
06268          chan->cid.cid_num = NULL;
06269           }
06270           if (chan->cid.cid_name) {
06271          free(chan->cid.cid_name);
06272          chan->cid.cid_name = NULL;
06273           }
06274       }
06275       if (number)
06276          ast_shrink_phone_number(number);
06277 
06278       ast_set_callerid(chan, number, name, number);
06279 
06280       if (cs)
06281          callerid_free(cs);
06282       ast_setstate(chan, AST_STATE_RING);
06283       chan->rings = 1;
06284       p->ringt = p->ringt_base;
06285       res = ast_pbx_run(chan);
06286       if (res) {
06287          ast_hangup(chan);
06288          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06289       }
06290       return NULL;
06291    default:
06292       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06293       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06294       if (res < 0)
06295             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06296    }
06297    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06298    if (res < 0)
06299          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06300    ast_hangup(chan);
06301    return NULL;
06302 }

static void swap_subs struct zt_pvt p,
int  a,
int  b
[static]
 

Definition at line 863 of file chan_zap.c.

References ast_log(), zt_subchannel::chan, ast_channel::fds, zt_subchannel::inthreeway, LOG_DEBUG, zt_subchannel::owner, zt_pvt::subs, wakeup_sub(), and zt_subchannel::zfd.

Referenced by attempt_transfer(), ss_thread(), zt_answer(), zt_handle_event(), and zt_hangup().

00864 {
00865    int tchan;
00866    int tinthreeway;
00867    struct ast_channel *towner;
00868 
00869    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00870 
00871    tchan = p->subs[a].chan;
00872    towner = p->subs[a].owner;
00873    tinthreeway = p->subs[a].inthreeway;
00874 
00875    p->subs[a].chan = p->subs[b].chan;
00876    p->subs[a].owner = p->subs[b].owner;
00877    p->subs[a].inthreeway = p->subs[b].inthreeway;
00878 
00879    p->subs[b].chan = tchan;
00880    p->subs[b].owner = towner;
00881    p->subs[b].inthreeway = tinthreeway;
00882 
00883    if (p->subs[a].owner) 
00884       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00885    if (p->subs[b].owner) 
00886       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00887    wakeup_sub(p, a, NULL);
00888    wakeup_sub(p, b, NULL);
00889 }

static int unalloc_sub struct zt_pvt p,
int  x
[static]
 

Definition at line 1000 of file chan_zap.c.

References ast_log(), zt_subchannel::chan, zt_pvt::channel, zt_subchannel::curconf, zt_subchannel::inthreeway, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, zt_subchannel::owner, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::subs, zt_subchannel::zfd, and zt_close().

01001 {
01002    if (!x) {
01003       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
01004       return -1;
01005    }
01006    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
01007    if (p->subs[x].zfd > -1) {
01008       zt_close(p->subs[x].zfd);
01009    }
01010    p->subs[x].zfd = -1;
01011    p->subs[x].linear = 0;
01012    p->subs[x].chan = 0;
01013    p->subs[x].owner = NULL;
01014    p->subs[x].inthreeway = 0;
01015    p->polarity = POLARITY_IDLE;
01016    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01017    return 0;
01018 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 10288 of file chan_zap.c.

References __unload_module(), ast_mutex_destroy(), and lock.

10289 {
10290 #ifdef ZAPATA_PRI    
10291    int y;
10292    for (y=0;y<NUM_SPANS;y++)
10293       ast_mutex_destroy(&pris[y].lock);
10294 #endif
10295    return __unload_module();
10296 }

static int update_conf struct zt_pvt p  )  [static]
 

Definition at line 1330 of file chan_zap.c.

References conf_add(), zt_subchannel::inthreeway, isslavenative(), zt_pvt::subs, and zt_subchannel::zfd.

Referenced by __zt_exception(), zt_bridge(), zt_handle_event(), and zt_hangup().

01331 {
01332    int needconf = 0;
01333    int x;
01334    int useslavenative;
01335    struct zt_pvt *slave = NULL;
01336 
01337    useslavenative = isslavenative(p, &slave);
01338    /* Start with the obvious, general stuff */
01339    for (x=0;x<3;x++) {
01340       /* Look for three way calls */
01341       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01342          conf_add(p, &p->subs[x], x, 0);
01343          needconf++;
01344       } else {
01345          conf_del(p, &p->subs[x], x);
01346       }
01347    }
01348    /* If we have a slave, add him to our conference now. or DAX
01349       if this is slave native */
01350    for (x=0;x<MAX_SLAVES;x++) {
01351       if (p->slaves[x]) {
01352          if (useslavenative)
01353             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01354          else {
01355             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01356             needconf++;
01357          }
01358       }
01359    }
01360    /* If we're supposed to be in there, do so now */
01361    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01362       if (useslavenative)
01363          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01364       else {
01365          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01366          needconf++;
01367       }
01368    }
01369    /* If we have a master, add ourselves to his conference */
01370    if (p->master) {
01371       if (isslavenative(p->master, NULL)) {
01372          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01373       } else {
01374          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01375       }
01376    }
01377    if (!needconf) {
01378       /* Nobody is left (or should be left) in our conference.  
01379          Kill it.  */
01380       p->confno = -1;
01381    }
01382    ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01383    return 0;
01384 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 11249 of file chan_zap.c.

11250 {
11251    return usecnt;
11252 }

static void wakeup_sub struct zt_pvt p,
int  a,
void *  pri
[static]
 

Definition at line 802 of file chan_zap.c.

References AST_FRAME_NULL, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), zt_pvt::lock, ast_channel::lock, zt_subchannel::owner, and zt_pvt::subs.

Referenced by swap_subs().

00804 {
00805    struct ast_frame null = { AST_FRAME_NULL, };
00806 #ifdef ZAPATA_PRI
00807    if (pri)
00808       ast_mutex_unlock(&pri->lock);
00809 #endif         
00810    for (;;) {
00811       if (p->subs[a].owner) {
00812          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00813             ast_mutex_unlock(&p->lock);
00814             usleep(1);
00815             ast_mutex_lock(&p->lock);
00816          } else {
00817             ast_queue_frame(p->subs[a].owner, &null);
00818             ast_mutex_unlock(&p->subs[a].owner->lock);
00819             break;
00820          }
00821       } else
00822          break;
00823    }
00824 #ifdef ZAPATA_PRI
00825    if (pri)
00826       ast_mutex_lock(&pri->lock);
00827 #endif         
00828 }

static int zap_destroy_channel int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 9635 of file chan_zap.c.

References zt_pvt::channel, destroy_channel(), iflist, zt_pvt::next, zt_pvt::prev, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

09636 {
09637    int channel = 0;
09638    struct zt_pvt *tmp = NULL;
09639    struct zt_pvt *prev = NULL;
09640    
09641    if (argc != 4) {
09642       return RESULT_SHOWUSAGE;
09643    }
09644    channel = atoi(argv[3]);
09645 
09646    tmp = iflist;
09647    while (tmp) {
09648       if (tmp->channel == channel) {
09649          destroy_channel(prev, tmp, 1);
09650          return RESULT_SUCCESS;
09651       }
09652       prev = tmp;
09653       tmp = tmp->next;
09654    }
09655    return RESULT_FAILURE;
09656 }

static int zap_fake_event struct zt_pvt p,
int  mode
[static]
 

Definition at line 10030 of file chan_zap.c.

References ast_log(), zt_pvt::fake_event, HANGUP, ast_channel::name, zt_pvt::owner, and TRANSFER.

Referenced by action_transfer(), and action_transferhangup().

10031 {
10032    if (p) {
10033       switch(mode) {
10034          case TRANSFER:
10035             p->fake_event = ZT_EVENT_WINKFLASH;
10036             break;
10037          case HANGUP:
10038             p->fake_event = ZT_EVENT_ONHOOK;
10039             break;
10040          default:
10041             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10042       }
10043    }
10044    return 0;
10045 }

static void zap_queue_frame struct zt_pvt p,
struct ast_frame f,
void *  pri
[static]
 

Definition at line 833 of file chan_zap.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.

Referenced by action_zapdialoffhook().

00835 {
00836    /* We must unlock the PRI to avoid the possibility of a deadlock */
00837 #ifdef ZAPATA_PRI
00838    if (pri)
00839       ast_mutex_unlock(&pri->lock);
00840 #endif      
00841    for (;;) {
00842       if (p->owner) {
00843          if (ast_mutex_trylock(&p->owner->lock)) {
00844             ast_mutex_unlock(&p->lock);
00845             usleep(1);
00846             ast_mutex_lock(&p->lock);
00847          } else {
00848             ast_queue_frame(p->owner, f);
00849             ast_mutex_unlock(&p->owner->lock);
00850             break;
00851          }
00852       } else
00853          break;
00854    }
00855 #ifdef ZAPATA_PRI
00856    if (pri)
00857       ast_mutex_lock(&pri->lock);
00858 #endif      
00859 }

static int zap_restart void   )  [static]
 

Definition at line 9659 of file chan_zap.c.

References ast_log(), ast_verbose(), destroy_channel(), iflist, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.

Referenced by action_zaprestart(), and zap_restart_cmd().

09660 {
09661    if (option_verbose > 0)
09662       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09663    while (iflist) {
09664       if (option_debug)
09665          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09666       /* Also updates iflist: */
09667       destroy_channel(NULL, iflist, 1);
09668    }
09669    if (option_debug)
09670       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09671    if (setup_zap(0) != 0) {
09672       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09673       return 1;
09674    }
09675    return 0;
09676 }

static int zap_restart_cmd int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 9678 of file chan_zap.c.

References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().

09679 {
09680    if (argc != 2) {
09681       return RESULT_SHOWUSAGE;
09682    }
09683 
09684    if (zap_restart() != 0)
09685       return RESULT_FAILURE;
09686    return RESULT_SUCCESS;
09687 }

static int zap_show_channel int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 9760 of file chan_zap.c.

References iflist, lock, and RESULT_SHOWUSAGE.

09761 {
09762    int channel;
09763    struct zt_pvt *tmp = NULL;
09764    ZT_CONFINFO ci;
09765    ZT_PARAMS ps;
09766    int x;
09767    ast_mutex_t *lock;
09768    struct zt_pvt *start;
09769 #ifdef ZAPATA_PRI
09770    char *c;
09771    int trunkgroup;
09772    struct zt_pri *pri=NULL;
09773 #endif
09774 
09775    lock = &iflock;
09776    start = iflist;
09777 
09778    if (argc != 4)
09779       return RESULT_SHOWUSAGE;
09780 #ifdef ZAPATA_PRI
09781    if ((c = strchr(argv[3], ':'))) {
09782       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
09783          return RESULT_SHOWUSAGE;
09784       if ((trunkgroup < 1) || (channel < 1))
09785          return RESULT_SHOWUSAGE;
09786       for (x=0;x<NUM_SPANS;x++) {
09787          if (pris[x].trunkgroup == trunkgroup) {
09788             pri = pris + x;
09789             break;
09790          }
09791       }
09792       if (pri) {
09793          start = pri->crvs;
09794          lock = &pri->lock;
09795       } else {
09796          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09797          return RESULT_FAILURE;
09798       }
09799    } else
09800 #endif
09801       channel = atoi(argv[3]);
09802 
09803    ast_mutex_lock(lock);
09804    tmp = start;
09805    while (tmp) {
09806       if (tmp->channel == channel) {
09807 #ifdef ZAPATA_PRI
09808          if (pri) 
09809             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
09810          else
09811 #endif         
09812          ast_cli(fd, "Channel: %d\n", tmp->channel);
09813          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
09814          ast_cli(fd, "Span: %d\n", tmp->span);
09815          ast_cli(fd, "Extension: %s\n", tmp->exten);
09816          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
09817          ast_cli(fd, "Context: %s\n", tmp->context);
09818          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
09819          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
09820          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
09821          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
09822          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
09823          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
09824          ast_cli(fd, "Radio: %d\n", tmp->radio);
09825          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
09826          ast_cli(fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? tmp->subs[SUB_REAL].owner->name : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
09827          ast_cli(fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? tmp->subs[SUB_CALLWAIT].owner->name : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
09828          ast_cli(fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? tmp->subs[SUB_THREEWAY].owner->name : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
09829          ast_cli(fd, "Confno: %d\n", tmp->confno);
09830          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
09831          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
09832          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
09833          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
09834          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
09835          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
09836          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
09837          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
09838          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
09839          if (tmp->master)
09840             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
09841          for (x=0;x<MAX_SLAVES;x++) {
09842             if (tmp->slaves[x])
09843                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
09844          }
09845 #ifdef ZAPATA_PRI
09846          if (tmp->pri) {
09847             ast_cli(fd, "PRI Flags: ");
09848             if (tmp->resetting)
09849                ast_cli(fd, "Resetting ");
09850             if (tmp->call)
09851                ast_cli(fd, "Call ");
09852             if (tmp->bearer)
09853                ast_cli(fd, "Bearer ");
09854             ast_cli(fd, "\n");
09855             if (tmp->logicalspan) 
09856                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
09857             else
09858                ast_cli(fd, "PRI Logical Span: Implicit\n");
09859          }
09860             
09861 #endif
09862 #ifdef ZAPATA_R2
09863          if (tmp->r2) {
09864             ast_cli(fd, "R2 Flags: ");
09865             if (tmp->r2blocked)
09866                ast_cli(fd, "Blocked ");
09867             if (tmp->hasr2call)
09868                ast_cli(fd, "Call ");
09869             ast_cli(fd, "\n");
09870          }
09871 #endif
09872          memset(&ci, 0, sizeof(ci));
09873          ps.channo = tmp->channel;
09874          if (tmp->subs[SUB_REAL].zfd > -1) {
09875             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
09876                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
09877             }
09878 #ifdef ZT_GETCONFMUTE
09879             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
09880                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
09881             }
09882 #endif
09883             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
09884                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
09885             } else {
09886                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
09887             }
09888          }
09889          ast_mutex_unlock(lock);
09890          return RESULT_SUCCESS;
09891       }
09892       tmp = tmp->next;
09893    }
09894    
09895    ast_cli(fd, "Unable to find given channel %d\n", channel);
09896    ast_mutex_unlock(lock);
09897    return RESULT_FAILURE;
09898 }

static int zap_show_channels int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 9699 of file chan_zap.c.

References iflist, lock, and RESULT_SHOWUSAGE.

09700 {
09701 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09702 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09703    struct zt_pvt *tmp = NULL;
09704    char tmps[20] = "";
09705    ast_mutex_t *lock;
09706    struct zt_pvt *start;
09707 #ifdef ZAPATA_PRI
09708    int trunkgroup;
09709    struct zt_pri *pri=NULL;
09710    int x;
09711 #endif
09712 
09713    lock = &iflock;
09714    start = iflist;
09715 
09716 #ifdef ZAPATA_PRI
09717    if (argc == 4) {
09718       if ((trunkgroup = atoi(argv[3])) < 1)
09719          return RESULT_SHOWUSAGE;
09720       for (x=0;x<NUM_SPANS;x++) {
09721          if (pris[x].trunkgroup == trunkgroup) {
09722             pri = pris + x;
09723             break;
09724          }
09725       }
09726       if (pri) {
09727          start = pri->crvs;
09728          lock = &pri->lock;
09729       } else {
09730          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09731          return RESULT_FAILURE;
09732       }
09733    } else
09734 #endif
09735    if (argc != 3)
09736       return RESULT_SHOWUSAGE;
09737 
09738    ast_mutex_lock(lock);
09739 #ifdef ZAPATA_PRI
09740    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MusicOnHold");
09741 #else
09742    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MusicOnHold");
09743 #endif   
09744    
09745    tmp = start;
09746    while (tmp) {
09747       if (tmp->channel > 0) {
09748          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09749       } else
09750          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09751       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->musicclass);
09752       tmp = tmp->next;
09753    }
09754    ast_mutex_unlock(lock);
09755    return RESULT_SUCCESS;
09756 #undef FORMAT
09757 #undef FORMAT2
09758 }

static int zap_show_status int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 9931 of file chan_zap.c.

References alarms, ast_cli(), FORMAT2, and RESULT_FAILURE.

09931                                                            {
09932    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
09933    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
09934 
09935    int span;
09936    int res;
09937    char alarms[50];
09938 
09939    int ctl;
09940    ZT_SPANINFO s;
09941 
09942    ctl = open("/dev/zap/ctl", O_RDWR);
09943    if (ctl < 0) {
09944       fprintf(stderr, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
09945       ast_cli(fd, "No Zaptel interface found.\n");
09946       return RESULT_FAILURE;
09947    }
09948    ast_cli(fd,FORMAT2, "Description", "Alarms","IRQ","bpviol","CRC4");
09949 
09950    for (span=1;span < ZT_MAX_SPANS;++span) {
09951       s.spanno = span;
09952       res = ioctl(ctl, ZT_SPANSTAT, &s);
09953       if (res) {
09954          continue;
09955       }
09956       alarms[0] = '\0';
09957       if (s.alarms > 0) {
09958          if (s.alarms & ZT_ALARM_BLUE)
09959             strcat(alarms,"BLU/");
09960          if (s.alarms & ZT_ALARM_YELLOW)
09961             strcat(alarms, "YEL/");
09962          if (s.alarms & ZT_ALARM_RED)
09963             strcat(alarms, "RED/");
09964          if (s.alarms & ZT_ALARM_LOOPBACK)
09965             strcat(alarms,"LB/");
09966          if (s.alarms & ZT_ALARM_RECOVER)
09967             strcat(alarms,"REC/");
09968          if (s.alarms & ZT_ALARM_NOTOPEN)
09969             strcat(alarms, "NOP/");
09970          if (!strlen(alarms))
09971             strcat(alarms, "UUU/");
09972          if (strlen(alarms)) {
09973             /* Strip trailing / */
09974             alarms[strlen(alarms)-1]='\0';
09975          }
09976       } else {
09977          if (s.numchans)
09978             strcpy(alarms, "OK");
09979          else
09980             strcpy(alarms, "UNCONFIGURED");
09981       }
09982 
09983       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
09984    }
09985    close(ctl);
09986 
09987    return RESULT_SUCCESS;
09988 #undef FORMAT
09989 #undef FORMAT2
09990 }

static char* zap_sig2str int  sig  )  [static]
 

Definition at line 1142 of file chan_zap.c.

References SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.

01143 {
01144    static char buf[256];
01145    switch(sig) {
01146    case SIG_EM:
01147       return "E & M Immediate";
01148    case SIG_EMWINK:
01149       return "E & M Wink";
01150    case SIG_EM_E1:
01151       return "E & M E1";
01152    case SIG_FEATD:
01153       return "Feature Group D (DTMF)";
01154    case SIG_FEATDMF:
01155       return "Feature Group D (MF)";
01156    case SIG_FEATDMF_TA:
01157       return "Feature Groud D (MF) Tandem Access";
01158    case SIG_FEATB:
01159       return "Feature Group B (MF)";
01160    case SIG_E911:
01161       return "E911 (MF)";
01162    case SIG_FXSLS:
01163       return "FXS Loopstart";
01164    case SIG_FXSGS:
01165       return "FXS Groundstart";
01166    case SIG_FXSKS:
01167       return "FXS Kewlstart";
01168    case SIG_FXOLS:
01169       return "FXO Loopstart";
01170    case SIG_FXOGS:
01171       return "FXO Groundstart";
01172    case SIG_FXOKS:
01173       return "FXO Kewlstart";
01174    case SIG_PRI:
01175       return "PRI Signalling";
01176    case SIG_R2:
01177       return "R2 Signalling";
01178    case SIG_SF:
01179       return "SF (Tone) Signalling Immediate";
01180    case SIG_SFWINK:
01181       return "SF (Tone) Signalling Wink";
01182    case SIG_SF_FEATD:
01183       return "SF (Tone) Signalling with Feature Group D (DTMF)";
01184    case SIG_SF_FEATDMF:
01185       return "SF (Tone) Signalling with Feature Group D (MF)";
01186    case SIG_SF_FEATB:
01187       return "SF (Tone) Signalling with Feature Group B (MF)";
01188    case SIG_GR303FXOKS:
01189       return "GR-303 Signalling with FXOKS";
01190    case SIG_GR303FXSKS:
01191       return "GR-303 Signalling with FXSKS";
01192    case 0:
01193       return "Pseudo Signalling";
01194    default:
01195       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01196       return buf;
01197    }
01198 }

static int zt_answer struct ast_channel ast  )  [static]
 

Definition at line 2647 of file chan_zap.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().

02648 {
02649    struct zt_pvt *p = ast->tech_pvt;
02650    int res=0;
02651    int index;
02652    int oldstate = ast->_state;
02653    ast_setstate(ast, AST_STATE_UP);
02654    ast_mutex_lock(&p->lock);
02655    index = zt_get_index(ast, p, 0);
02656    if (index < 0)
02657       index = SUB_REAL;
02658    /* nothing to do if a radio channel */
02659    if (p->radio) {
02660       ast_mutex_unlock(&p->lock);
02661       return 0;
02662    }
02663    switch(p->sig) {
02664    case SIG_FXSLS:
02665    case SIG_FXSGS:
02666    case SIG_FXSKS:
02667       p->ringt = 0;
02668       /* Fall through */
02669    case SIG_EM:
02670    case SIG_EM_E1:
02671    case SIG_EMWINK:
02672    case SIG_FEATD:
02673    case SIG_FEATDMF:
02674    case SIG_E911:
02675    case SIG_FEATB:
02676    case SIG_SF:
02677    case SIG_SFWINK:
02678    case SIG_SF_FEATD:
02679    case SIG_SF_FEATDMF:
02680    case SIG_SF_FEATB:
02681    case SIG_FXOLS:
02682    case SIG_FXOGS:
02683    case SIG_FXOKS:
02684       /* Pick up the line */
02685       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02686       if(p->hanguponpolarityswitch) {
02687          gettimeofday(&p->polaritydelaytv, NULL);
02688       }
02689       res =  zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02690       tone_zone_play_tone(p->subs[index].zfd, -1);
02691       p->dialing = 0;
02692       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02693          if (oldstate == AST_STATE_RINGING) {
02694             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02695             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02696             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02697             p->owner = p->subs[SUB_REAL].owner;
02698          }
02699       }
02700       if (p->sig & __ZT_SIG_FXS) {
02701          zt_enable_ec(p);
02702          zt_train_ec(p);
02703       }
02704       break;
02705 #ifdef ZAPATA_PRI
02706    case SIG_PRI:
02707       /* Send a pri acknowledge */
02708       if (!pri_grab(p, p->pri)) {
02709          p->proceeding = 1;
02710          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02711          pri_rel(p->pri);
02712       } else {
02713          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02714          res= -1;
02715       }
02716       break;
02717 #endif
02718 #ifdef ZAPATA_R2
02719    case SIG_R2:
02720       res = mfcr2_AnswerCall(p->r2, NULL);
02721       if (res)
02722          ast_log(LOG_WARNING, "R2 Answer call failed :( on %s\n", ast->name);
02723       break;
02724 #endif         
02725    case 0:
02726       ast_mutex_unlock(&p->lock);
02727       return 0;
02728    default:
02729       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02730       res = -1;
02731    }
02732    ast_mutex_unlock(&p->lock);
02733    return res;
02734 }

static enum ast_bridge_result zt_bridge struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
int  timeoutms
[static]
 

Definition at line 3004 of file chan_zap.c.

References ast_channel::_state, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), AST_STATE_RINGING, ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, ast_channel::fds, ast_frame::frametype, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, master, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), and zt_link().

03005 {
03006    struct ast_channel *who;
03007    struct zt_pvt *p0, *p1, *op0, *op1;
03008    struct zt_pvt *master = NULL, *slave = NULL;
03009    struct ast_frame *f;
03010    int inconf = 0;
03011    int nothingok = 1;
03012    int ofd0, ofd1;
03013    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03014    int os0 = -1, os1 = -1;
03015    int priority = 0;
03016    struct ast_channel *oc0, *oc1;
03017    enum ast_bridge_result res;
03018 
03019 #ifdef PRI_2BCT
03020    int triedtopribridge = 0;
03021    q931_call *q931c0 = NULL, *q931c1 = NULL;
03022 #endif
03023 
03024    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03025       There is code below to handle it properly until DTMF is actually seen,
03026       but due to currently unresolved issues it's ignored...
03027    */
03028 
03029    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03030       return AST_BRIDGE_FAILED_NOWARN;
03031 
03032    ast_mutex_lock(&c0->lock);
03033    ast_mutex_lock(&c1->lock);
03034 
03035    p0 = c0->tech_pvt;
03036    p1 = c1->tech_pvt;
03037    /* cant do pseudo-channels here */
03038    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03039       ast_mutex_unlock(&c0->lock);
03040       ast_mutex_unlock(&c1->lock);
03041       return AST_BRIDGE_FAILED_NOWARN;
03042    }
03043 
03044    oi0 = zt_get_index(c0, p0, 0);
03045    oi1 = zt_get_index(c1, p1, 0);
03046    if ((oi0 < 0) || (oi1 < 0)) {
03047       ast_mutex_unlock(&c0->lock);
03048       ast_mutex_unlock(&c1->lock);
03049       return AST_BRIDGE_FAILED;
03050    }
03051 
03052    op0 = p0 = c0->tech_pvt;
03053    op1 = p1 = c1->tech_pvt;
03054    ofd0 = c0->fds[0];
03055    ofd1 = c1->fds[0];
03056    oc0 = p0->owner;
03057    oc1 = p1->owner;
03058 
03059    ast_mutex_lock(&p0->lock);
03060    if (ast_mutex_trylock(&p1->lock)) {
03061       /* Don't block, due to potential for deadlock */
03062       ast_mutex_unlock(&p0->lock);
03063       ast_mutex_unlock(&c0->lock);
03064       ast_mutex_unlock(&c1->lock);
03065       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03066       return AST_BRIDGE_RETRY;
03067    }
03068 
03069    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03070       if (p0->owner && p1->owner) {
03071          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03072          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03073             master = p0;
03074             slave = p1;
03075             inconf = 1;
03076          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03077             master = p1;
03078             slave = p0;
03079             inconf = 1;
03080          } else {
03081             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03082             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03083                p0->channel,
03084                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03085                p0->subs[SUB_REAL].inthreeway, p0->channel,
03086                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03087                p1->subs[SUB_REAL].inthreeway);
03088          }
03089          nothingok = 0;
03090       }
03091    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03092       if (p1->subs[SUB_THREEWAY].inthreeway) {
03093          master = p1;
03094          slave = p0;
03095          nothingok = 0;
03096       }
03097    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03098       if (p0->subs[SUB_THREEWAY].inthreeway) {
03099          master = p0;
03100          slave = p1;
03101          nothingok = 0;
03102       }
03103    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03104       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03105          don't put us in anything */
03106       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03107          master = p1;
03108          slave = p0;
03109          nothingok = 0;
03110       }
03111    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03112       /* Same as previous */
03113       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03114          master = p0;
03115          slave = p1;
03116          nothingok = 0;
03117       }
03118    }
03119    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03120       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03121    if (master && slave) {
03122       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03123          in an active threeway call with a channel that is ringing, we should
03124          indicate ringing. */
03125       if ((oi1 == SUB_THREEWAY) && 
03126           p1->subs[SUB_THREEWAY].inthreeway && 
03127           p1->subs[SUB_REAL].owner && 
03128           p1->subs[SUB_REAL].inthreeway && 
03129           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03130          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03131          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03132          os1 = p1->subs[SUB_REAL].owner->_state;
03133       } else {
03134          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03135          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03136       }
03137       if ((oi0 == SUB_THREEWAY) && 
03138           p0->subs[SUB_THREEWAY].inthreeway && 
03139           p0->subs[SUB_REAL].owner && 
03140           p0->subs[SUB_REAL].inthreeway && 
03141           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03142          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03143          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03144          os0 = p0->subs[SUB_REAL].owner->_state;
03145       } else {
03146          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03147          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03148       }
03149       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03150          if (!p0->echocanbridged || !p1->echocanbridged) {
03151             /* Disable echo cancellation if appropriate */
03152             zt_disable_ec(p0);
03153             zt_disable_ec(p1);
03154          }
03155       }
03156       zt_link(slave, master);
03157       master->inconference = inconf;
03158    } else if (!nothingok)
03159       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03160 
03161    update_conf(p0);
03162    update_conf(p1);
03163    t0 = p0->subs[SUB_REAL].inthreeway;
03164    t1 = p1->subs[SUB_REAL].inthreeway;
03165 
03166    ast_mutex_unlock(&p0->lock);
03167    ast_mutex_unlock(&p1->lock);
03168 
03169    ast_mutex_unlock(&c0->lock);
03170    ast_mutex_unlock(&c1->lock);
03171 
03172    /* Native bridge failed */
03173    if ((!master || !slave) && !nothingok) {
03174       zt_enable_ec(p0);
03175       zt_enable_ec(p1);
03176       return AST_BRIDGE_FAILED;
03177    }
03178    
03179    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03180       disable_dtmf_detect(op0);
03181 
03182    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03183       disable_dtmf_detect(op1);
03184 
03185    for (;;) {
03186       struct ast_channel *c0_priority[2] = {c0, c1};
03187       struct ast_channel *c1_priority[2] = {c1, c0};
03188 
03189       /* Here's our main loop...  Start by locking things, looking for private parts, 
03190          and then balking if anything is wrong */
03191       ast_mutex_lock(&c0->lock);
03192       ast_mutex_lock(&c1->lock);
03193       p0 = c0->tech_pvt;
03194       p1 = c1->tech_pvt;
03195 
03196       if (op0 == p0)
03197          i0 = zt_get_index(c0, p0, 1);
03198       if (op1 == p1)
03199          i1 = zt_get_index(c1, p1, 1);
03200       ast_mutex_unlock(&c0->lock);
03201       ast_mutex_unlock(&c1->lock);
03202 
03203       if (!timeoutms || 
03204           (op0 != p0) ||
03205           (op1 != p1) || 
03206           (ofd0 != c0->fds[0]) || 
03207           (ofd1 != c1->fds[0]) ||
03208           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03209           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03210           (oc0 != p0->owner) || 
03211           (oc1 != p1->owner) ||
03212           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03213           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03214           (oi0 != i0) ||
03215           (oi1 != i1)) {
03216          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03217             op0->channel, oi0, op1->channel, oi1);
03218          res = AST_BRIDGE_RETRY;
03219          goto return_from_bridge;
03220       }
03221 
03222 #ifdef PRI_2BCT
03223       q931c0 = p0->call;
03224       q931c1 = p1->call;
03225       if (p0->transfer && p1->transfer 
03226           && q931c0 && q931c1 
03227           && !triedtopribridge) {
03228          pri_channel_bridge(q931c0, q931c1);
03229          triedtopribridge = 1;
03230       }
03231 #endif
03232 
03233       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03234       if (!who) {
03235          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03236          continue;
03237       }
03238       f = ast_read(who);
03239       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03240          *fo = f;
03241          *rc = who;
03242          res = AST_BRIDGE_COMPLETE;
03243          goto return_from_bridge;
03244       }
03245       if (f->frametype == AST_FRAME_DTMF) {
03246          if ((who == c0) && p0->pulsedial) {
03247             ast_write(c1, f);
03248          } else if ((who == c1) && p1->pulsedial) {
03249             ast_write(c0, f);
03250          } else {
03251             *fo = f;
03252             *rc = who;
03253             res = AST_BRIDGE_COMPLETE;
03254             goto return_from_bridge;
03255          }
03256       }
03257       ast_frfree(f);
03258       
03259       /* Swap who gets priority */
03260       priority = !priority;
03261    }
03262 
03263 return_from_bridge:
03264    if (op0 == p0)
03265       zt_enable_ec(p0);
03266 
03267    if (op1 == p1)
03268       zt_enable_ec(p1);
03269 
03270    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03271       enable_dtmf_detect(op0);
03272 
03273    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03274       enable_dtmf_detect(op1);
03275 
03276    zt_unlink(slave, master, 1);
03277 
03278    return res;
03279 }

static int zt_call struct ast_channel ast,
char *  rdest,
int  timeout
[static]
 

Definition at line 1749 of file chan_zap.c.

References ast_channel::_state, ast_callerid_generate(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::callwaitrings, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, zt_pvt::finaldial, free, zt_pvt::hidecallerid, IS_DIGITAL, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_pvt::law, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, malloc, MAX_CALLERID_SIZE, n, ast_channel::name, zt_subchannel::needbusy, zt_subchannel::needringing, option_verbose, zt_pvt::outgoing, zt_pvt::owner, pbx_builtin_getvar_helper(), zt_pvt::priexclusive, zt_pvt::pulse, zt_pvt::radio, zt_pvt::rxgain, s, send_callerid(), zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::stripmsd, SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, ast_channel::transfercapability, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_subchannel::zfd, zt_callwait(), and zt_get_index().

01750 {
01751    struct zt_pvt *p = ast->tech_pvt;
01752    int x, res, index;
01753    char *c, *n, *l;
01754 #ifdef ZAPATA_PRI
01755    char *s=NULL;
01756 #endif
01757    char dest[256]; /* must be same length as p->dialdest */
01758    ast_mutex_lock(&p->lock);
01759    ast_copy_string(dest, rdest, sizeof(dest));
01760    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01761    if ((ast->_state == AST_STATE_BUSY)) {
01762       p->subs[SUB_REAL].needbusy = 1;
01763       ast_mutex_unlock(&p->lock);
01764       return 0;
01765    }
01766    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01767       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01768       ast_mutex_unlock(&p->lock);
01769       return -1;
01770    }
01771    p->dialednone = 0;
01772    if (p->radio)  /* if a radio channel, up immediately */
01773    {
01774       /* Special pseudo -- automatically up */
01775       ast_setstate(ast, AST_STATE_UP); 
01776       ast_mutex_unlock(&p->lock);
01777       return 0;
01778    }
01779    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01780    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01781    if (res)
01782       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01783    p->outgoing = 1;
01784 
01785    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01786 
01787    switch(p->sig) {
01788    case SIG_FXOLS:
01789    case SIG_FXOGS:
01790    case SIG_FXOKS:
01791       if (p->owner == ast) {
01792          /* Normal ring, on hook */
01793          
01794          /* Don't send audio while on hook, until the call is answered */
01795          p->dialing = 1;
01796          if (p->use_callerid) {
01797             /* Generate the Caller-ID spill if desired */
01798             if (p->cidspill) {
01799                ast_log(LOG_WARNING, "cidspill already exists??\n");
01800                free(p->cidspill);
01801             }
01802             p->cidspill = malloc(MAX_CALLERID_SIZE);
01803             p->callwaitcas = 0;
01804             if (p->cidspill) {
01805                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01806                p->cidpos = 0;
01807                send_callerid(p);
01808             } else
01809                ast_log(LOG_WARNING, "Unable to generate CallerID spill\n");
01810          }
01811          /* Choose proper cadence */
01812          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01813             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering-1]))
01814                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01815             p->cidrings = cidrings[p->distinctivering - 1];
01816          } else {
01817             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01818                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01819             p->cidrings = p->sendcalleridafter;
01820          }
01821 
01822 
01823          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01824          c = strchr(dest, '/');
01825          if (c)
01826             c++;
01827          if (c && (strlen(c) < p->stripmsd)) {
01828             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01829             c = NULL;
01830          }
01831          if (c) {
01832             p->dop.op = ZT_DIAL_OP_REPLACE;
01833             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01834             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01835          } else {
01836             p->dop.dialstr[0] = '\0';
01837          }
01838          x = ZT_RING;
01839          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01840             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01841             ast_mutex_unlock(&p->lock);
01842             return -1;
01843          }
01844          p->dialing = 1;
01845       } else {
01846          /* Call waiting call */
01847          p->callwaitrings = 0;
01848          if (ast->cid.cid_num)
01849             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01850          else
01851             p->callwait_num[0] = '\0';
01852          if (ast->cid.cid_name)
01853             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01854          else
01855             p->callwait_name[0] = '\0';
01856          /* Call waiting tone instead */
01857          if (zt_callwait(ast)) {
01858             ast_mutex_unlock(&p->lock);
01859             return -1;
01860          }
01861          /* Make ring-back */
01862          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01863             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01864             
01865       }
01866       n = ast->cid.cid_name;
01867       l = ast->cid.cid_num;
01868       if (l)
01869          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01870       else
01871          p->lastcid_num[0] = '\0';
01872       if (n)
01873          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01874       else
01875          p->lastcid_name[0] = '\0';
01876       ast_setstate(ast, AST_STATE_RINGING);
01877       index = zt_get_index(ast, p, 0);
01878       if (index > -1) {
01879          p->subs[index].needringing = 1;
01880       }
01881       break;
01882    case SIG_FXSLS:
01883    case SIG_FXSGS:
01884    case SIG_FXSKS:
01885    case SIG_EMWINK:
01886    case SIG_EM:
01887    case SIG_EM_E1:
01888    case SIG_FEATD:
01889    case SIG_FEATDMF:
01890    case SIG_E911:
01891    case SIG_FEATB:
01892    case SIG_SFWINK:
01893    case SIG_SF:
01894    case SIG_SF_FEATD:
01895    case SIG_SF_FEATDMF:
01896    case SIG_FEATDMF_TA:
01897    case SIG_SF_FEATB:
01898       c = strchr(dest, '/');
01899       if (c)
01900          c++;
01901       else
01902          c = "";
01903       if (strlen(c) < p->stripmsd) {
01904          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01905          ast_mutex_unlock(&p->lock);
01906          return -1;
01907       }
01908 #ifdef ZAPATA_PRI
01909       /* Start the trunk, if not GR-303 */
01910       if (!p->pri) {
01911 #endif
01912          x = ZT_START;
01913          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01914          if (res < 0) {
01915             if (errno != EINPROGRESS) {
01916                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
01917                ast_mutex_unlock(&p->lock);
01918                return -1;
01919             }
01920          }
01921 #ifdef ZAPATA_PRI
01922       }
01923 #endif
01924       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
01925       p->dop.op = ZT_DIAL_OP_REPLACE;
01926 
01927       c += p->stripmsd;
01928 
01929       switch (p->sig) {
01930       case SIG_FEATD:
01931          l = ast->cid.cid_num;
01932          if (l) 
01933             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01934          else
01935             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01936          break;
01937       case SIG_FEATDMF:
01938          l = ast->cid.cid_num;
01939          if (l) 
01940             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01941          else
01942             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01943          break;
01944       case SIG_FEATDMF_TA:
01945       {
01946          char *cic = NULL, *ozz = NULL;
01947 
01948          /* If you have to go through a Tandem Access point you need to use this */
01949          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01950          if (!ozz)
01951             ozz = defaultozz;
01952          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01953          if (!cic)
01954             cic = defaultcic;
01955          if (!ozz || !cic) {
01956             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01957             ast_mutex_unlock(&p->lock);
01958             return -1;
01959          }
01960          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01961          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01962          p->whichwink = 0;
01963       }
01964          break;
01965       case SIG_E911:
01966          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01967          break;
01968       case SIG_FEATB:
01969          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
01970          break;
01971       default:
01972          if (p->pulse)
01973             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
01974          else
01975             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
01976          break;
01977       }
01978 
01979       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
01980          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
01981          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
01982          p->echorest[sizeof(p->echorest) - 1] = '\0';
01983          p->echobreak = 1;
01984          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
01985       } else
01986          p->echobreak = 0;
01987       if (!res) {
01988          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
01989             x = ZT_ONHOOK;
01990             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01991             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
01992             ast_mutex_unlock(&p->lock);
01993             return -1;
01994          }
01995       } else
01996          ast_log(LOG_DEBUG, "Deferring dialing...\n");
01997       p->dialing = 1;
01998       if (ast_strlen_zero(c))
01999          p->dialednone = 1;
02000       ast_setstate(ast, AST_STATE_DIALING);
02001       break;
02002    case 0:
02003       /* Special pseudo -- automatically up*/
02004       ast_setstate(ast, AST_STATE_UP);
02005       break;      
02006    case SIG_PRI:
02007       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02008       p->dialdest[0] = '\0';
02009       break;
02010    default:
02011       ast_log(LOG_DEBUG, "not yet implemented\n");
02012       ast_mutex_unlock(&p->lock);
02013       return -1;
02014    }
02015 #ifdef ZAPATA_PRI
02016    if (p->pri) {
02017       struct pri_sr *sr;
02018 #ifdef SUPPORT_USERUSER
02019       char *useruser;
02020 #endif
02021       int pridialplan;
02022       int dp_strip;
02023       int prilocaldialplan;
02024       int ldp_strip;
02025       int exclusive;
02026 
02027       c = strchr(dest, '/');
02028       if (c)
02029          c++;
02030       else
02031          c = dest;
02032       if (!p->hidecallerid) {
02033          l = ast->cid.cid_num;
02034          n = ast->cid.cid_name;
02035       } else {
02036          l = NULL;
02037          n = NULL;
02038       }
02039       if (strlen(c) < p->stripmsd) {
02040          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02041          ast_mutex_unlock(&p->lock);
02042          return -1;
02043       }
02044       if (p->sig != SIG_FXSKS) {
02045          p->dop.op = ZT_DIAL_OP_REPLACE;
02046          s = strchr(c + p->stripmsd, 'w');
02047          if (s) {
02048             if (strlen(s) > 1)
02049                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02050             else
02051                p->dop.dialstr[0] = '\0';
02052             *s = '\0';
02053          } else {
02054             p->dop.dialstr[0] = '\0';
02055          }
02056       }
02057       if (pri_grab(p, p->pri)) {
02058          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02059          ast_mutex_unlock(&p->lock);
02060          return -1;
02061       }
02062       if (!(p->call = pri_new_call(p->pri->pri))) {
02063          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02064          pri_rel(p->pri);
02065          ast_mutex_unlock(&p->lock);
02066          return -1;
02067       }
02068       if (!(sr = pri_sr_new())) {
02069          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02070          pri_rel(p->pri);
02071          ast_mutex_unlock(&p->lock);
02072       }
02073       if (p->bearer || (p->sig == SIG_FXSKS)) {
02074          if (p->bearer) {
02075             ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
02076             p->bearer->call = p->call;
02077          } else
02078             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02079          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02080       }
02081       p->digital = IS_DIGITAL(ast->transfercapability);
02082       /* Add support for exclusive override */
02083       if (p->priexclusive)
02084          exclusive = 1;
02085       else {
02086       /* otherwise, traditional behavior */
02087          if (p->pri->nodetype == PRI_NETWORK)
02088             exclusive = 0;
02089          else
02090             exclusive = 1;
02091       }
02092       
02093       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02094       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02095                (p->digital ? -1 : 
02096                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02097       if (p->pri->facilityenable)
02098          pri_facility_enable(p->pri->pri);
02099 
02100       if (option_verbose > 2)
02101          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02102       dp_strip = 0;
02103       pridialplan = p->pri->dialplan - 1;
02104       if (pridialplan == -2) { /* compute dynamically */
02105          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02106             dp_strip = strlen(p->pri->internationalprefix);
02107             pridialplan = PRI_INTERNATIONAL_ISDN;
02108          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02109             dp_strip = strlen(p->pri->nationalprefix);
02110             pridialplan = PRI_NATIONAL_ISDN;
02111          } else {
02112             pridialplan = PRI_LOCAL_ISDN;
02113          }
02114       }
02115       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan,  s ? 1 : 0);
02116 
02117       ldp_strip = 0;
02118       prilocaldialplan = p->pri->localdialplan - 1;
02119       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02120          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02121             ldp_strip = strlen(p->pri->internationalprefix);
02122             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02123          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02124             ldp_strip = strlen(p->pri->nationalprefix);
02125             prilocaldialplan = PRI_NATIONAL_ISDN;
02126          } else {
02127             prilocaldialplan = PRI_LOCAL_ISDN;
02128          }
02129       }
02130       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 
02131                l ? (p->use_callingpres ? ast->cid.cid_pres : PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN) : 
02132                    PRES_NUMBER_NOT_AVAILABLE);
02133       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL);
02134 
02135 #ifdef SUPPORT_USERUSER
02136       /* User-user info */
02137       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02138 
02139       if (useruser)
02140          pri_sr_set_useruser(sr, useruser);
02141 #endif
02142 
02143       if (pri_setup(p->pri->pri, p->call,  sr)) {
02144          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02145                   c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02146          pri_rel(p->pri);
02147          ast_mutex_unlock(&p->lock);
02148          pri_sr_free(sr);
02149          return -1;
02150       }
02151       pri_sr_free(sr);
02152       ast_setstate(ast, AST_STATE_DIALING);
02153       pri_rel(p->pri);
02154    }
02155 #endif      
02156    ast_mutex_unlock(&p->lock);
02157    return 0;
02158 }

static int zt_callwait struct ast_channel ast  )  [static]
 

Definition at line 1718 of file chan_zap.c.

References ast_gen_cas(), AST_LAW, ast_log(), zt_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, zt_pvt::callwaitingcallerid, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, LOG_WARNING, malloc, READ_SIZE, save_conference(), send_callerid(), and ast_channel::tech_pvt.

Referenced by zt_call(), and zt_read().

01719 {
01720    struct zt_pvt *p = ast->tech_pvt;
01721    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01722    if (p->cidspill) {
01723       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01724       free(p->cidspill);
01725    }
01726    p->cidspill = malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4);
01727    if (p->cidspill) {
01728       save_conference(p);
01729       /* Silence */
01730       memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01731       if (!p->callwaitrings && p->callwaitingcallerid) {
01732          ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01733          p->callwaitcas = 1;
01734          p->cidlen = 2400 + 680 + READ_SIZE * 4;
01735       } else {
01736          ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01737          p->callwaitcas = 0;
01738          p->cidlen = 2400 + READ_SIZE * 4;
01739       }
01740       p->cidpos = 0;
01741       send_callerid(p);
01742    } else {
01743       ast_log(LOG_WARNING, "Unable to create SAS/CAS spill\n");
01744       return -1;
01745    }
01746    return 0;
01747 }

static void zt_close int  fd  )  [static]
 

Definition at line 932 of file chan_zap.c.

Referenced by alloc_sub(), and unalloc_sub().

00933 {
00934    if(fd > 0)
00935       close(fd);
00936 }

static int zt_confmute struct zt_pvt p,
int  muted
[inline, static]
 

Definition at line 1599 of file chan_zap.c.

References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, and zt_pvt::subs.

Referenced by zt_handle_event(), zt_hangup(), zt_new(), and zt_read().

01600 {
01601    int x, y, res;
01602    x = muted;
01603    if (p->sig == SIG_PRI) {
01604       y = 1;
01605       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01606       if (res)
01607          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01608    }
01609    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01610    if (res < 0) 
01611       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01612    return res;
01613 }

static int zt_digit struct ast_channel ast,
char  digit
[static]
 

Definition at line 1020 of file chan_zap.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DIALING, zt_pvt::dialdest, zt_pvt::dialing, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, and zt_get_index().

01021 {
01022    ZT_DIAL_OPERATION zo;
01023    struct zt_pvt *p;
01024    int res = 0;
01025    int index;
01026    p = ast->tech_pvt;
01027    ast_mutex_lock(&p->lock);
01028    index = zt_get_index(ast, p, 0);
01029    if ((index == SUB_REAL) && p->owner) {
01030 #ifdef ZAPATA_PRI
01031       if ((p->sig == SIG_PRI) && (ast->_state == AST_STATE_DIALING) && !p->proceeding) {
01032          if (p->setup_ack) {
01033             if (!pri_grab(p, p->pri)) {
01034                pri_information(p->pri->pri,p->call,digit);
01035                pri_rel(p->pri);
01036             } else
01037                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
01038          } else if (strlen(p->dialdest) < sizeof(p->dialdest) - 1) {
01039             ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01040             res = strlen(p->dialdest);
01041             p->dialdest[res++] = digit;
01042             p->dialdest[res] = '\0';
01043          }
01044       } else {
01045 #else
01046       {
01047 #endif
01048          zo.op = ZT_DIAL_OP_APPEND;
01049          zo.dialstr[0] = 'T';
01050          zo.dialstr[1] = digit;
01051          zo.dialstr[2] = 0;
01052          if ((res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01053             ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01054          else
01055             p->dialing = 1;
01056       }
01057    }
01058    ast_mutex_unlock(&p->lock);
01059    return res;
01060 }

static void zt_disable_ec struct zt_pvt p  )  [static]
 

Definition at line 1435 of file chan_zap.c.

References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, SUB_REAL, and zt_pvt::subs.

Referenced by __zt_exception(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().

01436 {
01437    int x;
01438    int res;
01439    if (p->echocancel) {
01440       x = 0;
01441       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01442       if (res) 
01443          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01444       else
01445          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01446    }
01447    p->echocanon = 0;
01448 }

static void zt_enable_ec struct zt_pvt p  )  [static]
 

Definition at line 1386 of file chan_zap.c.

References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, and zt_pvt::subs.

Referenced by handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), and zt_handle_event().

01387 {
01388    int x;
01389    int res;
01390    if (!p)
01391       return;
01392    if (p->echocanon) {
01393       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01394       return;
01395    }
01396    if (p->digital) {
01397       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01398       return;
01399    }
01400    if (p->echocancel) {
01401       if (p->sig == SIG_PRI) {
01402          x = 1;
01403          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01404          if (res)
01405             ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01406       }
01407       x = p->echocancel;
01408       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01409       if (res) 
01410          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01411       else {
01412          p->echocanon = 1;
01413          ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01414       }
01415    } else
01416       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01417 }

struct ast_frame * zt_exception struct ast_channel ast  ) 
 

Definition at line 4370 of file chan_zap.c.

References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, and ast_channel::tech_pvt.

04371 {
04372    struct zt_pvt *p = ast->tech_pvt;
04373    struct ast_frame *f;
04374    ast_mutex_lock(&p->lock);
04375    f = __zt_exception(ast);
04376    ast_mutex_unlock(&p->lock);
04377    return f;
04378 }

static int zt_fixup struct ast_channel oldchan,
struct ast_channel newchan
[static]
 

Definition at line 3281 of file chan_zap.c.

References ast_log(), ast_mutex_lock(), zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, and zt_unlink().

03282 {
03283    struct zt_pvt *p = newchan->tech_pvt;
03284    int x;
03285    ast_mutex_lock(&p->lock);
03286    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03287    if (p->owner == oldchan) {
03288       p->owner = newchan;
03289    }
03290    for (x=0;x<3;x++)
03291       if (p->subs[x].owner == oldchan) {
03292          if (!x)
03293             zt_unlink(NULL, p, 0);
03294          p->subs[x].owner = newchan;
03295       }
03296    if (newchan->_state == AST_STATE_RINGING) 
03297       zt_indicate(newchan, AST_CONTROL_RINGING);
03298    update_conf(p);
03299    ast_mutex_unlock(&p->lock);
03300    return 0;
03301 }

static int zt_get_event int  fd  )  [inline, static]
 

Avoid the silly zt_getevent which ignores a bunch of events.

Definition at line 361 of file chan_zap.c.

Referenced by __zt_exception(), ss_thread(), and zt_handle_event().

00362 {
00363    int j;
00364    if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
00365    return j;
00366 }

static int zt_get_history int  fd,
void *  buf,
int  buf_size
[static]
 

Definition at line 957 of file chan_zap.c.

Referenced by ss_thread().

00958 {
00959    struct zt_history hist;
00960    hist.buf=buf;
00961    hist.len=buf_size;
00962    return ioctl(fd, ZT_GET_HISTORY, &hist);
00963 }

static int zt_get_index struct ast_channel ast,
struct zt_pvt p,
int  nullok
[static]
 

Definition at line 782 of file chan_zap.c.

References ast_log(), LOG_WARNING, zt_subchannel::owner, and zt_pvt::subs.

Referenced by __zt_exception(), ss_thread(), zt_answer(), zt_bridge(), zt_call(), zt_digit(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), zt_sendtext(), zt_setoption(), and zt_write().

00783 {
00784    int res;
00785    if (p->subs[0].owner == ast)
00786       res = 0;
00787    else if (p->subs[1].owner == ast)
00788       res = 1;
00789    else if (p->subs[2].owner == ast)
00790       res = 2;
00791    else {
00792       res = -1;
00793       if (!nullok)
00794          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00795    }
00796    return res;
00797 }

static struct ast_frame* zt_handle_event struct ast_channel ast  )  [static]
 

Definition at line 3518 of file chan_zap.c.

References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_hangup(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callwaitcas, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, zt_pvt::cid_num, ast_callerid::cid_num, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, zt_pvt::dialdest, zt_pvt::dialing, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, ast_channel::lock, zt_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::msgstate, ast_channel::name, zt_subchannel::needflash, ast_frame::offset, zt_pvt::onhooktime, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::overlapdial, zt_subchannel::owner, zt_pvt::owner, ast_channel::pbx, zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, zt_pvt::polaritydelaytv, zt_pvt::polarityonanswerdelay, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, ast_frame::samples, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), strdup, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::threewaycalling, zt_pvt::transfer, zt_pvt::transfertobusy, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_enable_ec(), ZT_EVENT_DTMFDOWN, ZT_EVENT_DTMFUP, zt_get_event(), zt_get_index(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().

Referenced by __zt_exception().

03519 {
03520    int res,x;
03521    int index;
03522    char *c;
03523    struct zt_pvt *p = ast->tech_pvt;
03524    pthread_t threadid;
03525    pthread_attr_t attr;
03526    struct ast_channel *chan;
03527 
03528    pthread_attr_init(&attr);
03529    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
03530 
03531    index = zt_get_index(ast, p, 0);
03532    p->subs[index].f.frametype = AST_FRAME_NULL;
03533    p->subs[index].f.datalen = 0;
03534    p->subs[index].f.samples = 0;
03535    p->subs[index].f.mallocd = 0;
03536    p->subs[index].f.offset = 0;
03537    p->subs[index].f.src = "zt_handle_event";
03538    p->subs[index].f.data = NULL;
03539    if (index < 0)
03540       return &p->subs[index].f;
03541    if (p->fake_event) {
03542       res = p->fake_event;
03543       p->fake_event = 0;
03544    } else
03545       res = zt_get_event(p->subs[index].zfd);
03546 
03547    ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03548 
03549    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03550       if (res & ZT_EVENT_PULSEDIGIT)
03551          p->pulsedial = 1;
03552       else
03553          p->pulsedial = 0;
03554       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03555 #ifdef ZAPATA_PRI
03556       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03557          p->subs[index].f.frametype = AST_FRAME_NULL;
03558          p->subs[index].f.subclass = 0;
03559       } else {
03560 #endif
03561          p->subs[index].f.frametype = AST_FRAME_DTMF;
03562          p->subs[index].f.subclass = res & 0xff;
03563 #ifdef ZAPATA_PRI
03564       }
03565 #endif
03566       /* Unmute conference, return the captured digit */
03567       zt_confmute(p, 0);
03568       return &p->subs[index].f;
03569    }
03570 
03571    if (res & ZT_EVENT_DTMFDOWN) {
03572       ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03573       p->subs[index].f.frametype = AST_FRAME_NULL;
03574       p->subs[index].f.subclass = 0;
03575       zt_confmute(p, 1);
03576       /* Mute conference, return null frame */
03577       return &p->subs[index].f;
03578    }
03579 
03580    switch(res) {
03581       case ZT_EVENT_BITSCHANGED:
03582          if (p->sig == SIG_R2) {
03583 #ifdef ZAPATA_R2
03584             struct ast_frame  *f = &p->subs[index].f;
03585             mfcr2_event_t *e;
03586             e = r2_get_event_bits(p);
03587             if (e)
03588                f = handle_r2_event(p, e, index);
03589             return f;
03590 #else          
03591             break;
03592 #endif
03593          }
03594          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03595       case ZT_EVENT_PULSE_START:
03596          /* Stop tone if there's a pulse start and the PBX isn't started */
03597          if (!ast->pbx)
03598             tone_zone_play_tone(p->subs[index].zfd, -1);
03599          break;   
03600       case ZT_EVENT_DIALCOMPLETE:
03601          if (p->inalarm) break;
03602          if (p->radio) break;
03603          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03604             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03605             return NULL;
03606          }
03607          if (!x) { /* if not still dialing in driver */
03608             zt_enable_ec(p);
03609             if (p->echobreak) {
03610                zt_train_ec(p);
03611                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03612                p->dop.op = ZT_DIAL_OP_REPLACE;
03613                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03614                p->echobreak = 0;
03615             } else {
03616                p->dialing = 0;
03617                if (p->sig == SIG_E911) {
03618                   /* if thru with dialing after offhook */
03619                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03620                      ast_setstate(ast, AST_STATE_UP);
03621                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03622                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03623                      break;
03624                   } else { /* if to state wait for offhook to dial rest */
03625                      /* we now wait for off hook */
03626                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03627                   }
03628                }
03629                if (ast->_state == AST_STATE_DIALING) {
03630                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03631                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03632                   } else if (p->confirmanswer || (!p->dialednone && ((p->sig == SIG_EM) || (p->sig == SIG_EM_E1) ||  (p->sig == SIG_EMWINK) || (p->sig == SIG_FEATD) || (p->sig == SIG_FEATDMF) || (p->sig == SIG_E911) || (p->sig == SIG_FEATB) || (p->sig == SIG_SF) || (p->sig == SIG_SFWINK) || (p->sig == SIG_SF_FEATD) || (p->sig == SIG_SF_FEATDMF) || (p->sig == SIG_SF_FEATB)))) {
03633                      ast_setstate(ast, AST_STATE_RINGING);
03634                   } else if (!p->answeronpolarityswitch) {
03635                      ast_setstate(ast, AST_STATE_UP);
03636                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03637                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03638                   }
03639                }
03640             }
03641          }
03642          break;
03643       case ZT_EVENT_ALARM:
03644 #ifdef ZAPATA_PRI
03645          if (p->call) {
03646             if (p->pri && p->pri->pri) {
03647                if (!pri_grab(p, p->pri)) {
03648                   pri_hangup(p->pri->pri, p->call, -1);
03649                   pri_destroycall(p->pri->pri, p->call);
03650                   p->call = NULL;
03651                   pri_rel(p->pri);
03652                } else
03653                   ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03654             } else
03655                ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
03656          }
03657          if (p->owner)
03658             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03659          if (p->bearer)
03660             p->bearer->inalarm = 1;
03661          else
03662 #endif
03663          p->inalarm = 1;
03664          res = get_alarms(p);
03665          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res));
03666          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
03667                         "Alarm: %s\r\n"
03668                         "Channel: %d\r\n",
03669                         alarm2str(res), p->channel);
03670          /* fall through intentionally */
03671       case ZT_EVENT_ONHOOK:
03672          if (p->radio)
03673          {
03674             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03675             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
03676             break;
03677          }
03678          switch(p->sig) {
03679          case SIG_FXOLS:
03680          case SIG_FXOGS:
03681          case SIG_FXOKS:
03682             p->onhooktime = time(NULL);
03683             p->msgstate = -1;
03684             /* Check for some special conditions regarding call waiting */
03685             if (index == SUB_REAL) {
03686                /* The normal line was hung up */
03687                if (p->subs[SUB_CALLWAIT].owner) {
03688                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
03689                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03690                   if (option_verbose > 2) 
03691                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
03692                   unalloc_sub(p, SUB_CALLWAIT); 
03693 #if 0
03694                   p->subs[index].needanswer = 0;
03695                   p->subs[index].needringing = 0;
03696 #endif                  
03697                   p->callwaitingrepeat = 0;
03698                   p->cidcwexpire = 0;
03699                   p->owner = NULL;
03700                   /* Don't start streaming audio yet if the incoming call isn't up yet */
03701                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
03702                      p->dialing = 1;
03703                   zt_ring_phone(p);
03704                } else if (p->subs[SUB_THREEWAY].owner) {
03705                   unsigned int mssinceflash;
03706                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
03707                      the private structure -- not especially easy or clean */
03708                   while(p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
03709                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
03710                      ast_mutex_unlock(&p->lock);
03711                      ast_mutex_unlock(&ast->lock);
03712                      usleep(1);
03713                      /* We can grab ast and p in that order, without worry.  We should make sure
03714                         nothing seriously bad has happened though like some sort of bizarre double
03715                         masquerade! */
03716                      ast_mutex_lock(&ast->lock);
03717                      ast_mutex_lock(&p->lock);
03718                      if (p->owner != ast) {
03719                         ast_log(LOG_WARNING, "This isn't good...\n");
03720                         return NULL;
03721                      }
03722                   }
03723                   if (!p->subs[SUB_THREEWAY].owner) {
03724                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
03725                      return NULL;
03726                   }
03727                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
03728                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
03729                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
03730                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
03731                         hanging up.  Hangup both channels now */
03732                      if (p->subs[SUB_THREEWAY].owner)
03733                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
03734                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03735                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
03736                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03737                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
03738                      if (p->transfer) {
03739                         /* In any case this isn't a threeway call anymore */
03740                         p->subs[SUB_REAL].inthreeway = 0;
03741                         p->subs[SUB_THREEWAY].inthreeway = 0;
03742                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
03743                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
03744                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03745                            /* Swap subs and dis-own channel */
03746                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
03747                            p->owner = NULL;
03748                            /* Ring the phone */
03749                            zt_ring_phone(p);
03750                         } else {
03751                            if ((res = attempt_transfer(p)) < 0) {
03752                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03753                               if (p->subs[SUB_THREEWAY].owner)
03754                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03755                            } else if (res) {
03756                               /* Don't actually hang up at this point */
03757                               if (p->subs[SUB_THREEWAY].owner)
03758                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03759                               break;
03760                            }
03761                         }
03762                      } else {
03763                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03764                         if (p->subs[SUB_THREEWAY].owner)
03765                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03766                      }
03767                   } else {
03768                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03769                      /* Swap subs and dis-own channel */
03770                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
03771                      p->owner = NULL;
03772                      /* Ring the phone */
03773                      zt_ring_phone(p);
03774                   }
03775                }
03776             } else {
03777                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
03778             }
03779             /* Fall through */
03780          default:
03781             zt_disable_ec(p);
03782             return NULL;
03783          }
03784          break;
03785       case ZT_EVENT_RINGOFFHOOK:
03786          if (p->inalarm) break;
03787          if (p->radio)
03788          {
03789             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03790             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
03791             break;
03792          }
03793          /* for E911, its supposed to wait for offhook then dial
03794             the second half of the dial string */
03795          if ((p->sig == SIG_E911) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
03796             c = strchr(p->dialdest, '/');
03797             if (c)
03798                c++;
03799             else
03800                c = p->dialdest;
03801             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
03802             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
03803             if (strlen(p->dop.dialstr) > 4) {
03804                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
03805                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
03806                p->echorest[sizeof(p->echorest) - 1] = '\0';
03807                p->echobreak = 1;
03808                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
03809             } else
03810                p->echobreak = 0;
03811             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
03812                x = ZT_ONHOOK;
03813                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03814                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
03815                return NULL;
03816                }
03817             p->dialing = 1;
03818             return &p->subs[index].f;
03819          }
03820          switch(p->sig) {
03821          case SIG_FXOLS:
03822          case SIG_FXOGS:
03823          case SIG_FXOKS:
03824             switch(ast->_state) {
03825             case AST_STATE_RINGING:
03826                zt_enable_ec(p);
03827                zt_train_ec(p);
03828                p->subs[index].f.frametype = AST_FRAME_CONTROL;
03829                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03830                /* Make sure it stops ringing */
03831                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
03832                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
03833                if (p->cidspill) {
03834                   /* Cancel any running CallerID spill */
03835                   free(p->cidspill);
03836                   p->cidspill = NULL;
03837                }
03838                p->dialing = 0;
03839                p->callwaitcas = 0;
03840                if (p->confirmanswer) {
03841                   /* Ignore answer if "confirm answer" is enabled */
03842                   p->subs[index].f.frametype = AST_FRAME_NULL;
03843                   p->subs[index].f.subclass = 0;
03844                } else if (!ast_strlen_zero(p->dop.dialstr)) {
03845                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
03846                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03847                   if (res < 0) {
03848                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
03849                      p->dop.dialstr[0] = '\0';
03850                      return NULL;
03851                   } else {
03852                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
03853                      p->subs[index].f.frametype = AST_FRAME_NULL;
03854                      p->subs[index].f.subclass = 0;
03855                      p->dialing = 1;
03856                   }
03857                   p->dop.dialstr[0] = '\0';
03858                   ast_setstate(ast, AST_STATE_DIALING);
03859                } else
03860                   ast_setstate(ast, AST_STATE_UP);
03861                return &p->subs[index].f;
03862             case AST_STATE_DOWN:
03863                ast_setstate(ast, AST_STATE_RING);
03864                ast->rings = 1;
03865                p->subs[index].f.frametype = AST_FRAME_CONTROL;
03866                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
03867                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
03868                return &p->subs[index].f;
03869             case AST_STATE_UP:
03870                /* Make sure it stops ringing */
03871                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
03872                /* Okay -- probably call waiting*/
03873                if (ast_bridged_channel(p->owner))
03874                      ast_moh_stop(ast_bridged_channel(p->owner));
03875                break;
03876             case AST_STATE_RESERVED:
03877                /* Start up dialtone */
03878                if (has_voicemail(p))
03879                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
03880                else
03881                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
03882                break;
03883             default:
03884                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
03885             }
03886             break;
03887          case SIG_FXSLS:
03888          case SIG_FXSGS:
03889          case SIG_FXSKS:
03890             if (ast->_state == AST_STATE_RING) {
03891                p->ringt = p->ringt_base;
03892             }
03893 
03894             /* If we get a ring then we cannot be in 
03895              * reversed polarity. So we reset to idle */
03896             ast_log(LOG_DEBUG, "Setting IDLE polarity due "
03897                "to ring. Old polarity was %d\n", 
03898                p->polarity);
03899             p->polarity = POLARITY_IDLE;
03900 
03901             /* Fall through */
03902          case SIG_EM:
03903          case SIG_EM_E1:
03904          case SIG_EMWINK:
03905          case SIG_FEATD:
03906          case SIG_FEATDMF:
03907          case SIG_FEATDMF_TA:
03908          case SIG_E911:
03909          case SIG_FEATB:
03910          case SIG_SF:
03911          case SIG_SFWINK:
03912          case SIG_SF_FEATD:
03913          case SIG_SF_FEATDMF:
03914          case SIG_SF_FEATB:
03915             if (ast->_state == AST_STATE_PRERING)
03916                ast_setstate(ast, AST_STATE_RING);
03917             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
03918                if (option_debug)
03919                   ast_log(LOG_DEBUG, "Ring detected\n");
03920                p->subs[index].f.frametype = AST_FRAME_CONTROL;
03921                p->subs[index].f.subclass = AST_CONTROL_RING;
03922             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
03923                if (option_debug)
03924                   ast_log(LOG_DEBUG, "Line answered\n");
03925                if (p->confirmanswer) {
03926                   p->subs[index].f.frametype = AST_FRAME_NULL;
03927                   p->subs[index].f.subclass = 0;
03928                } else {
03929                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
03930                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03931                   ast_setstate(ast, AST_STATE_UP);
03932                }
03933             } else if (ast->_state != AST_STATE_RING)
03934                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
03935             break;
03936          default:
03937             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
03938          }
03939          break;
03940 #ifdef ZT_EVENT_RINGBEGIN
03941       case ZT_EVENT_RINGBEGIN:
03942          switch(p->sig) {
03943          case SIG_FXSLS:
03944          case SIG_FXSGS:
03945          case SIG_FXSKS:
03946             if (ast->_state == AST_STATE_RING) {
03947                p->ringt = p->ringt_base;
03948             }
03949             break;
03950          }
03951          break;
03952 #endif         
03953       case ZT_EVENT_RINGEROFF:
03954          if (p->inalarm) break;
03955          if (p->radio) break;
03956          ast->rings++;
03957          if ((ast->rings > p->cidrings) && (p->cidspill)) {
03958             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
03959             free(p->cidspill);
03960             p->cidspill = NULL;
03961             p->callwaitcas = 0;
03962          }
03963          p->subs[index].f.frametype = AST_FRAME_CONTROL;
03964          p->subs[index].f.subclass = AST_CONTROL_RINGING;
03965          break;
03966       case ZT_EVENT_RINGERON:
03967          break;
03968       case ZT_EVENT_NOALARM:
03969          p->inalarm = 0;
03970 #ifdef ZAPATA_PRI
03971          /* Extremely unlikely but just in case */
03972          if (p->bearer)
03973             p->bearer->inalarm = 0;
03974 #endif            
03975          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
03976          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
03977                         "Channel: %d\r\n", p->channel);
03978          break;
03979       case ZT_EVENT_WINKFLASH:
03980          if (p->inalarm) break;
03981          if (p->radio) break;
03982          /* Remember last time we got a flash-hook */
03983          gettimeofday(&p->flashtime, NULL);
03984          switch(p->sig) {
03985          case SIG_FXOLS:
03986          case SIG_FXOGS:
03987          case SIG_FXOKS:
03988             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
03989                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
03990             p->callwaitcas = 0;
03991 
03992             if (index != SUB_REAL) {
03993                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
03994                goto winkflashdone;
03995             }
03996             
03997             if (p->subs[SUB_CALLWAIT].owner) {
03998                /* Swap to call-wait */
03999                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04000                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04001                p->owner = p->subs[SUB_REAL].owner;
04002                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04003                if (p->owner->_state == AST_STATE_RINGING) {
04004                   ast_setstate(p->owner, AST_STATE_UP);
04005                   p->subs[SUB_REAL].needanswer = 1;
04006                }
04007                p->callwaitingrepeat = 0;
04008                p->cidcwexpire = 0;
04009                /* Start music on hold if appropriate */
04010                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
04011                   ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
04012                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
04013                   ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
04014             } else if (!p->subs[SUB_THREEWAY].owner) {
04015                char cid_num[256];
04016                char cid_name[256];
04017 
04018                if (!p->threewaycalling) {
04019                   /* Just send a flash if no 3-way calling */
04020                   p->subs[SUB_REAL].needflash = 1;
04021                   goto winkflashdone;
04022                } else if (!check_for_conference(p)) {
04023                   if (p->zaptrcallerid && p->owner) {
04024                      if (p->owner->cid.cid_num)
04025                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04026                      if (p->owner->cid.cid_name)
04027                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04028                   }
04029                   /* XXX This section needs much more error checking!!! XXX */
04030                   /* Start a 3-way call if feasible */
04031                   if (!((ast->pbx) ||
04032                         (ast->_state == AST_STATE_UP) ||
04033                         (ast->_state == AST_STATE_RING))) {
04034                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04035                         goto winkflashdone;
04036                   }
04037                   if (alloc_sub(p, SUB_THREEWAY)) {
04038                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04039                      goto winkflashdone;
04040                   }
04041                   /* Make new channel */
04042                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04043                   if (p->zaptrcallerid) {
04044                      if (!p->origcid_num)
04045                         p->origcid_num = strdup(p->cid_num);
04046                      if (!p->origcid_name)
04047                         p->origcid_name = strdup(p->cid_name);
04048                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04049                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04050                   }
04051                   /* Swap things around between the three-way and real call */
04052                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04053                   /* Disable echo canceller for better dialing */
04054                   zt_disable_ec(p);
04055                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04056                   if (res)
04057                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04058                   p->owner = chan;
04059                   if (!chan) {
04060                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04061                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04062                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04063                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04064                      zt_enable_ec(p);
04065                      ast_hangup(chan);
04066                   } else {
04067                      if (option_verbose > 2) 
04068                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04069                      /* Start music on hold if appropriate */
04070                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
04071                         ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
04072                   }     
04073                }
04074             } else {
04075                /* Already have a 3 way call */
04076                if (p->subs[SUB_THREEWAY].inthreeway) {
04077                   /* Call is already up, drop the last person */
04078                   if (option_debug)
04079                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04080                   /* If the primary call isn't answered yet, use it */
04081                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04082                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04083                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04084                      p->owner = p->subs[SUB_REAL].owner;
04085                   }
04086                   /* Drop the last call and stop the conference */
04087                   if (option_verbose > 2)
04088                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04089                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04090                   p->subs[SUB_REAL].inthreeway = 0;
04091                   p->subs[SUB_THREEWAY].inthreeway = 0;
04092                } else {
04093                   /* Lets see what we're up to */
04094                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04095                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04096                      int otherindex = SUB_THREEWAY;
04097 
04098                      if (option_verbose > 2)
04099                         ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
04100                      /* Put them in the threeway, and flip */
04101                      p->subs[SUB_THREEWAY].inthreeway = 1;
04102                      p->subs[SUB_REAL].inthreeway = 1;
04103                      if (ast->_state == AST_STATE_UP) {
04104                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04105                         otherindex = SUB_REAL;
04106                      }
04107                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04108                         ast_moh_stop(ast_bridged_channel(p->subs[otherindex].owner));
04109                      p->owner = p->subs[SUB_REAL].owner;
04110                      if (ast->_state == AST_STATE_RINGING) {
04111                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04112                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04113                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04114                      }
04115                   } else {
04116                      if (option_verbose > 2)
04117                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04118                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04119                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04120                      p->owner = p->subs[SUB_REAL].owner;
04121                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04122                         ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
04123                      zt_enable_ec(p);
04124                   }
04125                      
04126                }
04127             }
04128          winkflashdone:              
04129             update_conf(p);
04130             break;
04131          case SIG_EM:
04132          case SIG_EM_E1:
04133          case SIG_EMWINK:
04134          case SIG_FEATD:
04135          case SIG_SF:
04136          case SIG_SFWINK:
04137          case SIG_SF_FEATD:
04138          case SIG_FXSLS:
04139          case SIG_FXSGS:
04140             if (p->dialing)
04141                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04142             else
04143                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04144             break;
04145          case SIG_FEATDMF_TA:
04146             switch (p->whichwink) {
04147             case 0:
04148                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04149                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04150                break;
04151             case 1:
04152                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04153                break;
04154             case 2:
04155                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04156                return NULL;
04157             }
04158             p->whichwink++;
04159             /* Fall through */
04160          case SIG_FEATDMF:
04161          case SIG_E911:
04162          case SIG_FEATB:
04163          case SIG_SF_FEATDMF:
04164          case SIG_SF_FEATB:
04165             /* FGD MF *Must* wait for wink */
04166             if (!ast_strlen_zero(p->dop.dialstr))
04167                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04168             else if (res < 0) {
04169                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04170                p->dop.dialstr[0] = '\0';
04171                return NULL;
04172             } else 
04173                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04174             p->dop.dialstr[0] = '\0';
04175             break;
04176          default:
04177             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04178          }
04179          break;
04180       case ZT_EVENT_HOOKCOMPLETE:
04181          if (p->inalarm) break;
04182          if (p->radio) break;
04183          switch(p->sig) {
04184          case SIG_FXSLS:  /* only interesting for FXS */
04185          case SIG_FXSGS:
04186          case SIG_FXSKS:
04187          case SIG_EM:
04188          case SIG_EM_E1:
04189          case SIG_EMWINK:
04190          case SIG_FEATD:
04191          case SIG_SF:
04192          case SIG_SFWINK:
04193          case SIG_SF_FEATD:
04194             if (!ast_strlen_zero(p->dop.dialstr)) 
04195                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04196             else if (res < 0) {
04197                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04198                p->dop.dialstr[0] = '\0';
04199                return NULL;
04200             } else 
04201                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04202             p->dop.dialstr[0] = '\0';
04203             p->dop.op = ZT_DIAL_OP_REPLACE;
04204             break;
04205          case SIG_FEATDMF:
04206          case SIG_E911:
04207          case SIG_FEATB:
04208          case SIG_SF_FEATDMF:
04209          case SIG_SF_FEATB:
04210             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04211             break;
04212          default:
04213             break;
04214          }
04215          break;
04216       case ZT_EVENT_POLARITY:
04217                         /*
04218                          * If we get a Polarity Switch event, check to see
04219                          * if we should change the polarity state and
04220                          * mark the channel as UP or if this is an indication
04221                          * of remote end disconnect.
04222                          */
04223                         if (p->polarity == POLARITY_IDLE) {
04224                                 p->polarity = POLARITY_REV;
04225                                 if (p->answeronpolarityswitch &&
04226                                     ((ast->_state == AST_STATE_DIALING) ||
04227                                      (ast->_state == AST_STATE_RINGING))) {
04228                                         ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04229                                         ast_setstate(p->owner, AST_STATE_UP);
04230                if(p->hanguponpolarityswitch) {
04231                   gettimeofday(&p->polaritydelaytv, NULL);
04232                }
04233                break;
04234                                 } else
04235                                         ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04236          } 
04237          /* Removed else statement from here as it was preventing hangups from ever happening*/
04238          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04239          if(p->hanguponpolarityswitch &&
04240             (p->polarityonanswerdelay > 0) &&
04241                 (p->polarity == POLARITY_REV) &&
04242             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04243                                 /* Added log_debug information below to provide a better indication of what is going on */
04244             ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
04245          
04246             if(ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04247                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04248                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04249                p->polarity = POLARITY_IDLE;
04250             } else {
04251                ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
04252             }
04253          } else {
04254             p->polarity = POLARITY_IDLE;
04255             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04256          }
04257                         /* Added more log_debug information below to provide a better indication of what is going on */
04258          ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
04259          break;
04260       default:
04261          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04262    }
04263    return &p->subs[index].f;
04264 }

static int zt_hangup struct ast_channel ast  )  [static]
 

Definition at line 2309 of file chan_zap.c.

References ast_channel::_state, ast_bridged_channel(), ast_channel_setoption(), ast_dsp_digitmode(), ast_dsp_free(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_STATE_RESERVED, AST_STATE_UP, ast_update_use_count(), ast_verbose(), zt_pvt::callwaitcas, zt_pvt::callwaiting, zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, zt_pvt::destroy, destroy_channel(), zt_pvt::dialing, zt_pvt::didtdd, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::exten, zt_pvt::faxhandled, free, zt_pvt::guardtime, ast_channel::hangupcause, zt_pvt::hidecallerid, iflist, zt_pvt::ignoredtmf, zt_subchannel::inthreeway, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, zt_pvt::next, zt_pvt::onhooktime, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_getvar_helper(), zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::prev, zt_pvt::pulsedial, zt_pvt::radio, zt_pvt::rdnis, reset_conf(), restart_monitor(), restore_gains(), zt_pvt::ringt, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), usecnt_lock, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().

02310 {
02311    int res;
02312    int index,x, law;
02313    /*static int restore_gains(struct zt_pvt *p);*/
02314    struct zt_pvt *p = ast->tech_pvt;
02315    struct zt_pvt *tmp = NULL;
02316    struct zt_pvt *prev = NULL;
02317    ZT_PARAMS par;
02318 
02319    if (option_debug)
02320       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02321    if (!ast->tech_pvt) {
02322       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02323       return 0;
02324    }
02325    
02326    ast_mutex_lock(&p->lock);
02327    
02328    index = zt_get_index(ast, p, 1);
02329 
02330    if (p->sig == SIG_PRI) {
02331       x = 1;
02332       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02333    }
02334 
02335    x = 0;
02336    zt_confmute(p, 0);
02337    restore_gains(p);
02338    if (p->origcid_num) {
02339       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02340       free(p->origcid_num);
02341       p->origcid_num = NULL;
02342    }  
02343    if (p->origcid_name) {
02344       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02345       free(p->origcid_name);
02346       p->origcid_name = NULL;
02347    }  
02348    if (p->dsp)
02349       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02350    if (p->exten)
02351       p->exten[0] = '\0';
02352 
02353    ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02354       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02355    p->ignoredtmf = 0;
02356    
02357    if (index > -1) {
02358       /* Real channel, do some fixup */
02359       p->subs[index].owner = NULL;
02360       p->subs[index].needanswer = 0;
02361       p->subs[index].needflash = 0;
02362       p->subs[index].needringing = 0;
02363       p->subs[index].needbusy = 0;
02364       p->subs[index].needcongestion = 0;
02365       p->subs[index].linear = 0;
02366       p->subs[index].needcallerid = 0;
02367       p->polarity = POLARITY_IDLE;
02368       zt_setlinear(p->subs[index].zfd, 0);
02369       if (index == SUB_REAL) {
02370          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02371             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02372             if (p->subs[SUB_CALLWAIT].inthreeway) {
02373                /* We had flipped over to answer a callwait and now it's gone */
02374                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02375                /* Move to the call-wait, but un-own us until they flip back. */
02376                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02377                unalloc_sub(p, SUB_CALLWAIT);
02378                p->owner = NULL;
02379             } else {
02380                /* The three way hung up, but we still have a call wait */
02381                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02382                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02383                unalloc_sub(p, SUB_THREEWAY);
02384                if (p->subs[SUB_REAL].inthreeway) {
02385                   /* This was part of a three way call.  Immediately make way for
02386                      another call */
02387                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02388                   p->owner = p->subs[SUB_REAL].owner;
02389                } else {
02390                   /* This call hasn't been completed yet...  Set owner to NULL */
02391                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02392                   p->owner = NULL;
02393                }
02394                p->subs[SUB_REAL].inthreeway = 0;
02395             }
02396          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02397             /* Move to the call-wait and switch back to them. */
02398             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02399             unalloc_sub(p, SUB_CALLWAIT);
02400             p->owner = p->subs[SUB_REAL].owner;
02401             if (p->owner->_state != AST_STATE_UP)
02402                p->subs[SUB_REAL].needanswer = 1;
02403             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02404                ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
02405          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02406             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02407             unalloc_sub(p, SUB_THREEWAY);
02408             if (p->subs[SUB_REAL].inthreeway) {
02409                /* This was part of a three way call.  Immediately make way for
02410                   another call */
02411                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02412                p->owner = p->subs[SUB_REAL].owner;
02413             } else {
02414                /* This call hasn't been completed yet...  Set owner to NULL */
02415                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02416                p->owner = NULL;
02417             }
02418             p->subs[SUB_REAL].inthreeway = 0;
02419          }
02420       } else if (index == SUB_CALLWAIT) {
02421          /* Ditch the holding callwait call, and immediately make it availabe */
02422          if (p->subs[SUB_CALLWAIT].inthreeway) {
02423             /* This is actually part of a three way, placed on hold.  Place the third part
02424                on music on hold now */
02425             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
02426                ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
02427             p->subs[SUB_THREEWAY].inthreeway = 0;
02428             /* Make it the call wait now */
02429             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02430             unalloc_sub(p, SUB_THREEWAY);
02431          } else
02432             unalloc_sub(p, SUB_CALLWAIT);
02433       } else if (index == SUB_THREEWAY) {
02434          if (p->subs[SUB_CALLWAIT].inthreeway) {
02435             /* The other party of the three way call is currently in a call-wait state.
02436                Start music on hold for them, and take the main guy out of the third call */
02437             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
02438                ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
02439             p->subs[SUB_CALLWAIT].inthreeway = 0;
02440          }
02441          p->subs[SUB_REAL].inthreeway = 0;
02442          /* If this was part of a three way call index, let us make
02443             another three way call */
02444          unalloc_sub(p, SUB_THREEWAY);
02445       } else {
02446          /* This wasn't any sort of call, but how are we an index? */
02447          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02448       }
02449    }
02450 
02451 
02452    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02453       p->owner = NULL;
02454       p->ringt = 0;
02455       p->distinctivering = 0;
02456       p->confirmanswer = 0;
02457       p->cidrings = 1;
02458       p->outgoing = 0;
02459       p->digital = 0;
02460       p->faxhandled = 0;
02461       p->pulsedial = 0;
02462       p->onhooktime = time(NULL);
02463 #ifdef ZAPATA_PRI
02464       p->proceeding = 0;
02465       p->progress = 0;
02466       p->alerting = 0;
02467       p->setup_ack = 0;
02468 #endif      
02469       if (p->dsp) {
02470          ast_dsp_free(p->dsp);
02471          p->dsp = NULL;
02472       }
02473 
02474       law = ZT_LAW_DEFAULT;
02475       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02476       if (res < 0) 
02477          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02478       /* Perform low level hangup if no owner left */
02479 #ifdef ZAPATA_PRI
02480       if (p->pri) {
02481 #ifdef SUPPORT_USERUSER
02482          char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02483 #endif
02484 
02485          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02486          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02487             if (!pri_grab(p, p->pri)) {
02488                if (p->alreadyhungup) {
02489                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02490 
02491 #ifdef SUPPORT_USERUSER
02492                   pri_call_set_useruser(p->call, useruser);
02493 #endif
02494 
02495                   pri_hangup(p->pri->pri, p->call, -1);
02496                   p->call = NULL;
02497                   if (p->bearer) 
02498                      p->bearer->call = NULL;
02499                } else {
02500                   char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02501                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02502                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02503 
02504 #ifdef SUPPORT_USERUSER
02505                   pri_call_set_useruser(p->call, useruser);
02506 #endif
02507 
02508                   p->alreadyhungup = 1;
02509                   if (p->bearer)
02510                      p->bearer->alreadyhungup = 1;
02511                   if (cause) {
02512                      if (atoi(cause))
02513                         icause = atoi(cause);
02514                   }
02515                   pri_hangup(p->pri->pri, p->call, icause);
02516                }
02517                if (res < 0) 
02518                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02519                pri_rel(p->pri);        
02520             } else {
02521                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02522                res = -1;
02523             }
02524          } else {
02525             if (p->bearer)
02526                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02527             p->call = NULL;
02528             res = 0;
02529          }
02530       }
02531 #endif
02532 #ifdef ZAPATA_R2
02533       if (p->sig == SIG_R2) {
02534          if (p->hasr2call) {
02535             mfcr2_DropCall(p->r2, NULL, UC_NORMAL_CLEARING);
02536             p->hasr2call = 0;
02537             res = 0;
02538          } else
02539             res = 0;
02540 
02541       }
02542 #endif
02543       if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2))
02544          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02545       if (res < 0) {
02546          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02547       }
02548       switch(p->sig) {
02549       case SIG_FXOGS:
02550       case SIG_FXOLS:
02551       case SIG_FXOKS:
02552          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02553          if (!res) {
02554 #if 0
02555             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02556 #endif
02557             /* If they're off hook, try playing congestion */
02558             if ((par.rxisoffhook) && (!p->radio))
02559                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02560             else
02561                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02562          }
02563          break;
02564       case SIG_FXSGS:
02565       case SIG_FXSLS:
02566       case SIG_FXSKS:
02567          /* Make sure we're not made available for at least two seconds assuming
02568             we were actually used for an inbound or outbound call. */
02569          if (ast->_state != AST_STATE_RESERVED) {
02570             time(&p->guardtime);
02571             p->guardtime += 2;
02572          }
02573          break;
02574       default:
02575          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02576       }
02577       if (p->cidspill)
02578          free(p->cidspill);
02579       if (p->sig)
02580          zt_disable_ec(p);
02581       x = 0;
02582       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02583       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02584       p->didtdd = 0;
02585       p->cidspill = NULL;
02586       p->callwaitcas = 0;
02587       p->callwaiting = p->permcallwaiting;
02588       p->hidecallerid = p->permhidecallerid;
02589       p->dialing = 0;
02590       p->rdnis[0] = '\0';
02591       update_conf(p);
02592       reset_conf(p);
02593       /* Restore data mode */
02594       if (p->sig == SIG_PRI) {
02595          x = 0;
02596          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02597       }
02598 #ifdef ZAPATA_PRI
02599       if (p->bearer) {
02600          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02601          /* Free up the bearer channel as well, and
02602             don't use its file descriptor anymore */
02603          update_conf(p->bearer);
02604          reset_conf(p->bearer);
02605          p->bearer->owner = NULL;
02606          p->bearer->realcall = NULL;
02607          p->bearer = NULL;
02608          p->subs[SUB_REAL].zfd = -1;
02609          p->pri = NULL;
02610       }
02611 #endif
02612       restart_monitor();
02613    }
02614 
02615 
02616    p->callwaitingrepeat = 0;
02617    p->cidcwexpire = 0;
02618    ast->tech_pvt = NULL;
02619    ast_mutex_unlock(&p->lock);
02620    ast_mutex_lock(&usecnt_lock);
02621    usecnt--;
02622    if (usecnt < 0) 
02623       ast_log(LOG_WARNING, "Usecnt < 0???\n");
02624    ast_mutex_unlock(&usecnt_lock);
02625    ast_update_use_count();
02626    if (option_verbose > 2) 
02627       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02628 
02629    ast_mutex_lock(&iflock);
02630    tmp = iflist;
02631    prev = NULL;
02632    if (p->destroy) {
02633       while (tmp) {
02634          if (tmp == p) {
02635             destroy_channel(prev, tmp, 0);
02636             break;
02637          } else {
02638             prev = tmp;
02639             tmp = tmp->next;
02640          }
02641       }
02642    }
02643    ast_mutex_unlock(&iflock);
02644    return 0;
02645 }

static int zt_indicate struct ast_channel chan,
int  condition
[static]
 

Definition at line 4817 of file chan_zap.c.

References ast_channel::_softhangup, ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, zt_pvt::digital, zt_pvt::dop, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, ast_channel::name, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().

04818 {
04819    struct zt_pvt *p = chan->tech_pvt;
04820    int res=-1;
04821    int index;
04822    int func = ZT_FLASH;
04823    ast_mutex_lock(&p->lock);
04824    index = zt_get_index(chan, p, 0);
04825    ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
04826    if (index == SUB_REAL) {
04827       switch(condition) {
04828       case AST_CONTROL_BUSY:
04829 #ifdef ZAPATA_PRI
04830          if (p->priindication_oob && p->sig == SIG_PRI) {
04831             chan->hangupcause = AST_CAUSE_USER_BUSY;
04832             chan->_softhangup |= AST_SOFTHANGUP_DEV;
04833             res = 0;
04834          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04835             if (p->pri->pri) {      
04836                if (!pri_grab(p, p->pri)) {
04837                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
04838                   pri_rel(p->pri);
04839                }
04840                else
04841                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04842             }
04843             p->progress = 1;
04844             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
04845          } else
04846 #endif
04847             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
04848          break;
04849       case AST_CONTROL_RINGING:
04850 #ifdef ZAPATA_PRI
04851          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
04852             if (p->pri->pri) {      
04853                if (!pri_grab(p, p->pri)) {
04854                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04855                   pri_rel(p->pri);
04856                }
04857                else
04858                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04859             }
04860             p->alerting = 1;
04861          }
04862 #endif
04863          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
04864          if (chan->_state != AST_STATE_UP) {
04865             if ((chan->_state != AST_STATE_RING) ||
04866                ((p->sig != SIG_FXSKS) &&
04867                 (p->sig != SIG_FXSLS) &&
04868                 (p->sig != SIG_FXSGS)))
04869                ast_setstate(chan, AST_STATE_RINGING);
04870          }
04871          break;
04872       case AST_CONTROL_PROCEEDING:
04873          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
04874 #ifdef ZAPATA_PRI
04875          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04876             if (p->pri->pri) {      
04877                if (!pri_grab(p, p->pri)) {
04878                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04879                   pri_rel(p->pri);
04880                }
04881                else
04882                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04883             }
04884             p->proceeding = 1;
04885          }
04886 #endif
04887          /* don't continue in ast_indicate */
04888          res = 0;
04889          break;
04890       case AST_CONTROL_PROGRESS:
04891          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
04892 #ifdef ZAPATA_PRI
04893          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
04894          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04895             if (p->pri->pri) {      
04896                if (!pri_grab(p, p->pri)) {
04897                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
04898                   pri_rel(p->pri);
04899                }
04900                else
04901                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04902             }
04903             p->progress = 1;
04904          }
04905 #endif
04906          /* don't continue in ast_indicate */
04907          res = 0;
04908          break;
04909       case AST_CONTROL_CONGESTION:
04910          chan->hangupcause = AST_CAUSE_CONGESTION;
04911 #ifdef ZAPATA_PRI
04912          if (p->priindication_oob && p->sig == SIG_PRI) {
04913             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
04914             chan->_softhangup |= AST_SOFTHANGUP_DEV;
04915             res = 0;
04916          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04917             if (p->pri) {     
04918                if (!pri_grab(p, p->pri)) {
04919                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
04920                   pri_rel(p->pri);
04921                } else
04922                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04923             }
04924             p->progress = 1;
04925             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
04926          } else
04927 #endif
04928             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
04929          break;
04930 #ifdef ZAPATA_PRI
04931       case AST_CONTROL_HOLD:
04932          if (p->pri) {
04933             if (!pri_grab(p, p->pri)) {
04934                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
04935                pri_rel(p->pri);
04936             } else
04937                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
04938          }
04939          break;
04940       case AST_CONTROL_UNHOLD:
04941          if (p->pri) {
04942             if (!pri_grab(p, p->pri)) {
04943                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
04944                pri_rel(p->pri);
04945             } else
04946                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
04947          }
04948          break;
04949 #endif
04950       case AST_CONTROL_RADIO_KEY:
04951          if (p->radio) 
04952              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04953          res = 0;
04954          break;
04955       case AST_CONTROL_RADIO_UNKEY:
04956          if (p->radio)
04957              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
04958          res = 0;
04959          break;
04960       case AST_CONTROL_FLASH:
04961          /* flash hookswitch */
04962          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
04963             /* Clear out the dial buffer */
04964             p->dop.dialstr[0] = '\0';
04965             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
04966                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
04967                   chan->name, strerror(errno));
04968             } else
04969                res = 0;
04970          } else
04971             res = 0;
04972          break;
04973       case -1:
04974          res = tone_zone_play_tone(p->subs[index].zfd, -1);
04975          break;
04976       }
04977    } else
04978       res = 0;
04979    ast_mutex_unlock(&p->lock);
04980    return res;
04981 }

static void zt_link struct zt_pvt slave,
struct zt_pvt master
[static]
 

Definition at line 2942 of file chan_zap.c.

References ast_log(), LOG_WARNING, and master.

Referenced by zt_bridge().

02942                                                                  {
02943    int x;
02944    if (!slave || !master) {
02945       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
02946       return;
02947    }
02948    for (x=0;x<MAX_SLAVES;x++) {
02949       if (!master->slaves[x]) {
02950          master->slaves[x] = slave;
02951          break;
02952       }
02953    }
02954    if (x >= MAX_SLAVES) {
02955       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
02956       master->slaves[MAX_SLAVES - 1] = slave;
02957    }
02958    if (slave->master) 
02959       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
02960    slave->master = master;
02961    
02962    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
02963 }

static struct ast_channel * zt_new struct zt_pvt ,
int  ,
int  ,
int  ,
int  ,
int 
[static]
 

Definition at line 4983 of file chan_zap.c.

References ast_channel::accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_strlen_zero(), ast_transfercapability2str(), ast_update_use_count(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::call_forward, ast_channel::call_forward, zt_pvt::callgroup, ast_channel::callgroup, zt_pvt::callingpres, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_dnid, zt_pvt::cid_name, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, zt_pvt::context, ast_channel::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, zt_pvt::dsp_features, DSP_PROGRESS_TALK, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, features, zt_pvt::hardwaredtmf, ast_channel::language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, ast_channel::musicclass, zt_pvt::musicclass, ast_channel::name, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, strdup, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::type, usecnt_lock, ast_channel::writeformat, zap_tech, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().

Referenced by handle_init_event(), and zt_handle_event().

04984 {
04985    struct ast_channel *tmp;
04986    int deflaw;
04987    int res;
04988    int x,y;
04989    int features;
04990    ZT_PARAMS ps;
04991    if (i->subs[index].owner) {
04992       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
04993       return NULL;
04994    }
04995    tmp = ast_channel_alloc(0);
04996    if (tmp) {
04997       tmp->tech = &zap_tech;
04998       ps.channo = i->channel;
04999       res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05000       if (res) {
05001          ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05002          ps.curlaw = ZT_LAW_MULAW;
05003       }
05004       if (ps.curlaw == ZT_LAW_ALAW)
05005          deflaw = AST_FORMAT_ALAW;
05006       else
05007          deflaw = AST_FORMAT_ULAW;
05008       if (law) {
05009          if (law == ZT_LAW_ALAW)
05010             deflaw = AST_FORMAT_ALAW;
05011          else
05012             deflaw = AST_FORMAT_ULAW;
05013       }
05014       y = 1;
05015       do {
05016 #ifdef ZAPATA_PRI
05017          if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05018             snprintf(tmp->name, sizeof(tmp->name), "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05019          else
05020 #endif
05021          if (i->channel == CHAN_PSEUDO)
05022             snprintf(tmp->name, sizeof(tmp->name), "Zap/pseudo-%d", rand());
05023          else  
05024             snprintf(tmp->name, sizeof(tmp->name), "Zap/%d-%d", i->channel, y);
05025          for (x=0;x<3;x++) {
05026             if ((index != x) && i->subs[x].owner && !strcasecmp(tmp->name, i->subs[x].owner->name))
05027                break;
05028          }
05029          y++;
05030       } while (x < 3);
05031       tmp->type = type;
05032       tmp->fds[0] = i->subs[index].zfd;
05033       tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05034       /* Start out assuming ulaw since it's smaller :) */
05035       tmp->rawreadformat = deflaw;
05036       tmp->readformat = deflaw;
05037       tmp->rawwriteformat = deflaw;
05038       tmp->writeformat = deflaw;
05039       i->subs[index].linear = 0;
05040       zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05041       features = 0;
05042       if (i->busydetect && CANBUSYDETECT(i)) {
05043          features |= DSP_FEATURE_BUSY_DETECT;
05044       }
05045       if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) {
05046          features |= DSP_FEATURE_CALL_PROGRESS;
05047       }
05048       if ((!i->outgoing && (i->callprogress & 4)) || 
05049           (i->outgoing && (i->callprogress & 2))) {
05050          features |= DSP_FEATURE_FAX_DETECT;
05051       }
05052 #ifdef ZT_TONEDETECT
05053       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05054       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05055 #endif      
05056          i->hardwaredtmf = 0;
05057          features |= DSP_FEATURE_DTMF_DETECT;
05058 #ifdef ZT_TONEDETECT
05059       } else if (NEED_MFDETECT(i)) {
05060          i->hardwaredtmf = 1;
05061          features |= DSP_FEATURE_DTMF_DETECT;
05062       }
05063 #endif
05064       if (features) {
05065          if (i->dsp) {
05066             ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05067          } else {
05068             if (i->channel != CHAN_PSEUDO)
05069                i->dsp = ast_dsp_new();
05070             else
05071                i->dsp = NULL;
05072             if (i->dsp) {
05073                i->dsp_features = features & ~DSP_PROGRESS_TALK;
05074 #ifdef ZAPATA_PRI
05075                /* We cannot do progress detection until receives PROGRESS message */
05076                if (i->outgoing && (i->sig == SIG_PRI)) {
05077                   /* Remember requested DSP features, don't treat
05078                      talking as ANSWER */
05079                   features = 0;
05080                }
05081 #endif
05082                ast_dsp_set_features(i->dsp, features);
05083                ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05084                if (!ast_strlen_zero(progzone))
05085                   ast_dsp_set_call_progress_zone(i->dsp, progzone);
05086                if (i->busydetect && CANBUSYDETECT(i)) {
05087                   ast_dsp_set_busy_count(i->dsp, i->busycount);
05088                   ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05089                }
05090             }
05091          }
05092       }
05093       
05094       if (state == AST_STATE_RING)
05095          tmp->rings = 1;
05096       tmp->tech_pvt = i;
05097       if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05098          /* Only FXO signalled stuff can be picked up */
05099          tmp->callgroup = i->callgroup;
05100          tmp->pickupgroup = i->pickupgroup;
05101       }
05102       if (!ast_strlen_zero(i->language))
05103          ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
05104       if (!ast_strlen_zero(i->musicclass))
05105          ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass));
05106       if (!i->owner)
05107          i->owner = tmp;
05108       if (!ast_strlen_zero(i->accountcode))
05109          ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
05110       if (i->amaflags)
05111          tmp->amaflags = i->amaflags;
05112       i->subs[index].owner = tmp;
05113       ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05114       /* Copy call forward info */
05115       ast_copy_string(tmp->call_forward, i->call_forward, sizeof(tmp->call_forward));
05116       /* If we've been told "no ADSI" then enforce it */
05117       if (!i->adsi)
05118          tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05119       if (!ast_strlen_zero(i->exten))
05120          ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05121       if (!ast_strlen_zero(i->rdnis))
05122          tmp->cid.cid_rdnis = strdup(i->rdnis);
05123       if (!ast_strlen_zero(i->dnid))
05124          tmp->cid.cid_dnid = strdup(i->dnid);
05125 
05126 #ifdef PRI_ANI
05127       ast_set_callerid(tmp, i->cid_num, i->cid_name, ast_strlen_zero(i->cid_ani) ? i->cid_num : i->cid_ani);
05128 #else
05129       ast_set_callerid(tmp, i->cid_num, i->cid_name, i->cid_num);
05130 #endif
05131       tmp->cid.cid_pres = i->callingpres;
05132       tmp->cid.cid_ton = i->cid_ton;
05133 #ifdef ZAPATA_PRI
05134       tmp->transfercapability = transfercapability;
05135       pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05136       if (transfercapability & PRI_TRANS_CAP_DIGITAL) {
05137          i->digital = 1;
05138       }
05139       /* Assume calls are not idle calls unless we're told differently */
05140       i->isidlecall = 0;
05141       i->alreadyhungup = 0;
05142 #endif
05143       /* clear the fake event in case we posted one before we had ast_channel */
05144       i->fake_event = 0;
05145       /* Assure there is no confmute on this channel */
05146       zt_confmute(i, 0);
05147       ast_setstate(tmp, state);
05148       ast_mutex_lock(&usecnt_lock);
05149       usecnt++;
05150       ast_mutex_unlock(&usecnt_lock);
05151       ast_update_use_count();
05152       if (startpbx) {
05153          if (ast_pbx_start(tmp)) {
05154             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05155             ast_hangup(tmp);
05156             tmp = NULL;
05157          }
05158       }
05159    } else
05160       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
05161    return tmp;
05162 }

static int zt_open char *  fn  )  [static]
 

Definition at line 891 of file chan_zap.c.

Referenced by alloc_sub(), chandup(), and mkintf().

00892 {
00893    int fd;
00894    int isnum;
00895    int chan = 0;
00896    int bs;
00897    int x;
00898    isnum = 1;
00899    for (x=0;x<strlen(fn);x++) {
00900       if (!isdigit(fn[x])) {
00901          isnum = 0;
00902          break;
00903       }
00904    }
00905    if (isnum) {
00906       chan = atoi(fn);
00907       if (chan < 1) {
00908          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00909          return -1;
00910       }
00911       fn = "/dev/zap/channel";
00912    }
00913    fd = open(fn, O_RDWR | O_NONBLOCK);
00914    if (fd < 0) {
00915       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00916       return -1;
00917    }
00918    if (chan) {
00919       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00920          x = errno;
00921          close(fd);
00922          errno = x;
00923          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00924          return -1;
00925       }
00926    }
00927    bs = READ_SIZE;
00928    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1;
00929    return fd;
00930 }

struct ast_frame * zt_read struct ast_channel ast  ) 
 

Definition at line 4380 of file chan_zap.c.

References __zt_exception(), ast_channel::_state, ast_async_goto(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, ast_dsp_process(), ast_exists_extension(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_callerid(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), zt_subchannel::buffer, zt_pvt::busydetect, zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::channel, CHECK_BLOCKING, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, zt_pvt::dsp, ast_channel::exten, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::faxhandled, zt_pvt::firstradio, ast_frame::frametype, free, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::macrocontext, ast_frame::mallocd, ast_channel::name, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, ast_frame::offset, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, pbx_builtin_setvar_helper(), zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, ast_frame::samples, send_callerid(), send_cwcidspill(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_confmute(), zt_get_index(), and zt_setlinear().

04381 {
04382    struct zt_pvt *p = ast->tech_pvt;
04383    int res;
04384    int index;
04385    void *readbuf;
04386    struct ast_frame *f;
04387    
04388 
04389    ast_mutex_lock(&p->lock);
04390    
04391    index = zt_get_index(ast, p, 0);
04392    
04393    /* Hang up if we don't really exist */
04394    if (index < 0) {
04395       ast_log(LOG_WARNING, "We dont exist?\n");
04396       ast_mutex_unlock(&p->lock);
04397       return NULL;
04398    }
04399    
04400    if (p->radio && p->inalarm) return NULL;
04401 
04402    p->subs[index].f.frametype = AST_FRAME_NULL;
04403    p->subs[index].f.datalen = 0;
04404    p->subs[index].f.samples = 0;
04405    p->subs[index].f.mallocd = 0;
04406    p->subs[index].f.offset = 0;
04407    p->subs[index].f.subclass = 0;
04408    p->subs[index].f.delivery = ast_tv(0,0);
04409    p->subs[index].f.src = "zt_read";
04410    p->subs[index].f.data = NULL;
04411    
04412    /* make sure it sends initial key state as first frame */
04413    if (p->radio && (!p->firstradio))
04414    {
04415       ZT_PARAMS ps;
04416 
04417       ps.channo = p->channel;
04418       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04419          ast_mutex_unlock(&p->lock);
04420          return NULL;
04421       }
04422       p->firstradio = 1;
04423       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04424       if (ps.rxisoffhook)
04425       {
04426          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04427       }
04428       else
04429       {
04430          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04431       }
04432       ast_mutex_unlock(&p->lock);
04433       return &p->subs[index].f;
04434    }
04435    if (p->ringt == 1) {
04436       ast_mutex_unlock(&p->lock);
04437       return NULL;
04438    }
04439    else if (p->ringt > 0) 
04440       p->ringt--;
04441 
04442    if (p->subs[index].needringing) {
04443       /* Send ringing frame if requested */
04444       p->subs[index].needringing = 0;
04445       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04446       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04447       ast_setstate(ast, AST_STATE_RINGING);
04448       ast_mutex_unlock(&p->lock);
04449       return &p->subs[index].f;
04450    }
04451 
04452    if (p->subs[index].needbusy) {
04453       /* Send busy frame if requested */
04454       p->subs[index].needbusy = 0;
04455       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04456       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04457       ast_mutex_unlock(&p->lock);
04458       return &p->subs[index].f;
04459    }
04460 
04461    if (p->subs[index].needcongestion) {
04462       /* Send congestion frame if requested */
04463       p->subs[index].needcongestion = 0;
04464       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04465       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04466       ast_mutex_unlock(&p->lock);
04467       return &p->subs[index].f;
04468    }
04469 
04470    if (p->subs[index].needcallerid) {
04471       ast_set_callerid(ast, !ast_strlen_zero(p->lastcid_num) ? p->lastcid_num : NULL, 
04472                      !ast_strlen_zero(p->lastcid_name) ? p->lastcid_name : NULL,
04473                      !ast_strlen_zero(p->lastcid_num) ? p->lastcid_num : NULL
04474                      );
04475       p->subs[index].needcallerid = 0;
04476    }
04477    
04478    if (p->subs[index].needanswer) {
04479       /* Send answer frame if requested */
04480       p->subs[index].needanswer = 0;
04481       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04482       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04483       ast_mutex_unlock(&p->lock);
04484       return &p->subs[index].f;
04485    }  
04486    
04487    if (p->subs[index].needflash) {
04488       /* Send answer frame if requested */
04489       p->subs[index].needflash = 0;
04490       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04491       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04492       ast_mutex_unlock(&p->lock);
04493       return &p->subs[index].f;
04494    }  
04495    
04496    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04497       if (!p->subs[index].linear) {
04498          p->subs[index].linear = 1;
04499          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04500          if (res) 
04501             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04502       }
04503    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04504          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04505       if (p->subs[index].linear) {
04506          p->subs[index].linear = 0;
04507          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04508          if (res) 
04509             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04510       }
04511    } else {
04512       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04513       ast_mutex_unlock(&p->lock);
04514       return NULL;
04515    }
04516    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04517    CHECK_BLOCKING(ast);
04518    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04519    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04520    /* Check for hangup */
04521    if (res < 0) {
04522       f = NULL;
04523       if (res == -1)  {
04524          if (errno == EAGAIN) {
04525             /* Return "NULL" frame if there is nobody there */
04526             ast_mutex_unlock(&p->lock);
04527             return &p->subs[index].f;
04528          } else if (errno == ELAST) {
04529             f = __zt_exception(ast);
04530          } else
04531             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04532       }
04533       ast_mutex_unlock(&p->lock);
04534       return f;
04535    }
04536    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04537       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04538       f = __zt_exception(ast);
04539       ast_mutex_unlock(&p->lock);
04540       return f;
04541    }
04542    if (p->tdd) { /* if in TDD mode, see if we receive that */
04543       int c;
04544 
04545       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04546       if (c < 0) {
04547          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04548          ast_mutex_unlock(&p->lock);
04549          return NULL;
04550       }
04551       if (c) { /* if a char to return */
04552          p->subs[index].f.subclass = 0;
04553          p->subs[index].f.frametype = AST_FRAME_TEXT;
04554          p->subs[index].f.mallocd = 0;
04555          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04556          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04557          p->subs[index].f.datalen = 1;
04558          *((char *) p->subs[index].f.data) = c;
04559          ast_mutex_unlock(&p->lock);
04560          return &p->subs[index].f;
04561       }
04562    }
04563    if (p->callwaitingrepeat)
04564       p->callwaitingrepeat--;
04565    if (p->cidcwexpire)
04566       p->cidcwexpire--;
04567    /* Repeat callwaiting */
04568    if (p->callwaitingrepeat == 1) {
04569       p->callwaitrings++;
04570       zt_callwait(ast);
04571    }
04572    /* Expire CID/CW */
04573    if (p->cidcwexpire == 1) {
04574       if (option_verbose > 2)
04575          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
04576       restore_conference(p);
04577    }
04578    if (p->subs[index].linear) {
04579       p->subs[index].f.datalen = READ_SIZE * 2;
04580    } else 
04581       p->subs[index].f.datalen = READ_SIZE;
04582 
04583    /* Handle CallerID Transmission */
04584    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
04585       send_callerid(p);
04586    }
04587 
04588    p->subs[index].f.frametype = AST_FRAME_VOICE;
04589    p->subs[index].f.subclass = ast->rawreadformat;
04590    p->subs[index].f.samples = READ_SIZE;
04591    p->subs[index].f.mallocd = 0;
04592    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04593    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET/2;
04594 #if 0
04595    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
04596 #endif   
04597    if (p->dialing || /* Transmitting something */
04598       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
04599       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
04600       ) {
04601       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
04602          don't send anything */
04603       p->subs[index].f.frametype = AST_FRAME_NULL;
04604       p->subs[index].f.subclass = 0;
04605       p->subs[index].f.samples = 0;
04606       p->subs[index].f.mallocd = 0;
04607       p->subs[index].f.offset = 0;
04608       p->subs[index].f.data = NULL;
04609       p->subs[index].f.datalen= 0;
04610    }
04611    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
04612       /* Perform busy detection. etc on the zap line */
04613       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
04614       if (f) {
04615          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
04616             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
04617                /* Treat this as a "hangup" instead of a "busy" on the assumption that
04618                   a busy  */
04619                f = NULL;
04620             }
04621          } else if (f->frametype == AST_FRAME_DTMF) {
04622 #ifdef ZAPATA_PRI
04623             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
04624                /* Don't accept in-band DTMF when in overlap dial mode */
04625                f->frametype = AST_FRAME_NULL;
04626                f->subclass = 0;
04627             }
04628 #endif            
04629             /* DSP clears us of being pulse */
04630             p->pulsedial = 0;
04631          }
04632       }
04633    } else 
04634       f = &p->subs[index].f; 
04635    if (f && (f->frametype == AST_FRAME_DTMF)) {
04636       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
04637       if (p->confirmanswer) {
04638          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
04639          /* Upon receiving a DTMF digit, consider this an answer confirmation instead
04640             of a DTMF digit */
04641          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04642          p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04643          f = &p->subs[index].f;
04644          /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
04645          p->confirmanswer = 0;
04646       } else if (p->callwaitcas) {
04647          if ((f->subclass == 'A') || (f->subclass == 'D')) {
04648             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
04649             if (p->cidspill)
04650                free(p->cidspill);
04651             send_cwcidspill(p);
04652          }
04653          if ((f->subclass != 'm') && (f->subclass != 'u')) 
04654             p->callwaitcas = 0;
04655          p->subs[index].f.frametype = AST_FRAME_NULL;
04656          p->subs[index].f.subclass = 0;
04657          f = &p->subs[index].f;
04658       } else if (f->subclass == 'f') {
04659          /* Fax tone -- Handle and return NULL */
04660          if (!p->faxhandled) {
04661             p->faxhandled++;
04662             if (strcmp(ast->exten, "fax")) {
04663                const char *target_context = ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext;
04664 
04665                if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
04666                   if (option_verbose > 2)
04667                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
04668                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
04669                   pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
04670                   if (ast_async_goto(ast, target_context, "fax", 1))
04671                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
04672                } else
04673                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
04674             } else
04675                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
04676          } else
04677                ast_log(LOG_DEBUG, "Fax already handled\n");
04678          zt_confmute(p, 0);
04679          p->subs[index].f.frametype = AST_FRAME_NULL;
04680          p->subs[index].f.subclass = 0;
04681          f = &p->subs[index].f;
04682       } else if (f->subclass == 'm') {
04683          /* Confmute request */
04684          zt_confmute(p, 1);
04685          p->subs[index].f.frametype = AST_FRAME_NULL;
04686          p->subs[index].f.subclass = 0;
04687          f = &p->subs[index].f;     
04688       } else if (f->subclass == 'u') {
04689          /* Unmute */
04690          zt_confmute(p, 0);
04691          p->subs[index].f.frametype = AST_FRAME_NULL;
04692          p->subs[index].f.subclass = 0;
04693          f = &p->subs[index].f;     
04694       } else
04695          zt_confmute(p, 0);
04696    }
04697 
04698    /* If we have a fake_event, trigger exception to handle it */
04699    if (p->fake_event)
04700       ast_set_flag(ast, AST_FLAG_EXCEPTION);
04701 
04702    ast_mutex_unlock(&p->lock);
04703    return f;
04704 }

static struct ast_channel * zt_request const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

Definition at line 7567 of file chan_zap.c.

References AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), ast_strdupa, busy, CHAN_PSEUDO, iflist, lock, LOG_NOTICE, zt_pvt::next, zt_pvt::prev, round_robin, s, and strsep().

07568 {
07569    int oldformat;
07570    int groupmatch = 0;
07571    int channelmatch = -1;
07572    int roundrobin = 0;
07573    int callwait = 0;
07574    int busy = 0;
07575    struct zt_pvt *p;
07576    struct ast_channel *tmp = NULL;
07577    char *dest=NULL;
07578    int x;
07579    char *s;
07580    char opt=0;
07581    int res=0, y=0;
07582    int backwards = 0;
07583 #ifdef ZAPATA_PRI
07584    int crv;
07585    int bearer = -1;
07586    int trunkgroup;
07587    struct zt_pri *pri=NULL;
07588 #endif   
07589    struct zt_pvt *exit, *start, *end;
07590    ast_mutex_t *lock;
07591    int channelmatched = 0;
07592    int groupmatched = 0;
07593    
07594    /* Assume we're locking the iflock */
07595    lock = &iflock;
07596    start = iflist;
07597    end = ifend;
07598    /* We do signed linear */
07599    oldformat = format;
07600    format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
07601    if (!format) {
07602       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
07603       return NULL;
07604    }
07605    if (data) {
07606       dest = ast_strdupa((char *)data);
07607    } else {
07608       ast_log(LOG_WARNING, "Channel requested with no data\n");
07609       return NULL;
07610    }
07611    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07612       /* Retrieve the group number */
07613       char *stringp=NULL;
07614       stringp=dest + 1;
07615       s = strsep(&stringp, "/");
07616       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07617          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07618          return NULL;
07619       }
07620       groupmatch = 1 << x;
07621       if (toupper(dest[0]) == 'G') {
07622          if (dest[0] == 'G') {
07623             backwards = 1;
07624             p = ifend;
07625          } else
07626             p = iflist;
07627       } else {
07628          if (dest[0] == 'R') {
07629             backwards = 1;
07630             p = round_robin[x]?round_robin[x]->prev:ifend;
07631             if (!p)
07632                p = ifend;
07633          } else {
07634             p = round_robin[x]?round_robin[x]->next:iflist;
07635             if (!p)
07636                p = iflist;
07637          }
07638          roundrobin = 1;
07639       }
07640    } else {
07641       char *stringp=NULL;
07642       stringp=dest;
07643       s = strsep(&stringp, "/");
07644       p = iflist;
07645       if (!strcasecmp(s, "pseudo")) {
07646          /* Special case for pseudo */
07647          x = CHAN_PSEUDO;
07648          channelmatch = x;
07649       } 
07650 #ifdef ZAPATA_PRI
07651       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07652          if ((trunkgroup < 1) || (crv < 1)) {
07653             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07654             return NULL;
07655          }
07656          res--;
07657          for (x=0;x<NUM_SPANS;x++) {
07658             if (pris[x].trunkgroup == trunkgroup) {
07659                pri = pris + x;
07660                lock = &pri->lock;
07661                start = pri->crvs;
07662                end = pri->crvend;
07663                break;
07664             }
07665          }
07666          if (!pri) {
07667             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07668             return NULL;
07669          }
07670          channelmatch = crv;
07671          p = pris[x].crvs;
07672       }
07673 #endif   
07674       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07675          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07676          return NULL;
07677       } else {
07678          channelmatch = x;
07679       }
07680    }
07681    /* Search for an unowned channel */
07682    if (ast_mutex_lock(lock)) {
07683       ast_log(LOG_ERROR, "Unable to lock interface list???\n");
07684       return NULL;
07685    }
07686    exit = p;
07687    while(p && !tmp) {
07688       if (roundrobin)
07689          round_robin[x] = p;
07690 #if 0
07691       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07692 #endif
07693 
07694       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07695          if (option_debug)
07696             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07697             if (p->inalarm) 
07698                goto next;
07699 
07700          callwait = (p->owner != NULL);
07701 #ifdef ZAPATA_PRI
07702          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07703             if (p->sig != SIG_FXSKS) {
07704                /* Gotta find an actual channel to use for this
07705                   CRV if this isn't a callwait */
07706                bearer = pri_find_empty_chan(pri, 0);
07707                if (bearer < 0) {
07708                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07709                   p = NULL;
07710                   break;
07711                }
07712                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07713             } else {
07714                if (alloc_sub(p, 0)) {
07715                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07716                   p = NULL;
07717                   break;
07718                } else
07719                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07720                p->pri = pri;
07721             }
07722          }
07723 #endif         
07724          if (p->channel == CHAN_PSEUDO) {
07725             p = chandup(p);
07726             if (!p) {
07727                break;
07728             }
07729          }
07730          if (p->owner) {
07731             if (alloc_sub(p, SUB_CALLWAIT)) {
07732                p = NULL;
07733                break;
07734             }
07735          }
07736          p->outgoing = 1;
07737          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07738 #ifdef ZAPATA_PRI
07739          if (p->bearer) {
07740             /* Log owner to bearer channel, too */
07741             p->bearer->owner = tmp;
07742          }
07743 #endif         
07744          /* Make special notes */
07745          if (res > 1) {
07746             if (opt == 'c') {
07747                /* Confirm answer */
07748                p->confirmanswer = 1;
07749             } else if (opt == 'r') {
07750                /* Distinctive ring */
07751                if (res < 3)
07752                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07753                else
07754                   p->distinctivering = y;
07755             } else if (opt == 'd') {
07756                /* If this is an ISDN call, make it digital */
07757                p->digital = 1;
07758                if (tmp)
07759                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07760             } else {
07761                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07762             }
07763          }
07764          /* Note if the call is a call waiting call */
07765          if (tmp && callwait)
07766             tmp->cdrflags |= AST_CDR_CALLWAIT;
07767          break;
07768       }
07769 next:
07770       if (backwards) {
07771          p = p->prev;
07772          if (!p)
07773             p = end;
07774       } else {
07775          p = p->next;
07776          if (!p)
07777             p = start;
07778       }
07779       /* stop when you roll to the one that we started from */
07780       if (p == exit)
07781          break;
07782    }
07783    ast_mutex_unlock(lock);
07784    restart_monitor();
07785    if (callwait)
07786       *cause = AST_CAUSE_BUSY;
07787    else if (!tmp) {
07788       if (channelmatched) {
07789          if (busy)
07790             *cause = AST_CAUSE_BUSY;
07791       } else if (groupmatched) {
07792          *cause = AST_CAUSE_CONGESTION;
07793       }
07794    }
07795       
07796    return tmp;
07797 }

static int zt_ring_phone struct zt_pvt p  )  [static]
 

Definition at line 3303 of file chan_zap.c.

References ast_log(), SUB_REAL, and zt_pvt::subs.

Referenced by __zt_exception(), and zt_handle_event().

03304 {
03305    int x;
03306    int res;
03307    /* Make sure our transmit state is on hook */
03308    x = 0;
03309    x = ZT_ONHOOK;
03310    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03311    do {
03312       x = ZT_RING;
03313       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03314 #if 0
03315       printf("Res: %d, error: %s\n", res, strerror(errno));
03316 #endif                  
03317       if (res) {
03318          switch(errno) {
03319          case EBUSY:
03320          case EINTR:
03321             /* Wait just in case */
03322             usleep(10000);
03323             continue;
03324          case EINPROGRESS:
03325             res = 0;
03326             break;
03327          default:
03328             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03329             res = 0;
03330          }
03331       }
03332    } while (res);
03333    return res;
03334 }

static int zt_sendtext struct ast_channel c,
const char *  text
[static]
 

Definition at line 11136 of file chan_zap.c.

References ASCII_BYTES_PER_CHAR, AST_LAW, ast_log(), END_SILENCE_LEN, HEADER_LEN, HEADER_MS, malloc, zt_pvt::mate, PUT_CLID, PUT_CLID_MARKMS, zt_pvt::tdd, TDD_BYTES_PER_CHAR, ast_channel::tech_pvt, and zt_get_index().

11137 {
11138 #define  END_SILENCE_LEN 400
11139 #define  HEADER_MS 50
11140 #define  TRAILER_MS 5
11141 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11142 #define  ASCII_BYTES_PER_CHAR 80
11143 
11144    unsigned char *buf,*mybuf;
11145    struct zt_pvt *p = c->tech_pvt;
11146    struct pollfd fds[1];
11147    int size,res,fd,len,x;
11148    int bytes=0;
11149    /* Initial carrier (imaginary) */
11150    float cr = 1.0;
11151    float ci = 0.0;
11152    float scont = 0.0;
11153    int index;
11154 
11155    index = zt_get_index(c, p, 0);
11156    if (index < 0) {
11157       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
11158       return -1;
11159    }
11160    if (!text[0]) return(0); /* if nothing to send, dont */
11161    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
11162    if (p->mate) 
11163       buf = malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
11164    else
11165       buf = malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
11166    if (!buf) {
11167       ast_log(LOG_ERROR, "MALLOC FAILED\n");
11168       return -1;
11169    }
11170    mybuf = buf;
11171    if (p->mate) {
11172       int codec = AST_LAW(p);
11173       for (x=0;x<HEADER_MS;x++) {   /* 50 ms of Mark */
11174          PUT_CLID_MARKMS;
11175          }
11176       /* Put actual message */
11177       for (x=0;text[x];x++)  {
11178          PUT_CLID(text[x]);
11179          }
11180       for (x=0;x<TRAILER_MS;x++) {  /* 5 ms of Mark */
11181          PUT_CLID_MARKMS;
11182          }
11183       len = bytes;
11184       buf = mybuf;
11185    }
11186    else {
11187       len = tdd_generate(p->tdd,buf,text);
11188       if (len < 1) {
11189          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n",(int)strlen(text));
11190          free(mybuf);
11191          return -1;
11192       }
11193    }
11194    memset(buf + len,0x7f,END_SILENCE_LEN);
11195    len += END_SILENCE_LEN;
11196    fd = p->subs[index].zfd;
11197    while(len) {
11198       if (ast_check_hangup(c)) {
11199          free(mybuf);
11200          return -1;
11201       }
11202       size = len;
11203       if (size > READ_SIZE)
11204          size = READ_SIZE;
11205       fds[0].fd = fd;
11206       fds[0].events = POLLOUT | POLLPRI;
11207       fds[0].revents = 0;
11208       res = poll(fds, 1, -1);
11209       if (!res) {
11210          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11211          continue;
11212       }
11213         /* if got exception */
11214       if (fds[0].revents & POLLPRI) return -1;
11215       if (!(fds[0].revents & POLLOUT)) {
11216          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11217          continue;
11218       }
11219       res = write(fd, buf, size);
11220       if (res != size) {
11221          if (res == -1) {
11222             free(mybuf);
11223             return -1;
11224          }
11225          if (option_debug)
11226             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11227          break;
11228       }
11229       len -= size;
11230       buf += size;
11231    }
11232    free(mybuf);
11233    return(0);
11234 }

static int zt_set_hook int  fd,
int  hs
[inline, static]
 

Definition at line 1586 of file chan_zap.c.

References ast_log(), and LOG_WARNING.

Referenced by __zt_exception(), handle_init_event(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().

01587 {
01588    int x, res;
01589    x = hs;
01590    res = ioctl(fd, ZT_HOOK, &x);
01591    if (res < 0) 
01592    {
01593       if (errno == EINPROGRESS) return 0;
01594       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01595    }
01596    return res;
01597 }

int zt_setlaw int  zfd,
int  law
 

Definition at line 948 of file chan_zap.c.

00949 {
00950    int res;
00951    res = ioctl(zfd, ZT_SETLAW, &law);
00952    if (res)
00953       return res;
00954    return 0;
00955 }

int zt_setlinear int  zfd,
int  linear
 

Definition at line 938 of file chan_zap.c.

Referenced by send_callerid(), zt_hangup(), zt_new(), zt_read(), and zt_write().

00939 {
00940    int res;
00941    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00942    if (res)
00943       return res;
00944    return 0;
00945 }

static int zt_setoption struct ast_channel chan,
int  option,
void *  data,
int  datalen
[static]
 

Definition at line 2736 of file chan_zap.c.

References ast_check_hangup(), ast_dsp_digitmode(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), zt_pvt::channel, zt_pvt::didtdd, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, pollfd::events, pollfd::fd, zt_pvt::law, LOG_DEBUG, LOG_WARNING, zt_pvt::mate, ast_channel::name, poll(), POLLOUT, POLLPRI, READ_SIZE, pollfd::revents, zt_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, zt_pvt::subs, zt_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech_pvt, zt_pvt::txgain, zt_subchannel::zfd, zt_disable_ec(), and zt_get_index().

02737 {
02738    char *cp;
02739    signed char *scp;
02740    int x;
02741    int index;
02742    struct zt_pvt *p = chan->tech_pvt;
02743 
02744    /* all supported options require data */
02745    if (!data || (datalen < 1)) {
02746       errno = EINVAL;
02747       return -1;
02748    }
02749 
02750    switch(option) {
02751    case AST_OPTION_TXGAIN:
02752       scp = (signed char *) data;
02753       index = zt_get_index(chan, p, 0);
02754       if (index < 0) {
02755          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02756          return -1;
02757       }
02758       ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02759       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02760    case AST_OPTION_RXGAIN:
02761       scp = (signed char *) data;
02762       index = zt_get_index(chan, p, 0);
02763       if (index < 0) {
02764          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
02765          return -1;
02766       }
02767       ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
02768       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
02769    case AST_OPTION_TONE_VERIFY:
02770       if (!p->dsp)
02771          break;
02772       cp = (char *) data;
02773       switch (*cp) {
02774       case 1:
02775          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
02776          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
02777          break;
02778       case 2:
02779          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
02780          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
02781          break;
02782       default:
02783          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
02784          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
02785          break;
02786       }
02787       break;
02788    case AST_OPTION_TDD:
02789       /* turn on or off TDD */
02790       cp = (char *) data;
02791       p->mate = 0;
02792       if (!*cp) { /* turn it off */
02793          ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
02794          if (p->tdd) tdd_free(p->tdd);
02795          p->tdd = 0;
02796          break;
02797       }
02798       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
02799          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
02800       zt_disable_ec(p);
02801       /* otherwise, turn it on */
02802       if (!p->didtdd) { /* if havent done it yet */
02803          unsigned char mybuf[41000],*buf;
02804          int size,res,fd,len;
02805          struct pollfd fds[1];
02806 
02807          buf = mybuf;
02808          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
02809          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
02810          len = 40000;
02811          index = zt_get_index(chan, p, 0);
02812          if (index < 0) {
02813             ast_log(LOG_WARNING, "No index in TDD?\n");
02814             return -1;
02815          }
02816          fd = p->subs[index].zfd;
02817          while(len) {
02818             if (ast_check_hangup(chan)) return -1;
02819             size = len;
02820             if (size > READ_SIZE)
02821                size = READ_SIZE;
02822             fds[0].fd = fd;
02823             fds[0].events = POLLPRI | POLLOUT;
02824             fds[0].revents = 0;
02825             res = poll(fds, 1, -1);
02826             if (!res) {
02827                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
02828                continue;
02829             }
02830             /* if got exception */
02831             if (fds[0].revents & POLLPRI) return -1;
02832             if (!(fds[0].revents & POLLOUT)) {
02833                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
02834                continue;
02835             }
02836             res = write(fd, buf, size);
02837             if (res != size) {
02838                if (res == -1) return -1;
02839                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
02840                break;
02841             }
02842             len -= size;
02843             buf += size;
02844          }
02845          p->didtdd = 1; /* set to have done it now */    
02846       }
02847       if (*cp == 2) { /* Mate mode */
02848          if (p->tdd) tdd_free(p->tdd);
02849          p->tdd = 0;
02850          p->mate = 1;
02851          break;
02852       }     
02853       if (!p->tdd) { /* if we dont have one yet */
02854          p->tdd = tdd_new(); /* allocate one */
02855       }     
02856       break;
02857    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
02858       if (!p->dsp)
02859          break;
02860       cp = (char *) data;
02861       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
02862          *cp ? "ON" : "OFF", (int) *cp, chan->name);
02863       ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
02864       break;
02865    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
02866       cp = (char *) data;
02867       if (!*cp) {    
02868          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
02869          x = 0;
02870          zt_disable_ec(p);
02871       } else {    
02872          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
02873          x = 1;
02874       }
02875       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
02876          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
02877       break;
02878    }
02879    errno = 0;
02880 
02881    return 0;
02882 }

static void zt_train_ec struct zt_pvt p  )  [static]
 

Definition at line 1419 of file chan_zap.c.

References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echotraining, LOG_DEBUG, LOG_WARNING, SUB_REAL, and zt_pvt::subs.

Referenced by zt_answer(), and zt_handle_event().

01420 {
01421    int x;
01422    int res;
01423    if (p && p->echocancel && p->echotraining) {
01424       x = p->echotraining;
01425       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01426       if (res) 
01427          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01428       else {
01429          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01430       }
01431    } else
01432       ast_log(LOG_DEBUG, "No echo training requested\n");
01433 }

static void zt_unlink struct zt_pvt slave,
struct zt_pvt master,
int  needlock
[static]
 

Definition at line 2884 of file chan_zap.c.

References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), conf_del(), zt_pvt::lock, LOG_DEBUG, master, and SUB_REAL.

Referenced by zt_fixup().

02885 {
02886    /* Unlink a specific slave or all slaves/masters from a given master */
02887    int x;
02888    int hasslaves;
02889    if (!master)
02890       return;
02891    if (needlock) {
02892       ast_mutex_lock(&master->lock);
02893       if (slave) {
02894          while(ast_mutex_trylock(&slave->lock)) {
02895             ast_mutex_unlock(&master->lock);
02896             usleep(1);
02897             ast_mutex_lock(&master->lock);
02898          }
02899       }
02900    }
02901    hasslaves = 0;
02902    for (x=0;x<MAX_SLAVES;x++) {
02903       if (master->slaves[x]) {
02904          if (!slave || (master->slaves[x] == slave)) {
02905             /* Take slave out of the conference */
02906             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
02907             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
02908             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
02909             master->slaves[x]->master = NULL;
02910             master->slaves[x] = NULL;
02911          } else
02912             hasslaves = 1;
02913       }
02914       if (!hasslaves)
02915          master->inconference = 0;
02916    }
02917    if (!slave) {
02918       if (master->master) {
02919          /* Take master out of the conference */
02920          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
02921          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
02922          hasslaves = 0;
02923          for (x=0;x<MAX_SLAVES;x++) {
02924             if (master->master->slaves[x] == master)
02925                master->master->slaves[x] = NULL;
02926             else if (master->master->slaves[x])
02927                hasslaves = 1;
02928          }
02929          if (!hasslaves)
02930             master->master->inconference = 0;
02931       }
02932       master->master = NULL;
02933    }
02934    update_conf(master);
02935    if (needlock) {
02936       if (slave)
02937          ast_mutex_unlock(&slave->lock);
02938       ast_mutex_unlock(&master->lock);
02939    }
02940 }

static int zt_wait_event int  fd  )  [inline, static]
 

Avoid the silly zt_waitevent which ignores a bunch of events.

Definition at line 369 of file chan_zap.c.

Referenced by flash_exec(), and ss_thread().

00370 {
00371    int i,j=0;
00372    i = ZT_IOMUX_SIGEVENT;
00373    if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1;
00374    if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
00375    return j;
00376 }

static int zt_wink struct zt_pvt p,
int  index
[static]
 

Definition at line 5184 of file chan_zap.c.

References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().

Referenced by ss_thread().

05185 {
05186    int j;
05187    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05188    for(;;)
05189    {
05190          /* set bits of interest */
05191       j = ZT_IOMUX_SIGEVENT;
05192           /* wait for some happening */
05193       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05194          /* exit loop if we have it */
05195       if (j & ZT_IOMUX_SIGEVENT) break;
05196    }
05197      /* get the event info */
05198    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05199    return 0;
05200 }

static int zt_write struct ast_channel ast,
struct ast_frame frame
[static]
 

Definition at line 4729 of file chan_zap.c.

References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, zt_pvt::dialing, zt_pvt::digital, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, my_zt_write(), ast_channel::name, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_setlinear().

04730 {
04731    struct zt_pvt *p = ast->tech_pvt;
04732    int res;
04733    unsigned char outbuf[4096];
04734    int index;
04735    index = zt_get_index(ast, p, 0);
04736    if (index < 0) {
04737       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
04738       return -1;
04739    }
04740 
04741 #if 0
04742 #ifdef ZAPATA_PRI
04743    ast_mutex_lock(&p->lock);
04744    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04745       if (p->pri->pri) {      
04746          if (!pri_grab(p, p->pri)) {
04747                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04748                pri_rel(p->pri);
04749          } else
04750                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04751       }
04752       p->proceeding=1;
04753    }
04754    ast_mutex_unlock(&p->lock);
04755 #endif
04756 #endif
04757    /* Write a frame of (presumably voice) data */
04758    if (frame->frametype != AST_FRAME_VOICE) {
04759       if (frame->frametype != AST_FRAME_IMAGE)
04760          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
04761       return 0;
04762    }
04763    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
04764        (frame->subclass != AST_FORMAT_ULAW) &&
04765        (frame->subclass != AST_FORMAT_ALAW)) {
04766       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
04767       return -1;
04768    }
04769    if (p->dialing) {
04770       if (option_debug)
04771          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
04772       return 0;
04773    }
04774    if (!p->owner) {
04775       if (option_debug)
04776          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
04777       return 0;
04778    }
04779    if (p->cidspill) {
04780       if (option_debug)
04781          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
04782       return 0;
04783    }
04784    /* Return if it's not valid data */
04785    if (!frame->data || !frame->datalen)
04786       return 0;
04787    if (frame->datalen > sizeof(outbuf) * 2) {
04788       ast_log(LOG_WARNING, "Frame too large\n");
04789       return 0;
04790    }
04791 
04792    if (frame->subclass == AST_FORMAT_SLINEAR) {
04793       if (!p->subs[index].linear) {
04794          p->subs[index].linear = 1;
04795          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04796          if (res)
04797             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
04798       }
04799       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
04800    } else {
04801       /* x-law already */
04802       if (p->subs[index].linear) {
04803          p->subs[index].linear = 0;
04804          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04805          if (res)
04806             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
04807       }
04808       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
04809    }
04810    if (res < 0) {
04811       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
04812       return -1;
04813    } 
04814    return 0;
04815 }


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] = "" [static]
 

Definition at line 269 of file chan_zap.c.

int adsi = 0 [static]
 

Definition at line 275 of file chan_zap.c.

int alarm
 

Definition at line 1085 of file chan_zap.c.

Referenced by action_zapshowchannels().

struct { ... } alarms[] [static]
 

Referenced by alarm2str(), and zap_show_status().

int amaflags = 0 [static]
 

Definition at line 273 of file chan_zap.c.

int answeronpolarityswitch = 0 [static]
 

Whether we answer on a Polarity Switch event.

Definition at line 335 of file chan_zap.c.

int busy_quietlength = 0 [static]
 

Definition at line 265 of file chan_zap.c.

int busy_tonelength = 0 [static]
 

Definition at line 264 of file chan_zap.c.

int busycount = 3 [static]
 

Definition at line 263 of file chan_zap.c.

int busydetect = 0 [static]
 

Definition at line 261 of file chan_zap.c.

struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static]
 

Definition at line 756 of file chan_zap.c.

int callprogress = 0 [static]
 

Definition at line 267 of file chan_zap.c.

int callreturn = 0 [static]
 

Definition at line 237 of file chan_zap.c.

int callwaiting = 0 [static]
 

Definition at line 227 of file chan_zap.c.

int callwaitingcallerid = 0 [static]
 

Definition at line 229 of file chan_zap.c.

int cancallforward = 0 [static]
 

Definition at line 245 of file chan_zap.c.

int canpark = 0 [static]
 

Definition at line 243 of file chan_zap.c.

char cid_name[256] = "" [static]
 

Definition at line 200 of file chan_zap.c.

char cid_num[256] = "" [static]
 

Definition at line 199 of file chan_zap.c.

int cid_signalling = CID_SIG_BELL [static]
 

Definition at line 213 of file chan_zap.c.

int cid_start = CID_START_RING [static]
 

Definition at line 214 of file chan_zap.c.

int cidrings[NUM_CADENCE_MAX] [static]
 

cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.

Definition at line 769 of file chan_zap.c.

const char config[] = "zapata.conf" [static]
 

Definition at line 160 of file chan_zap.c.

char context[AST_MAX_CONTEXT] = "default" [static]
 

Definition at line 198 of file chan_zap.c.

ast_group_t cur_callergroup = 0 [static]
 

Definition at line 219 of file chan_zap.c.

int cur_debounce = -1 [static]
 

Definition at line 286 of file chan_zap.c.

int cur_flash = -1 [static]
 

Definition at line 282 of file chan_zap.c.

ast_group_t cur_group = 0 [static]
 

Definition at line 218 of file chan_zap.c.

ast_group_t cur_pickupgroup = 0 [static]
 

Definition at line 220 of file chan_zap.c.

int cur_preflash = -1 [static]
 

Definition at line 280 of file chan_zap.c.

int cur_prewink = -1 [static]
 

Definition at line 279 of file chan_zap.c.

int cur_priexclusive = 0 [static]
 

Definition at line 287 of file chan_zap.c.

int cur_rxflash = -1 [static]
 

Definition at line 285 of file chan_zap.c.

int cur_rxwink = -1 [static]
 

Definition at line 284 of file chan_zap.c.

int cur_signalling = -1 [static]
 

Definition at line 216 of file chan_zap.c.

int cur_start = -1 [static]
 

Definition at line 283 of file chan_zap.c.

int cur_wink = -1 [static]
 

Definition at line 281 of file chan_zap.c.

char defaultcic[64] = "" [static]
 

Definition at line 201 of file chan_zap.c.

char defaultozz[64] = "" [static]
 

Definition at line 202 of file chan_zap.c.

const char desc[] = "Zapata Telephony" [static]
 

Definition at line 141 of file chan_zap.c.

char destroy_channel_usage[] [static]
 

Initial value:

   "Usage: zap destroy channel <chan num>\n"
   "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n"

Definition at line 10004 of file chan_zap.c.

struct zt_distRings drings [static]
 

Definition at line 482 of file chan_zap.c.

int echocanbridged = 0 [static]
 

Definition at line 259 of file chan_zap.c.

int echocancel [static]
 

Definition at line 253 of file chan_zap.c.

int echotraining [static]
 

Definition at line 255 of file chan_zap.c.

Referenced by fill_defaults(), misdn_cfg_get(), and misdn_cfg_get_config_string().

char* events[] [static]
 

Definition at line 1062 of file chan_zap.c.

Referenced by authenticate(), event2str(), and geteventbyname().

int firstdigittimeout = 16000 [static]
 

Wait up to 16 seconds for first digit (FXO logic).

Definition at line 313 of file chan_zap.c.

int gendigittimeout = 8000 [static]
 

How long to wait for following digits (FXO logic).

Definition at line 316 of file chan_zap.c.

int hanguponpolarityswitch = 0 [static]
 

Whether we hang up on a Polarity Switch event.

Definition at line 338 of file chan_zap.c.

int hidecallerid = 0 [static]
 

Definition at line 231 of file chan_zap.c.

int ifcount = 0 [static]
 

Definition at line 328 of file chan_zap.c.

struct zt_pvt * ifend [static]
 

Referenced by __build_step().

struct zt_pvt * iflist [static]
 

int immediate = 0 [static]
 

Definition at line 223 of file chan_zap.c.

char language[MAX_LANGUAGE] = "" [static]
 

Definition at line 204 of file chan_zap.c.

char mailbox[AST_MAX_EXTENSION] [static]
 

Definition at line 271 of file chan_zap.c.

int matchdigittimeout = 3000 [static]
 

How long to wait for an extra digit, if there is an ambiguous match.

Definition at line 319 of file chan_zap.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]
 

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 352 of file chan_zap.c.

char musicclass[MAX_MUSICCLASS] = "" [static]
 

Definition at line 205 of file chan_zap.c.

char* name
 

Definition at line 1086 of file chan_zap.c.

int num_cadence = 4 [static]
 

Definition at line 753 of file chan_zap.c.

int numbufs = 4 [static]
 

Definition at line 277 of file chan_zap.c.

int polarityonanswerdelay = 600 [static]
 

How long (ms) to ignore Polarity Switch events after we answer a call.

Definition at line 341 of file chan_zap.c.

int priindication_oob = 0 [static]
 

Definition at line 289 of file chan_zap.c.

char progzone[10] = "" [static]
 

Definition at line 206 of file chan_zap.c.

int pulse [static]
 

Definition at line 257 of file chan_zap.c.

int receivedRingT
 

Used to find out what ringtone we are on

Definition at line 763 of file chan_zap.c.

int relaxdtmf = 0 [static]
 

Definition at line 221 of file chan_zap.c.

int restrictcid = 0 [static]
 

Definition at line 233 of file chan_zap.c.

int ringt_base = DEFAULT_RINGT [static]
 

Definition at line 397 of file chan_zap.c.

struct zt_pvt* round_robin[32]
 

Definition at line 730 of file chan_zap.c.

Referenced by zt_request().

float rxgain = 0.0 [static]
 

Definition at line 247 of file chan_zap.c.

Referenced by fill_defaults(), load_module(), misdn_cfg_get(), misdn_cfg_get_config_string(), and misdn_set_opt_exec().

int sendcalleridafter = DEFAULT_CIDRINGS [static]
 

When to send the CallerID signals (rings).

Definition at line 344 of file chan_zap.c.

char show_channel_usage[] [static]
 

Initial value:

   "Usage: zap show channel <chan num>\n"
   "  Detailed information about a given channel\n"

Definition at line 9996 of file chan_zap.c.

char show_channels_usage[] [static]
 

Initial value:

   "Usage: zap show channels\n"
   "  Shows a list of available channels\n"

Definition at line 9992 of file chan_zap.c.

int stripmsd = 0 [static]
 

Definition at line 225 of file chan_zap.c.

char* subnames[] [static]
 

Initial value:

 {
   "Real",
   "Callwait",
   "Threeway"
}

Definition at line 495 of file chan_zap.c.

const char tdesc[] = "Zapata Telephony Driver" [static]
 

Definition at line 150 of file chan_zap.c.

int threewaycalling = 0 [static]
 

Definition at line 239 of file chan_zap.c.

int tonezone = -1 [static]
 

Definition at line 251 of file chan_zap.c.

int transfer = 0 [static]
 

Definition at line 241 of file chan_zap.c.

int transfertobusy = 1 [static]
 

Definition at line 210 of file chan_zap.c.

float txgain = 0.0 [static]
 

Definition at line 249 of file chan_zap.c.

Referenced by fill_defaults(), load_module(), misdn_cfg_get(), misdn_cfg_get_config_string(), and misdn_set_opt_exec().

const char type[] = "Zap" [static]
 

Definition at line 159 of file chan_zap.c.

int use_callerid = 1 [static]
 

Definition at line 212 of file chan_zap.c.

int use_callingpres = 0 [static]
 

Definition at line 235 of file chan_zap.c.

Referenced by fill_defaults(), misdn_cfg_get(), and misdn_cfg_get_config_string().

int usecnt = 0 [static]
 

Definition at line 321 of file chan_zap.c.

int usedistinctiveringdetection = 0 [static]
 

Definition at line 208 of file chan_zap.c.

int user_has_defined_cadences = 0 [static]
 

Definition at line 754 of file chan_zap.c.

struct ast_cli_entry zap_cli[] [static]
 

Definition at line 10012 of file chan_zap.c.

char zap_restart_usage[] [static]
 

Initial value:

   "Usage: zap restart\n"
   "  fully restarts the zaptel channels: destroys them all and then re-reads from config.\n"

Definition at line 10008 of file chan_zap.c.

char zap_show_cadences_help[] [static]
 

Initial value:

"Usage: zap show cadences\n"
"       Shows all cadences currently defined\n"

Definition at line 9900 of file chan_zap.c.

char zap_show_status_usage[] [static]
 

Initial value:

   "Usage: zap show status\n"
   "       Shows a list of Zaptel cards with status\n"

Definition at line 10000 of file chan_zap.c.

const struct ast_channel_tech zap_tech [static]
 

Definition at line 705 of file chan_zap.c.

Referenced by zt_new().

int zaptrcallerid = 0 [static]
 

Definition at line 215 of file chan_zap.c.


Generated on Sat Mar 24 23:27:26 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6