Sun Aug 6 15:06:36 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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.

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 *   name
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 do_monitor(), 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(), setup_zap(), 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.

Referenced by update_conf().

#define HANGUP   1
 

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

Referenced by mkintf().

#define MAX_SLAVES   4
 

Definition at line 521 of file chan_zap.c.

Referenced by isslavenative(), update_conf(), zap_show_channel(), zt_link(), and zt_unlink().

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

Referenced by setup_zap().

#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(), setup_zap(), zt_callwait(), zt_open(), zt_read(), zt_sendtext(), and zt_setoption().

#define sig2str   zap_sig2str
 

Definition at line 1200 of file chan_zap.c.

Referenced by action_zapshowchannels(), handle_init_event(), mkintf(), setup_zap(), ss_thread(), zap_show_channel(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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 mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), setup_zap(), 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(), mkintf(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), and zt_request().

#define SIG_FXSLS   ZT_SIG_FXSLS
 

Definition at line 169 of file chan_zap.c.

Referenced by available(), handle_init_event(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), and zap_sig2str().

#define SIG_GR303FXSKS   (0x0100000 | ZT_SIG_FXSKS)
 

Definition at line 184 of file chan_zap.c.

Referenced by handle_init_event(), mkintf(), setup_zap(), and zap_sig2str().

#define SIG_PRI   ZT_SIG_CLEAR
 

Definition at line 175 of file chan_zap.c.

Referenced by handle_init_event(), mkintf(), setup_zap(), 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 mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), setup_zap(), 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(), mkintf(), 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(), mkintf(), 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(), mkintf(), setup_zap(), 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
 

Referenced by zt_sendtext().

#define TRANSFER   0
 

Definition at line 10001 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 10178 of file chan_zap.c.

References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_verbose(), zt_pvt::cidspill, destroy_zt_pvt(), free, ifcount, iflist, master, monitor_thread, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_close().

10179 {
10180    int x = 0;
10181    struct zt_pvt *p, *pl;
10182 #ifdef ZAPATA_PRI
10183    int i;
10184    for(i=0;i<NUM_SPANS;i++) {
10185       if (pris[i].master != AST_PTHREADT_NULL) 
10186          pthread_cancel(pris[i].master);
10187    }
10188    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
10189 #endif
10190 #ifdef ZAPATA_R2
10191    ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
10192 #endif
10193    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
10194    ast_manager_unregister( "ZapDialOffhook" );
10195    ast_manager_unregister( "ZapHangup" );
10196    ast_manager_unregister( "ZapTransfer" );
10197    ast_manager_unregister( "ZapDNDoff" );
10198    ast_manager_unregister( "ZapDNDon" );
10199    ast_manager_unregister("ZapShowChannels");
10200    ast_channel_unregister(&zap_tech);
10201    if (!ast_mutex_lock(&iflock)) {
10202       /* Hangup all interfaces if they have an owner */
10203       p = iflist;
10204       while(p) {
10205          if (p->owner)
10206             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10207          p = p->next;
10208       }
10209       ast_mutex_unlock(&iflock);
10210    } else {
10211       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10212       return -1;
10213    }
10214    if (!ast_mutex_lock(&monlock)) {
10215       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10216          pthread_cancel(monitor_thread);
10217          pthread_kill(monitor_thread, SIGURG);
10218          pthread_join(monitor_thread, NULL);
10219       }
10220       monitor_thread = AST_PTHREADT_STOP;
10221       ast_mutex_unlock(&monlock);
10222    } else {
10223       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10224       return -1;
10225    }
10226 
10227    if (!ast_mutex_lock(&iflock)) {
10228       /* Destroy all the interfaces and free their memory */
10229       p = iflist;
10230       while(p) {
10231          /* Free any callerid */
10232          if (p->cidspill)
10233             free(p->cidspill);
10234          /* Close the zapata thingy */
10235          if (p->subs[SUB_REAL].zfd > -1)
10236             zt_close(p->subs[SUB_REAL].zfd);
10237          pl = p;
10238          p = p->next;
10239          x++;
10240          /* Free associated memory */
10241          if(pl)
10242             destroy_zt_pvt(&pl);
10243          ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10244       }
10245       iflist = NULL;
10246       ifcount = 0;
10247       ast_mutex_unlock(&iflock);
10248    } else {
10249       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10250       return -1;
10251    }
10252 #ifdef ZAPATA_PRI    
10253    for(i=0;i<NUM_SPANS;i++) {
10254       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10255          pthread_join(pris[i].master, NULL);
10256       zt_close(pris[i].fds[i]);
10257    }
10258 #endif
10259    return 0;
10260 }

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

Definition at line 4262 of file chan_zap.c.

References ast_channel::_state, ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_moh_stop(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cidcwexpire, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, event2str(), zt_subchannel::f, zt_pvt::fake_event, ast_channel::fds, zt_pvt::flashtime, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, ast_channel::name, zt_subchannel::needanswer, 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().

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

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

Definition at line 10068 of file chan_zap.c.

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

Referenced by load_module().

10069 {
10070    struct zt_pvt *p = NULL;
10071    char *channel = astman_get_header(m, "ZapChannel");
10072    if (ast_strlen_zero(channel)) {
10073       astman_send_error(s, m, "No channel specified");
10074       return 0;
10075    }
10076    p = find_channel(atoi(channel));
10077    if (!p) {
10078       astman_send_error(s, m, "No such channel");
10079       return 0;
10080    }
10081    zap_fake_event(p,TRANSFER);
10082    astman_send_ack(s, m, "ZapTransfer");
10083    return 0;
10084 }

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

Definition at line 10086 of file chan_zap.c.

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

Referenced by load_module().

10087 {
10088    struct zt_pvt *p = NULL;
10089    char *channel = astman_get_header(m, "ZapChannel");
10090    if (ast_strlen_zero(channel)) {
10091       astman_send_error(s, m, "No channel specified");
10092       return 0;
10093    }
10094    p = find_channel(atoi(channel));
10095    if (!p) {
10096       astman_send_error(s, m, "No such channel");
10097       return 0;
10098    }
10099    zap_fake_event(p,HANGUP);
10100    astman_send_ack(s, m, "ZapHangup");
10101    return 0;
10102 }

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

Definition at line 10104 of file chan_zap.c.

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

Referenced by load_module().

10105 {
10106    struct zt_pvt *p = NULL;
10107    char *channel = astman_get_header(m, "ZapChannel");
10108    char *number = astman_get_header(m, "Number");
10109    int i;
10110    if (ast_strlen_zero(channel)) {
10111       astman_send_error(s, m, "No channel specified");
10112       return 0;
10113    }
10114    if (ast_strlen_zero(number)) {
10115       astman_send_error(s, m, "No number specified");
10116       return 0;
10117    }
10118    p = find_channel(atoi(channel));
10119    if (!p) {
10120       astman_send_error(s, m, "No such channel");
10121       return 0;
10122    }
10123    if (!p->owner) {
10124       astman_send_error(s, m, "Channel does not have it's owner");
10125       return 0;
10126    }
10127    for (i=0; i<strlen(number); i++) {
10128       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10129       zap_queue_frame(p, &f, NULL); 
10130    }
10131    astman_send_ack(s, m, "ZapDialOffhook");
10132    return 0;
10133 }

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

Definition at line 10050 of file chan_zap.c.

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

Referenced by load_module().

10051 {
10052     struct zt_pvt *p = NULL;
10053     char *channel = astman_get_header(m, "ZapChannel");
10054     if (ast_strlen_zero(channel)) {
10055         astman_send_error(s, m, "No channel specified");
10056         return 0;
10057     }
10058     p = find_channel(atoi(channel));
10059     if (!p) {
10060         astman_send_error(s, m, "No such channel");
10061         return 0;
10062     }
10063     p->dnd = 0;
10064     astman_send_ack(s, m, "DND Disabled");
10065     return 0;
10066 }

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

Definition at line 10032 of file chan_zap.c.

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

Referenced by load_module().

10033 {
10034     struct zt_pvt *p = NULL;
10035     char *channel = astman_get_header(m, "ZapChannel");
10036     if (ast_strlen_zero(channel)) {
10037         astman_send_error(s, m, "No channel specified");
10038         return 0;
10039     }
10040     p = find_channel(atoi(channel));
10041     if (!p) {
10042         astman_send_error(s, m, "No such channel");
10043         return 0;
10044     }
10045     p->dnd = 1;
10046     astman_send_ack(s, m, "DND Enabled");
10047     return 0;
10048 }

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

Definition at line 9663 of file chan_zap.c.

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

09664 {
09665    if (zap_restart() != 0) {
09666       astman_send_error(s, m, "Failed rereading zaptel configuration");
09667       return 1;
09668    }
09669    astman_send_ack(s, m, "ZapRestart: Success");
09670    return 0;
09671 }

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

Definition at line 10135 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, mansession::fd, get_alarms(), iflist, zt_pvt::next, zt_pvt::sig, and sig2str.

Referenced by load_module().

10136 {
10137    struct zt_pvt *tmp = NULL;
10138    char *id = astman_get_header(m, "ActionID");
10139    char idText[256] = "";
10140 
10141    astman_send_ack(s, m, "Zapata channel status will follow");
10142    if (!ast_strlen_zero(id))
10143       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10144 
10145    ast_mutex_lock(&iflock);
10146    
10147    tmp = iflist;
10148    while (tmp) {
10149       if (tmp->channel > 0) {
10150          int alarm = get_alarms(tmp);
10151          ast_cli(s->fd,
10152             "Event: ZapShowChannels\r\n"
10153             "Channel: %d\r\n"
10154             "Signalling: %s\r\n"
10155             "Context: %s\r\n"
10156             "DND: %s\r\n"
10157             "Alarm: %s\r\n"
10158             "%s"
10159             "\r\n",
10160             tmp->channel, sig2str(tmp->sig), tmp->context, 
10161             tmp->dnd ? "Enabled" : "Disabled",
10162             alarm2str(alarm), idText);
10163       } 
10164 
10165       tmp = tmp->next;
10166    }
10167 
10168    ast_mutex_unlock(&iflock);
10169    
10170    ast_cli(s->fd, 
10171       "Event: ZapShowChannelsComplete\r\n"
10172       "%s"
10173       "\r\n", 
10174       idText);
10175    return 0;
10176 }

static char* alarm2str int  alarm  )  [static]
 

Definition at line 1097 of file chan_zap.c.

References alarms.

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, numbufs, option_debug, subnames, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().

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

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 3336 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, LOG_WARNING, ast_channel::name, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), and unalloc_sub().

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

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

Definition at line 7375 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, LOG_WARNING, 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.

Referenced by zt_request().

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

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 7488 of file chan_zap.c.

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

Referenced by zt_request().

07489 {
07490    struct zt_pvt *p;
07491    ZT_BUFFERINFO bi;
07492    int res;
07493    p = malloc(sizeof(struct zt_pvt));
07494    if (p) {
07495       memcpy(p, src, sizeof(struct zt_pvt));
07496       ast_mutex_init(&p->lock);
07497       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07498       /* Allocate a zapata structure */
07499       if (p->subs[SUB_REAL].zfd < 0) {
07500          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07501          destroy_zt_pvt(&p);
07502          return NULL;
07503       }
07504       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07505       if (!res) {
07506          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07507          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07508          bi.numbufs = numbufs;
07509          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07510          if (res < 0) {
07511             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07512          }
07513       } else
07514          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07515    }
07516    p->destroy = 1;
07517    p->next = iflist;
07518    iflist = p;
07519    return p;
07520 }

static int check_for_conference struct zt_pvt p  )  [static]
 

Definition at line 3478 of file chan_zap.c.

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

Referenced by zt_handle_event().

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

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 update_conf(), and 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 11230 of file chan_zap.c.

References desc.

11231 {
11232    return (char *) desc;
11233 }

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

Definition at line 2172 of file chan_zap.c.

References destroy_zt_pvt(), ifend, iflist, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::prev, SUB_REAL, zt_pvt::subs, and zt_close().

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

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

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

Definition at line 2159 of file chan_zap.c.

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

Referenced by __unload_module(), chandup(), destroy_channel(), and mkintf().

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

static void disable_dtmf_detect struct zt_pvt p  )  [static]
 

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

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

static void* do_monitor void *  data  )  [static]
 

Definition at line 6537 of file chan_zap.c.

References ast_app_has_voicemail(), ast_fdisset(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), zt_pvt::channel, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, event2str(), pollfd::events, pollfd::fd, free, handle_init_event(), ifcount, iflist, last, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, MAX_CALLERID_SIZE, zt_pvt::msgstate, zt_pvt::next, option_debug, zt_pvt::owner, poll(), POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, vmwi_generate(), zt_subchannel::zfd, and zt_get_event().

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

static void enable_dtmf_detect struct zt_pvt p  )  [static]
 

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

Referenced by zt_bridge().

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

static char* event2str int  event  )  [static]
 

Definition at line 1107 of file chan_zap.c.

Referenced by __zt_exception(), do_monitor(), 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, AST_MULAW, and rxgain.

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, AST_MULAW, and txgain.

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 10020 of file chan_zap.c.

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

10021 {
10022    struct zt_pvt *p = iflist;
10023    while(p) {
10024       if (p->channel == channel) {
10025          break;
10026       }
10027       p = p->next;
10028    }
10029    return p;
10030 }

static int get_alarms struct zt_pvt p  )  [static]
 

Definition at line 3500 of file chan_zap.c.

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

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

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

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

Definition at line 6343 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, EVENT_FLAG_SYSTEM, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event(), 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().

Referenced by do_monitor().

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

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

Definition at line 9878 of file chan_zap.c.

References ast_cli(), cadences, cidrings, COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, num_cadence, and term_color().

09879 {
09880    int i, j;
09881    for (i=0;i<num_cadence;i++) {
09882       char output[1024];
09883       char tmp[16], tmp2[64];
09884       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
09885       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
09886 
09887       for (j=0;j<16;j++) {
09888          if (cadences[i].ringcadence[j] == 0)
09889             break;
09890          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
09891          if (cidrings[i] * 2 - 1 == j)
09892             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
09893          else
09894             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
09895          if (j != 0)
09896             strncat(output, ",", sizeof(output) - strlen(output) - 1);
09897          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
09898       }
09899       ast_cli(fd,"%s\n",output);
09900    }
09901    return 0;
09902 }

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::law, MAX_SLAVES, zt_pvt::slaves, 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 11235 of file chan_zap.c.

References ASTERISK_GPL_KEY.

11236 {
11237    return ASTERISK_GPL_KEY;
11238 }

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 11066 of file chan_zap.c.

References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zapshowchannels(), ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register, ast_mutex_init(), AST_PTHREADT_NULL, lock, LOG_ERROR, setup_zap(), and type.

11067 {
11068    int res;
11069 
11070 #ifdef ZAPATA_PRI
11071    int y,i;
11072    memset(pris, 0, sizeof(pris));
11073    for (y=0;y<NUM_SPANS;y++) {
11074       ast_mutex_init(&pris[y].lock);
11075       pris[y].offset = -1;
11076       pris[y].master = AST_PTHREADT_NULL;
11077       for (i=0;i<NUM_DCHANS;i++)
11078          pris[y].fds[i] = -1;
11079    }
11080    pri_set_error(zt_pri_error);
11081    pri_set_message(zt_pri_message);
11082 #endif
11083    res = setup_zap(0);
11084    /* Make sure we can register our Zap channel type */
11085    if(res) {
11086      return -1;
11087    }
11088    if (ast_channel_register(&zap_tech)) {
11089       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
11090       __unload_module();
11091       return -1;
11092    }
11093 #ifdef ZAPATA_PRI
11094    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
11095 #endif   
11096 #ifdef ZAPATA_R2
11097    ast_cli_register_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
11098 #endif   
11099    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
11100    
11101    memset(round_robin, 0, sizeof(round_robin));
11102    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11103    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11104    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11105    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11106    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11107    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11108 
11109    return res;
11110 }

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

Definition at line 6914 of file chan_zap.c.

References accountcode, zt_pvt::accountcode, adsi, zt_pvt::adsi, amaflags, zt_pvt::amaflags, answeronpolarityswitch, zt_pvt::answeronpolarityswitch, ast_dsp_digitmode(), ast_log(), ast_mutex_init(), ast_strlen_zero(), busy_quietlength, zt_pvt::busy_quietlength, busy_tonelength, zt_pvt::busy_tonelength, busycount, zt_pvt::busycount, busydetect, zt_pvt::busydetect, zt_pvt::callgroup, callprogress, zt_pvt::callprogress, callreturn, zt_pvt::callreturn, zt_pvt::callwaiting, callwaiting, callwaitingcallerid, zt_pvt::callwaitingcallerid, cancallforward, zt_pvt::cancallforward, canpark, zt_pvt::canpark, CHAN_PSEUDO, zt_pvt::channel, cid_name, zt_pvt::cid_name, cid_num, zt_pvt::cid_num, cid_signalling, zt_pvt::cid_signalling, cid_start, zt_pvt::cid_start, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, context, cur_callergroup, cur_debounce, cur_flash, cur_group, cur_pickupgroup, cur_preflash, cur_prewink, cur_priexclusive, cur_rxflash, cur_rxwink, cur_start, cur_wink, zt_pvt::defcontext, zt_pvt::destroy, destroy_zt_pvt(), zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, echocanbridged, zt_pvt::echocanbridged, echocancel, zt_pvt::echocancel, echotraining, zt_pvt::echotraining, zt_pvt::firstradio, zt_pvt::group, hanguponpolarityswitch, zt_pvt::hanguponpolarityswitch, zt_pvt::hidecallerid, hidecallerid, ifcount, ifend, iflist, immediate, zt_pvt::immediate, zt_pvt::inalarm, language, zt_pvt::language, zt_pvt::law, zt_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, zt_pvt::mailbox, malloc, MAX_CHANNELS, zt_pvt::msgstate, musicclass, zt_pvt::musicclass, zt_pvt::next, numbufs, zt_pvt::onhooktime, zt_pvt::overlapdial, zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::pickupgroup, polarityonanswerdelay, zt_pvt::polarityonanswerdelay, zt_pvt::prev, zt_pvt::priexclusive, priindication_oob, zt_pvt::priindication_oob, zt_pvt::propconfno, pulse, zt_pvt::pulse, zt_pvt::radio, relaxdtmf, restrictcid, zt_pvt::restrictcid, ringt_base, zt_pvt::ringt_base, rxgain, zt_pvt::rxgain, sendcalleridafter, zt_pvt::sendcalleridafter, set_actual_gain(), 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_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, stripmsd, zt_pvt::stripmsd, SUB_REAL, zt_pvt::subs, threewaycalling, zt_pvt::threewaycalling, tonezone, zt_pvt::tonezone, transfer, zt_pvt::transfer, transfertobusy, zt_pvt::transfertobusy, txgain, zt_pvt::txgain, update_conf(), use_callerid, zt_pvt::use_callerid, use_callingpres, zt_pvt::use_callingpres, usedistinctiveringdetection, zt_pvt::usedistinctiveringdetection, zaptrcallerid, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_close(), zt_open(), and zt_set_hook().

Referenced by setup_zap().

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

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

Definition at line 5161 of file chan_zap.c.

References ast_waitfordigit().

Referenced by ss_thread().

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

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

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

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

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 11213 of file chan_zap.c.

References ast_log(), and setup_zap().

11214 {
11215    int res = 0;
11216 
11217    res = setup_zap(1);
11218    if (res) {
11219       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11220       return -1;
11221    }
11222    return 0;
11223 }

static int reset_conf struct zt_pvt p  )  [static]
 

Definition at line 1317 of file chan_zap.c.

References ast_log(), LOG_WARNING, and SUB_REAL.

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 6762 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(), LOG_ERROR, LOG_WARNING, and monitor_thread.

06763 {
06764    pthread_attr_t attr;
06765    pthread_attr_init(&attr);
06766    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06767    /* If we're supposed to be stopped -- stay stopped */
06768    if (monitor_thread == AST_PTHREADT_STOP)
06769       return 0;
06770    if (ast_mutex_lock(&monlock)) {
06771       ast_log(LOG_WARNING, "Unable to lock monitor\n");
06772       return -1;
06773    }
06774    if (monitor_thread == pthread_self()) {
06775       ast_mutex_unlock(&monlock);
06776       ast_log(LOG_WARNING, "Cannot kill myself\n");
06777       return -1;
06778    }
06779    if (monitor_thread != AST_PTHREADT_NULL) {
06780       /* Just signal it to be sure it wakes up */
06781 #if 0
06782       pthread_cancel(monitor_thread);
06783 #endif
06784       pthread_kill(monitor_thread, SIGURG);
06785 #if 0
06786       pthread_join(monitor_thread, NULL);
06787 #endif
06788    } else {
06789       /* Start a new monitor */
06790       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
06791          ast_mutex_unlock(&monlock);
06792          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
06793          return -1;
06794       }
06795    }
06796    ast_mutex_unlock(&monlock);
06797    return 0;
06798 }

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 ss_thread(), and 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(), mkintf(), 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 10272 of file chan_zap.c.

References accountcode, adsi, amaflags, answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_get_group(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose(), busy_quietlength, busy_tonelength, busycount, busydetect, cadences, callprogress, callreturn, callwaiting, callwaitingcallerid, cancallforward, canpark, cfg, CHAN_PSEUDO, cid_name, cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_V23, cid_signalling, cid_start, CID_START_POLARITY, CID_START_RING, CID_START_USEHIST, cidrings, config, context, ringContextData::contextData, cur_callergroup, cur_debounce, cur_flash, cur_group, cur_pickupgroup, cur_preflash, cur_prewink, cur_priexclusive, cur_rxflash, cur_rxwink, cur_signalling, cur_start, cur_wink, defaultcic, defaultozz, DSP_DIGITMODE_RELAXDTMF, echocanbridged, echocancel, echotraining, hanguponpolarityswitch, hidecallerid, immediate, language, ast_variable::lineno, LOG_ERROR, mailbox, mkintf(), musicclass, ast_variable::name, ast_variable::next, num_cadence, NUM_CADENCE_MAX, numbufs, option_verbose, polarityonanswerdelay, priindication_oob, progzone, pulse, READ_SIZE, relaxdtmf, restart_monitor(), restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ringt_base, rxgain, sendcalleridafter, 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_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, stripmsd, strsep(), threewaycalling, tonezone, transfer, transfertobusy, txgain, use_callerid, use_callingpres, usedistinctiveringdetection, user_has_defined_cadences, ast_variable::value, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and zaptrcallerid.

Referenced by load_module(), reload(), and zap_restart().

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

static void * ss_thread void *  data  )  [static]
 

Definition at line 5198 of file chan_zap.c.

References ast_channel::_state, 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_FRAME_DTMF, 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_shrink_phone_number(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, 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_get_dtmf(), callerid_new(), zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_V23, zt_pvt::cid_signalling, cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, CID_START_USEHIST, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, dsp, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, firstdigittimeout, callerid_state::flags, ast_frame::frametype, free, gendigittimeout, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, ast_channel::language, zt_pvt::lastcid_num, callerid_state::len, zt_subchannel::linear, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), matchdigittimeout, my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, callerid_state::number, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, receivedRingT, restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, 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_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, 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_setlinear(), zt_wait_event(), and zt_wink().

Referenced by handle_init_event(), and zt_handle_event().

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

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 10262 of file chan_zap.c.

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

10263 {
10264 #ifdef ZAPATA_PRI    
10265    int y;
10266    for (y=0;y<NUM_SPANS;y++)
10267       ast_mutex_destroy(&pris[y].lock);
10268 #endif
10269    return __unload_module();
10270 }

static int update_conf struct zt_pvt p  )  [static]
 

Definition at line 1330 of file chan_zap.c.

References ast_log(), zt_pvt::channel, conf_add(), conf_del(), zt_pvt::confno, GET_CHANNEL, zt_pvt::inconference, zt_subchannel::inthreeway, isslavenative(), LOG_DEBUG, zt_pvt::master, MAX_SLAVES, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.

Referenced by __zt_exception(), mkintf(), zt_bridge(), zt_fixup(), zt_handle_event(), zt_hangup(), and zt_unlink().

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 11225 of file chan_zap.c.

References usecnt.

11226 {
11227    return usecnt;
11228 }

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(), and ast_queue_frame().

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

09610 {
09611    int channel = 0;
09612    struct zt_pvt *tmp = NULL;
09613    struct zt_pvt *prev = NULL;
09614    
09615    if (argc != 4) {
09616       return RESULT_SHOWUSAGE;
09617    }
09618    channel = atoi(argv[3]);
09619 
09620    tmp = iflist;
09621    while (tmp) {
09622       if (tmp->channel == channel) {
09623          destroy_channel(prev, tmp, 1);
09624          return RESULT_SUCCESS;
09625       }
09626       prev = tmp;
09627       tmp = tmp->next;
09628    }
09629    return RESULT_FAILURE;
09630 }

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

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

10005 {
10006    if (p) {
10007       switch(mode) {
10008          case TRANSFER:
10009             p->fake_event = ZT_EVENT_WINKFLASH;
10010             break;
10011          case HANGUP:
10012             p->fake_event = ZT_EVENT_ONHOOK;
10013             break;
10014          default:
10015             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10016       }
10017    }
10018    return 0;
10019 }

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(), and ast_queue_frame().

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 9633 of file chan_zap.c.

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

Referenced by action_zaprestart(), and zap_restart_cmd().

09634 {
09635    if (option_verbose > 0)
09636       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09637    while (iflist) {
09638       if (option_debug)
09639          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09640       /* Also updates iflist: */
09641       destroy_channel(NULL, iflist, 1);
09642    }
09643    if (option_debug)
09644       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09645    if (setup_zap(0) != 0) {
09646       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09647       return 1;
09648    }
09649    return 0;
09650 }

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

Definition at line 9652 of file chan_zap.c.

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

09653 {
09654    if (argc != 2) {
09655       return RESULT_SHOWUSAGE;
09656    }
09657 
09658    if (zap_restart() != 0)
09659       return RESULT_FAILURE;
09660    return RESULT_SUCCESS;
09661 }

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

Definition at line 9734 of file chan_zap.c.

References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::callwaitcas, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::destroy, zt_pvt::dialing, zt_pvt::dsp, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::exten, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, zt_pvt::lock, lock, zt_pvt::master, MAX_SLAVES, ast_channel::name, zt_pvt::next, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.

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

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

Definition at line 9673 of file chan_zap.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::context, zt_pvt::exten, FORMAT, FORMAT2, iflist, zt_pvt::language, zt_pvt::lock, lock, zt_pvt::musicclass, zt_pvt::next, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

09674 {
09675 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09676 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09677    struct zt_pvt *tmp = NULL;
09678    char tmps[20] = "";
09679    ast_mutex_t *lock;
09680    struct zt_pvt *start;
09681 #ifdef ZAPATA_PRI
09682    int trunkgroup;
09683    struct zt_pri *pri=NULL;
09684    int x;
09685 #endif
09686 
09687    lock = &iflock;
09688    start = iflist;
09689 
09690 #ifdef ZAPATA_PRI
09691    if (argc == 4) {
09692       if ((trunkgroup = atoi(argv[3])) < 1)
09693          return RESULT_SHOWUSAGE;
09694       for (x=0;x<NUM_SPANS;x++) {
09695          if (pris[x].trunkgroup == trunkgroup) {
09696             pri = pris + x;
09697             break;
09698          }
09699       }
09700       if (pri) {
09701          start = pri->crvs;
09702          lock = &pri->lock;
09703       } else {
09704          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09705          return RESULT_FAILURE;
09706       }
09707    } else
09708 #endif
09709    if (argc != 3)
09710       return RESULT_SHOWUSAGE;
09711 
09712    ast_mutex_lock(lock);
09713 #ifdef ZAPATA_PRI
09714    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MusicOnHold");
09715 #else
09716    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MusicOnHold");
09717 #endif   
09718    
09719    tmp = start;
09720    while (tmp) {
09721       if (tmp->channel > 0) {
09722          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09723       } else
09724          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09725       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->musicclass);
09726       tmp = tmp->next;
09727    }
09728    ast_mutex_unlock(lock);
09729    return RESULT_SUCCESS;
09730 #undef FORMAT
09731 #undef FORMAT2
09732 }

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

Definition at line 9905 of file chan_zap.c.

References alarms, ast_cli(), ast_log(), FORMAT, FORMAT2, RESULT_FAILURE, and RESULT_SUCCESS.

09905                                                            {
09906    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
09907    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
09908 
09909    int span;
09910    int res;
09911    char alarms[50];
09912 
09913    int ctl;
09914    ZT_SPANINFO s;
09915 
09916    ctl = open("/dev/zap/ctl", O_RDWR);
09917    if (ctl < 0) {
09918       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
09919       ast_cli(fd, "No Zaptel interface found.\n");
09920       return RESULT_FAILURE;
09921    }
09922    ast_cli(fd,FORMAT2, "Description", "Alarms","IRQ","bpviol","CRC4");
09923 
09924    for (span=1;span < ZT_MAX_SPANS;++span) {
09925       s.spanno = span;
09926       res = ioctl(ctl, ZT_SPANSTAT, &s);
09927       if (res) {
09928          continue;
09929       }
09930       alarms[0] = '\0';
09931       if (s.alarms > 0) {
09932          if (s.alarms & ZT_ALARM_BLUE)
09933             strcat(alarms,"BLU/");
09934          if (s.alarms & ZT_ALARM_YELLOW)
09935             strcat(alarms, "YEL/");
09936          if (s.alarms & ZT_ALARM_RED)
09937             strcat(alarms, "RED/");
09938          if (s.alarms & ZT_ALARM_LOOPBACK)
09939             strcat(alarms,"LB/");
09940          if (s.alarms & ZT_ALARM_RECOVER)
09941             strcat(alarms,"REC/");
09942          if (s.alarms & ZT_ALARM_NOTOPEN)
09943             strcat(alarms, "NOP/");
09944          if (!strlen(alarms))
09945             strcat(alarms, "UUU/");
09946          if (strlen(alarms)) {
09947             /* Strip trailing / */
09948             alarms[strlen(alarms)-1]='\0';
09949          }
09950       } else {
09951          if (s.numchans)
09952             strcpy(alarms, "OK");
09953          else
09954             strcpy(alarms, "UNCONFIGURED");
09955       }
09956 
09957       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
09958    }
09959    close(ctl);
09960 
09961    return RESULT_SUCCESS;
09962 #undef FORMAT
09963 #undef FORMAT2
09964 }

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

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

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 3003 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, enable_dtmf_detect(), ast_channel::fds, ast_frame::frametype, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, master, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, subnames, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().

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

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(), cadences, 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, cidrings, zt_pvt::cidrings, zt_pvt::cidspill, defaultcic, defaultozz, 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, num_cadence, 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               p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02132       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL);
02133 
02134 #ifdef SUPPORT_USERUSER
02135       /* User-user info */
02136       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02137 
02138       if (useruser)
02139          pri_sr_set_useruser(sr, useruser);
02140 #endif
02141 
02142       if (pri_setup(p->pri->pri, p->call,  sr)) {
02143          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02144                   c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02145          pri_rel(p->pri);
02146          ast_mutex_unlock(&p->lock);
02147          pri_sr_free(sr);
02148          return -1;
02149       }
02150       pri_sr_free(sr);
02151       ast_setstate(ast, AST_STATE_DIALING);
02152       pri_rel(p->pri);
02153    }
02154 #endif      
02155    ast_mutex_unlock(&p->lock);
02156    return 0;
02157 }

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 __unload_module(), alloc_sub(), destroy_channel(), mkintf(), 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 4366 of file chan_zap.c.

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

04367 {
04368    struct zt_pvt *p = ast->tech_pvt;
04369    struct ast_frame *f;
04370    ast_mutex_lock(&p->lock);
04371    f = __zt_exception(ast);
04372    ast_mutex_unlock(&p->lock);
04373    return f;
04374 }

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

Definition at line 3280 of file chan_zap.c.

References ast_channel::_state, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RINGING, zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), zt_indicate(), and zt_unlink().

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

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(), do_monitor(), 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 3514 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, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, 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, LOG_WARNING, 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().

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

static int zt_hangup struct ast_channel ast  )  [static]
 

Definition at line 2308 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, usecnt_lock, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().

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

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

Definition at line 4813 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, LOG_WARNING, 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().

Referenced by zt_fixup().

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

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

Definition at line 2941 of file chan_zap.c.

References ast_log(), zt_pvt::channel, LOG_DEBUG, LOG_WARNING, zt_pvt::master, MAX_SLAVES, and zt_pvt::slaves.

Referenced by zt_bridge().

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

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

Definition at line 4979 of file chan_zap.c.

References ast_channel::accountcode, ast_channel::adsicpe, ast_channel::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::busydetect, ast_channel::call_forward, ast_channel::callgroup, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_ton, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, DSP_PROGRESS_TALK, ast_channel::exten, ast_channel::fds, features, zt_pvt::hardwaredtmf, ast_channel::language, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, ast_channel::musicclass, ast_channel::name, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_subchannel::owner, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, progzone, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, strdup, SUB_REAL, subnames, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, type, ast_channel::type, usecnt, usecnt_lock, ast_channel::writeformat, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().

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

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

static int zt_open char *  fn  )  [static]
 

Definition at line 891 of file chan_zap.c.

References ast_log(), LOG_WARNING, and READ_SIZE.

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 4376 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, LOG_WARNING, 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().

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

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

Definition at line 7550 of file chan_zap.c.

References alloc_sub(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CDR_CALLWAIT, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), busy, ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, ifend, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, and zt_new().

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

static int zt_ring_phone struct zt_pvt p  )  [static]
 

Definition at line 3302 of file chan_zap.c.

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

Referenced by __zt_exception(), and zt_handle_event().

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

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

Definition at line 11112 of file chan_zap.c.

References ASCII_BYTES_PER_CHAR, ast_check_hangup(), AST_LAW, ast_log(), zt_pvt::channel, END_SILENCE_LEN, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_DEBUG, LOG_ERROR, malloc, zt_pvt::mate, option_debug, poll(), POLLOUT, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, TRAILER_MS, zt_subchannel::zfd, and zt_get_index().

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

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(), mkintf(), 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(), ss_thread(), 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 2735 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().

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

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 2883 of file chan_zap.c.

References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), zt_pvt::channel, conf_del(), zt_pvt::inconference, zt_pvt::lock, LOG_DEBUG, zt_pvt::master, MAX_SLAVES, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and update_conf().

Referenced by zt_bridge(), and zt_fixup().

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

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 5180 of file chan_zap.c.

References zt_set_hook().

Referenced by ss_thread().

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

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

Definition at line 4725 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, LOG_WARNING, 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().

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


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.

Referenced by mkintf(), and setup_zap().

int busy_quietlength = 0 [static]
 

Definition at line 265 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int busy_tonelength = 0 [static]
 

Definition at line 264 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int busycount = 3 [static]
 

Definition at line 263 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int busydetect = 0 [static]
 

Definition at line 261 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static]
 

Definition at line 756 of file chan_zap.c.

Referenced by handle_zap_show_cadences(), setup_zap(), and zt_call().

int callprogress = 0 [static]
 

Definition at line 267 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

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.

Referenced by mkintf(), and setup_zap().

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.

Referenced by mkintf(), and setup_zap().

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.

Referenced by mkintf(), setup_zap(), and ss_thread().

int cid_start = CID_START_RING [static]
 

Definition at line 214 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

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.

Referenced by handle_zap_show_cadences(), setup_zap(), and zt_call().

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.

Referenced by mkintf(), and setup_zap().

int cur_flash = -1 [static]
 

Definition at line 282 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

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.

Referenced by mkintf(), and setup_zap().

int cur_prewink = -1 [static]
 

Definition at line 279 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_priexclusive = 0 [static]
 

Definition at line 287 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_rxflash = -1 [static]
 

Definition at line 285 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_rxwink = -1 [static]
 

Definition at line 284 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_signalling = -1 [static]
 

Definition at line 216 of file chan_zap.c.

Referenced by setup_zap().

int cur_start = -1 [static]
 

Definition at line 283 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_wink = -1 [static]
 

Definition at line 281 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char defaultcic[64] = "" [static]
 

Definition at line 201 of file chan_zap.c.

Referenced by setup_zap(), and zt_call().

char defaultozz[64] = "" [static]
 

Definition at line 202 of file chan_zap.c.

Referenced by setup_zap(), and zt_call().

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

Referenced by mkintf(), and setup_zap().

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 build_port_config(), fill_defaults(), free_port_cfg(), misdn_cfg_get(), misdn_cfg_get_config_string(), mkintf(), and setup_zap().

char* events[] [static]
 

Definition at line 1062 of file chan_zap.c.

Referenced by authenticate().

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.

Referenced by mkintf(), and setup_zap().

int hidecallerid = 0 [static]
 

Definition at line 231 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int ifcount = 0 [static]
 

Definition at line 328 of file chan_zap.c.

Referenced by __unload_module(), do_monitor(), and mkintf().

struct zt_pvt * ifend [static]
 

Referenced by __build_step(), destroy_channel(), mkintf(), and zt_request().

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.

Referenced by handle_zap_show_cadences(), setup_zap(), and zt_call().

int numbufs = 4 [static]
 

Definition at line 277 of file chan_zap.c.

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

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.

Referenced by mkintf(), and setup_zap().

int priindication_oob = 0 [static]
 

Definition at line 289 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char progzone[10] = "" [static]
 

Definition at line 206 of file chan_zap.c.

Referenced by setup_zap(), and zt_new().

int pulse [static]
 

Definition at line 257 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int receivedRingT
 

Used to find out what ringtone we are on

Definition at line 763 of file chan_zap.c.

Referenced by ss_thread().

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.

Referenced by mkintf(), and setup_zap().

int ringt_base = DEFAULT_RINGT [static]
 

Definition at line 397 of file chan_zap.c.

Referenced by mkintf(), setup_zap(), and ss_thread().

struct zt_pvt* round_robin[32]
 

Definition at line 730 of file chan_zap.c.

float rxgain = 0.0 [static]
 

Definition at line 247 of file chan_zap.c.

Referenced by build_port_config(), fill_defaults(), fill_rxgain(), free_port_cfg(), load_module(), misdn_cfg_get(), misdn_cfg_get_config_string(), misdn_set_opt_exec(), mkintf(), and setup_zap().

int sendcalleridafter = DEFAULT_CIDRINGS [static]
 

When to send the CallerID signals (rings).

Definition at line 344 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char show_channel_usage[] [static]
 

Initial value:

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

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

Referenced by alloc_sub(), zt_bridge(), and zt_new().

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.

Referenced by mkintf(), and setup_zap().

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.

Referenced by mkintf(), and setup_zap().

float txgain = 0.0 [static]
 

Definition at line 249 of file chan_zap.c.

Referenced by build_port_config(), fill_defaults(), fill_txgain(), free_port_cfg(), load_module(), misdn_cfg_get(), misdn_cfg_get_config_string(), misdn_set_opt_exec(), mkintf(), and setup_zap().

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.

Referenced by mkintf(), and setup_zap().

int use_callingpres = 0 [static]
 

Definition at line 235 of file chan_zap.c.

Referenced by build_port_config(), fill_defaults(), free_port_cfg(), misdn_cfg_get(), misdn_cfg_get_config_string(), mkintf(), and setup_zap().

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.

Referenced by mkintf(), and setup_zap().

int user_has_defined_cadences = 0 [static]
 

Definition at line 754 of file chan_zap.c.

Referenced by setup_zap().

struct ast_cli_entry zap_cli[] [static]
 

Definition at line 9986 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 9982 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 9874 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 9974 of file chan_zap.c.

const struct ast_channel_tech zap_tech [static]
 

Definition at line 705 of file chan_zap.c.

int zaptrcallerid = 0 [static]
 

Definition at line 215 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().


Generated on Sun Aug 6 15:06:41 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2