Sat Sep 16 05:47:58 2006

Asterisk developer's documentation


chan_zap.c File Reference

Zaptel Pseudo TDM interface. More...

#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <zaptel.h>
#include <math.h>
#include <linux/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"

Go to the source code of this file.

Data Structures

struct  distRingData
struct  ringContextData
struct  zt_distRings
struct  zt_pvt
struct  zt_subchannel

Defines

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

Functions

static int __unload_module (void)
static struct ast_frame__zt_exception (struct ast_channel *ast)
static int action_transfer (struct mansession *s, struct message *m)
static int action_transferhangup (struct mansession *s, struct message *m)
static int action_zapdialoffhook (struct mansession *s, struct message *m)
static int action_zapdndoff (struct mansession *s, struct message *m)
static int action_zapdndon (struct mansession *s, struct message *m)
static int action_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_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_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
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_show_cadences_help []
static char zap_show_status_usage []
static 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 777 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 778 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.

#define HANGUP   1

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

#define MIN_MS_SINCE_FLASH   ( (2000) )

2000 ms

Definition at line 387 of file chan_zap.c.

Referenced by zt_handle_event().

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

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

Definition at line 139 of file chan_zap.c.

Referenced by ss_thread(), and zt_new().

#define NUM_CADENCE_MAX   25

Definition at line 752 of file chan_zap.c.

#define NUM_DCHANS   4

No more than 4 d-channels

Definition at line 187 of file chan_zap.c.

#define NUM_SPANS   32

Definition at line 186 of file chan_zap.c.

#define POLARITY_IDLE   0

Definition at line 478 of file chan_zap.c.

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

#define POLARITY_REV   1

Definition at line 479 of file chan_zap.c.

Referenced by handle_init_event(), and zt_handle_event().

#define READ_SIZE   160

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

Definition at line 379 of file chan_zap.c.

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

#define sig2str   zap_sig2str

Definition at line 1190 of file chan_zap.c.

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

#define SIG_SF_FEATDMF   (0x0400000 | ZT_SIG_SF)

Definition at line 180 of file chan_zap.c.

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

#define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)

Definition at line 178 of file chan_zap.c.

Referenced by handle_init_event(), 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 9851 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 10028 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, iflist, master, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, zap_cli, zap_tech, and zt_close().

10029 {
10030    int x = 0;
10031    struct zt_pvt *p, *pl;
10032 #ifdef ZAPATA_PRI
10033    int i;
10034    for(i=0;i<NUM_SPANS;i++) {
10035       if (pris[i].master != AST_PTHREADT_NULL) 
10036          pthread_cancel(pris[i].master);
10037    }
10038    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
10039 #endif
10040 #ifdef ZAPATA_R2
10041    ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
10042 #endif
10043    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
10044    ast_manager_unregister( "ZapDialOffhook" );
10045    ast_manager_unregister( "ZapHangup" );
10046    ast_manager_unregister( "ZapTransfer" );
10047    ast_manager_unregister( "ZapDNDoff" );
10048    ast_manager_unregister( "ZapDNDon" );
10049    ast_manager_unregister("ZapShowChannels");
10050    ast_channel_unregister(&zap_tech);
10051    if (!ast_mutex_lock(&iflock)) {
10052       /* Hangup all interfaces if they have an owner */
10053       p = iflist;
10054       while(p) {
10055          if (p->owner)
10056             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10057          p = p->next;
10058       }
10059       ast_mutex_unlock(&iflock);
10060    } else {
10061       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10062       return -1;
10063    }
10064    if (!ast_mutex_lock(&monlock)) {
10065       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10066          pthread_cancel(monitor_thread);
10067          pthread_kill(monitor_thread, SIGURG);
10068          pthread_join(monitor_thread, NULL);
10069       }
10070       monitor_thread = AST_PTHREADT_STOP;
10071       ast_mutex_unlock(&monlock);
10072    } else {
10073       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10074       return -1;
10075    }
10076 
10077    if (!ast_mutex_lock(&iflock)) {
10078       /* Destroy all the interfaces and free their memory */
10079       p = iflist;
10080       while(p) {
10081          /* Free any callerid */
10082          if (p->cidspill)
10083             free(p->cidspill);
10084          /* Close the zapata thingy */
10085          if (p->subs[SUB_REAL].zfd > -1)
10086             zt_close(p->subs[SUB_REAL].zfd);
10087          pl = p;
10088          p = p->next;
10089          x++;
10090          /* Free associated memory */
10091          if(pl)
10092             destroy_zt_pvt(&pl);
10093          ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10094       }
10095       iflist = NULL;
10096       ifcount = 0;
10097       ast_mutex_unlock(&iflock);
10098    } else {
10099       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
10100       return -1;
10101    }
10102 #ifdef ZAPATA_PRI    
10103    for(i=0;i<NUM_SPANS;i++) {
10104       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10105          pthread_join(pris[i].master, NULL);
10106       zt_close(pris[i].fds[i]);
10107    }
10108 #endif
10109    return 0;
10110 }

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

Definition at line 4258 of file chan_zap.c.

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

Referenced by zt_exception(), and zt_read().

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

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

Definition at line 9918 of file chan_zap.c.

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

Referenced by load_module().

09919 {
09920    struct zt_pvt *p = NULL;
09921    char *channel = astman_get_header(m, "ZapChannel");
09922    if (ast_strlen_zero(channel)) {
09923       astman_send_error(s, m, "No channel specified");
09924       return 0;
09925    }
09926    p = find_channel(atoi(channel));
09927    if (!p) {
09928       astman_send_error(s, m, "No such channel");
09929       return 0;
09930    }
09931    zap_fake_event(p,TRANSFER);
09932    astman_send_ack(s, m, "ZapTransfer");
09933    return 0;
09934 }

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

Definition at line 9936 of file chan_zap.c.

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

Referenced by load_module().

09937 {
09938    struct zt_pvt *p = NULL;
09939    char *channel = astman_get_header(m, "ZapChannel");
09940    if (ast_strlen_zero(channel)) {
09941       astman_send_error(s, m, "No channel specified");
09942       return 0;
09943    }
09944    p = find_channel(atoi(channel));
09945    if (!p) {
09946       astman_send_error(s, m, "No such channel");
09947       return 0;
09948    }
09949    zap_fake_event(p,HANGUP);
09950    astman_send_ack(s, m, "ZapHangup");
09951    return 0;
09952 }

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

Definition at line 9954 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, s, and zap_queue_frame().

Referenced by load_module().

09955 {
09956    struct zt_pvt *p = NULL;
09957    char *channel = astman_get_header(m, "ZapChannel");
09958    char *number = astman_get_header(m, "Number");
09959    int i;
09960    if (ast_strlen_zero(channel)) {
09961       astman_send_error(s, m, "No channel specified");
09962       return 0;
09963    }
09964    if (ast_strlen_zero(number)) {
09965       astman_send_error(s, m, "No number specified");
09966       return 0;
09967    }
09968    p = find_channel(atoi(channel));
09969    if (!p) {
09970       astman_send_error(s, m, "No such channel");
09971       return 0;
09972    }
09973    if (!p->owner) {
09974       astman_send_error(s, m, "Channel does not have it's owner");
09975       return 0;
09976    }
09977    for (i=0; i<strlen(number); i++) {
09978       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
09979       zap_queue_frame(p, &f, NULL); 
09980    }
09981    astman_send_ack(s, m, "ZapDialOffhook");
09982    return 0;
09983 }

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

Definition at line 9900 of file chan_zap.c.

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

Referenced by load_module().

09901 {
09902     struct zt_pvt *p = NULL;
09903     char *channel = astman_get_header(m, "ZapChannel");
09904     if (ast_strlen_zero(channel)) {
09905         astman_send_error(s, m, "No channel specified");
09906         return 0;
09907     }
09908     p = find_channel(atoi(channel));
09909     if (!p) {
09910         astman_send_error(s, m, "No such channel");
09911         return 0;
09912     }
09913     p->dnd = 0;
09914     astman_send_ack(s, m, "DND Disabled");
09915     return 0;
09916 }

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

Definition at line 9882 of file chan_zap.c.

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

Referenced by load_module().

09883 {
09884     struct zt_pvt *p = NULL;
09885     char *channel = astman_get_header(m, "ZapChannel");
09886     if (ast_strlen_zero(channel)) {
09887         astman_send_error(s, m, "No channel specified");
09888         return 0;
09889     }
09890     p = find_channel(atoi(channel));
09891     if (!p) {
09892         astman_send_error(s, m, "No such channel");
09893         return 0;
09894     }
09895     p->dnd = 1;
09896     astman_send_ack(s, m, "DND Enabled");
09897     return 0;
09898 }

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

Definition at line 9985 of file chan_zap.c.

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

Referenced by load_module().

09986 {
09987    struct zt_pvt *tmp = NULL;
09988    char *id = astman_get_header(m, "ActionID");
09989    char idText[256] = "";
09990 
09991    astman_send_ack(s, m, "Zapata channel status will follow");
09992    if (!ast_strlen_zero(id))
09993       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
09994 
09995    ast_mutex_lock(&iflock);
09996    
09997    tmp = iflist;
09998    while (tmp) {
09999       if (tmp->channel > 0) {
10000          int alarm = get_alarms(tmp);
10001          ast_cli(s->fd,
10002             "Event: ZapShowChannels\r\n"
10003             "Channel: %d\r\n"
10004             "Signalling: %s\r\n"
10005             "Context: %s\r\n"
10006             "DND: %s\r\n"
10007             "Alarm: %s\r\n"
10008             "%s"
10009             "\r\n",
10010             tmp->channel, sig2str(tmp->sig), tmp->context, 
10011             tmp->dnd ? "Enabled" : "Disabled",
10012             alarm2str(alarm), idText);
10013       } 
10014 
10015       tmp = tmp->next;
10016    }
10017 
10018    ast_mutex_unlock(&iflock);
10019    
10020    ast_cli(s->fd, 
10021       "Event: ZapShowChannelsComplete\r\n"
10022       "%s"
10023       "\r\n", 
10024       idText);
10025    return 0;
10026 }

static char* alarm2str ( int  alarm  )  [static]

Definition at line 1087 of file chan_zap.c.

References alarms, and name.

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

01088 {
01089    int x;
01090    for (x=0;x<sizeof(alarms) / sizeof(alarms[0]); x++) {
01091       if (alarms[x].alarm & alarm)
01092          return alarms[x].name;
01093    }
01094    return alarm ? "Unknown Alarm" : "No Alarm";
01095 }

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

Definition at line 955 of file chan_zap.c.

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

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

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

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

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

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

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

Definition at line 7271 of file chan_zap.c.

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

Referenced by zt_request().

07272 {
07273    int res;
07274    ZT_PARAMS par;
07275 
07276    /* First, check group matching */
07277    if (groupmatch) {
07278       if ((p->group & groupmatch) != groupmatch)
07279          return 0;
07280       *groupmatched = 1;
07281    }
07282    /* Check to see if we have a channel match */
07283    if (channelmatch != -1) {
07284       if (p->channel != channelmatch)
07285          return 0;
07286       *channelmatched = 1;
07287    }
07288    /* We're at least busy at this point */
07289    if (busy) {
07290       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07291          *busy = 1;
07292    }
07293    /* If do not disturb, definitely not */
07294    if (p->dnd)
07295       return 0;
07296    /* If guard time, definitely not */
07297    if (p->guardtime && (time(NULL) < p->guardtime)) 
07298       return 0;
07299       
07300    /* If no owner definitely available */
07301    if (!p->owner) {
07302 #ifdef ZAPATA_PRI
07303       /* Trust PRI */
07304       if (p->pri) {
07305          if (p->resetting || p->call)
07306             return 0;
07307          else
07308             return 1;
07309       }
07310 #endif
07311 #ifdef ZAPATA_R2
07312       /* Trust R2 as well */
07313       if (p->r2) {
07314          if (p->hasr2call || p->r2blocked)
07315             return 0;
07316          else
07317             return 1;
07318       }
07319 #endif
07320       if (!p->radio)
07321       {
07322          if (!p->sig || (p->sig == SIG_FXSLS))
07323             return 1;
07324          /* Check hook state */
07325          if (p->subs[SUB_REAL].zfd > -1)
07326             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07327          else {
07328             /* Assume not off hook on CVRS */
07329             res = 0;
07330             par.rxisoffhook = 0;
07331          }
07332          if (res) {
07333             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07334          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07335             /* When "onhook" that means no battery on the line, and thus
07336               it is out of service..., if it's on a TDM card... If it's a channel
07337               bank, there is no telling... */
07338             if (par.rxbits > -1)
07339                return 1;
07340             if (par.rxisoffhook)
07341                return 1;
07342             else
07343 #ifdef ZAP_CHECK_HOOKSTATE
07344                return 0;
07345 #else
07346                return 1;
07347 #endif
07348          } else if (par.rxisoffhook) {
07349             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07350             /* Not available when the other end is off hook */
07351             return 0;
07352          }
07353       }
07354       return 1;
07355    }
07356 
07357    /* If it's not an FXO, forget about call wait */
07358    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07359       return 0;
07360 
07361    if (!p->callwaiting) {
07362       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07363       return 0;
07364    }
07365 
07366    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07367       /* If there is already a call waiting call, then we can't take a second one */
07368       return 0;
07369    }
07370    
07371    if ((p->owner->_state != AST_STATE_UP) &&
07372        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07373       /* If the current call is not up, then don't allow the call */
07374       return 0;
07375    }
07376    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07377       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07378       return 0;
07379    }
07380    /* We're cool */
07381    return 1;
07382 }

static int bump_gains ( struct zt_pvt p  )  [static]

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

01550 {
01551    int res;
01552 
01553    /* Bump receive gain by 5.0db */
01554    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01555    if (res) {
01556       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01557       return -1;
01558    }
01559 
01560    return 0;
01561 }

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

Definition at line 7384 of file chan_zap.c.

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

Referenced by zt_request().

07385 {
07386    struct zt_pvt *p;
07387    ZT_BUFFERINFO bi;
07388    int res;
07389    p = malloc(sizeof(struct zt_pvt));
07390    if (p) {
07391       memcpy(p, src, sizeof(struct zt_pvt));
07392       ast_mutex_init(&p->lock);
07393       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07394       /* Allocate a zapata structure */
07395       if (p->subs[SUB_REAL].zfd < 0) {
07396          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07397          destroy_zt_pvt(&p);
07398          return NULL;
07399       }
07400       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07401       if (!res) {
07402          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07403          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07404          bi.numbufs = numbufs;
07405          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07406          if (res < 0) {
07407             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07408          }
07409       } else
07410          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07411    }
07412    p->destroy = 1;
07413    p->next = iflist;
07414    iflist = p;
07415    return p;
07416 }

static int check_for_conference ( struct zt_pvt p  )  [static]

Definition at line 3474 of file chan_zap.c.

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

Referenced by zt_handle_event().

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

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

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

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

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

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

01242 {
01243    ZT_CONFINFO zi;
01244    if (/* Can't delete if there's no zfd */
01245       (c->zfd < 0) ||
01246       /* Don't delete from the conference if it's not our conference */
01247       !isourconf(p, c)
01248       /* Don't delete if we don't think it's conferenced at all (implied) */
01249       ) return 0;
01250    memset(&zi, 0, sizeof(zi));
01251    zi.chan = 0;
01252    zi.confno = 0;
01253    zi.confmode = 0;
01254    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01255       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01256       return -1;
01257    }
01258    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01259    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01260    return 0;
01261 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 11078 of file chan_zap.c.

11079 {
11080    return (char *) desc;
11081 }

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

Definition at line 2162 of file chan_zap.c.

References destroy_zt_pvt(), 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(), and zt_hangup().

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

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

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

02150 {
02151    struct zt_pvt *p = *pvt;
02152    /* Remove channel from the list */
02153    if(p->prev)
02154       p->prev->next = p->next;
02155    if(p->next)
02156       p->next->prev = p->prev;
02157    ast_mutex_destroy(&p->lock);
02158    free(p);
02159    *pvt = NULL;
02160 }

static void disable_dtmf_detect ( struct zt_pvt p  )  [static]

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

02955 {
02956 #ifdef ZT_TONEDETECT
02957    int val;
02958 #endif
02959 
02960    p->ignoredtmf = 1;
02961 
02962 #ifdef ZT_TONEDETECT
02963    val = 0;
02964    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
02965 #endif      
02966    if (!p->hardwaredtmf && p->dsp) {
02967       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
02968       ast_dsp_set_features(p->dsp, p->dsp_features);
02969    }
02970 }

static void* do_monitor ( void *  data  )  [static]

Definition at line 6433 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(), iflist, last, LOG_DEBUG, LOG_ERROR, malloc, MAX_CALLERID_SIZE, zt_pvt::msgstate, msglist::next, 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().

06434 {
06435    int count, res, res2, spoint, pollres=0;
06436    struct zt_pvt *i;
06437    struct zt_pvt *last = NULL;
06438    time_t thispass = 0, lastpass = 0;
06439    int found;
06440    char buf[1024];
06441    struct pollfd *pfds=NULL;
06442    int lastalloc = -1;
06443    /* This thread monitors all the frame relay interfaces which are not yet in use
06444       (and thus do not have a separate thread) indefinitely */
06445    /* From here on out, we die whenever asked */
06446 #if 0
06447    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06448       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06449       return NULL;
06450    }
06451    ast_log(LOG_DEBUG, "Monitor starting...\n");
06452 #endif
06453    for(;;) {
06454       /* Lock the interface list */
06455       if (ast_mutex_lock(&iflock)) {
06456          ast_log(LOG_ERROR, "Unable to grab interface lock\n");
06457          return NULL;
06458       }
06459       if (!pfds || (lastalloc != ifcount)) {
06460          if (pfds)
06461             free(pfds);
06462          if (ifcount) {
06463             pfds = malloc(ifcount * sizeof(struct pollfd));
06464             if (!pfds) {
06465                ast_log(LOG_WARNING, "Critical memory error.  Zap dies.\n");
06466                ast_mutex_unlock(&iflock);
06467                return NULL;
06468             }
06469          }
06470          lastalloc = ifcount;
06471       }
06472       /* Build the stuff we're going to poll on, that is the socket of every
06473          zt_pvt that does not have an associated owner channel */
06474       count = 0;
06475       i = iflist;
06476       while(i) {
06477          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06478             if (!i->owner && !i->subs[SUB_REAL].owner) {
06479                /* This needs to be watched, as it lacks an owner */
06480                pfds[count].fd = i->subs[SUB_REAL].zfd;
06481                pfds[count].events = POLLPRI;
06482                pfds[count].revents = 0;
06483                /* Message waiting or r2 channels also get watched for reading */
06484 #ifdef ZAPATA_R2
06485                if (i->cidspill || i->r2)
06486 #else             
06487                if (i->cidspill)
06488 #endif               
06489                   pfds[count].events |= POLLIN;
06490                count++;
06491             }
06492          }
06493          i = i->next;
06494       }
06495       /* Okay, now that we know what to do, release the interface lock */
06496       ast_mutex_unlock(&iflock);
06497       
06498       pthread_testcancel();
06499       /* Wait at least a second for something to happen */
06500       res = poll(pfds, count, 1000);
06501       pthread_testcancel();
06502       /* Okay, poll has finished.  Let's see what happened.  */
06503       if (res < 0) {
06504          if ((errno != EAGAIN) && (errno != EINTR))
06505             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06506          continue;
06507       }
06508       /* Alright, lock the interface list again, and let's look and see what has
06509          happened */
06510       if (ast_mutex_lock(&iflock)) {
06511          ast_log(LOG_WARNING, "Unable to lock the interface list\n");
06512          continue;
06513       }
06514       found = 0;
06515       spoint = 0;
06516       lastpass = thispass;
06517       thispass = time(NULL);
06518       i = iflist;
06519       while(i) {
06520          if (thispass != lastpass) {
06521             if (!found && ((i == last) || ((i == iflist) && !last))) {
06522                last = i;
06523                if (last) {
06524                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06525                      (last->sig & __ZT_SIG_FXO)) {
06526                      res = ast_app_has_voicemail(last->mailbox, NULL);
06527                      if (last->msgstate != res) {
06528                         int x;
06529                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06530                         x = ZT_FLUSH_BOTH;
06531                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06532                         if (res2)
06533                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06534                         last->cidspill = malloc(MAX_CALLERID_SIZE);
06535                         if (last->cidspill) {
06536                            /* Turn on on hook transfer for 4 seconds */
06537                            x = 4000;
06538                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06539                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06540                            last->cidpos = 0;
06541                            last->msgstate = res;
06542                            last->onhooktime = thispass;
06543                         }
06544                         found ++;
06545                      }
06546                   }
06547                   last = last->next;
06548                }
06549             }
06550          }
06551          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06552             if (i->radio && !i->owner)
06553             {
06554                res = zt_get_event(i->subs[SUB_REAL].zfd);
06555                if (res)
06556                {
06557                   if (option_debug)
06558                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06559                   /* Don't hold iflock while handling init events */
06560                   ast_mutex_unlock(&iflock);
06561                   handle_init_event(i, res);
06562                   ast_mutex_lock(&iflock);   
06563                }
06564                i = i->next;
06565                continue;
06566             }              
06567             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06568             if (pollres & POLLIN) {
06569                if (i->owner || i->subs[SUB_REAL].owner) {
06570 #ifdef ZAPATA_PRI
06571                   if (!i->pri)
06572 #endif                  
06573                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06574                   i = i->next;
06575                   continue;
06576                }
06577 #ifdef ZAPATA_R2
06578                if (i->r2) {
06579                   /* If it's R2 signalled, we always have to check for events */
06580                   mfcr2_event_t *e;
06581                   e = mfcr2_check_event(i->r2);
06582                   if (e)
06583                      handle_init_r2_event(i, e);
06584                   else {
06585                      e = mfcr2_schedule_run(i->r2);
06586                      if (e)
06587                         handle_init_r2_event(i, e);
06588                   }
06589                   i = i->next;
06590                   continue;
06591                }
06592 #endif
06593                if (!i->cidspill) {
06594                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06595                   i = i->next;
06596                   continue;
06597                }
06598                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06599                if (res > 0) {
06600                   /* We read some number of bytes.  Write an equal amount of data */
06601                   if (res > i->cidlen - i->cidpos) 
06602                      res = i->cidlen - i->cidpos;
06603                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06604                   if (res2 > 0) {
06605                      i->cidpos += res2;
06606                      if (i->cidpos >= i->cidlen) {
06607                         free(i->cidspill);
06608                         i->cidspill = 0;
06609                         i->cidpos = 0;
06610                         i->cidlen = 0;
06611                      }
06612                   } else {
06613                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06614                      i->msgstate = -1;
06615                   }
06616                } else {
06617                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06618                }
06619                if (option_debug)
06620                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06621                /* Don't hold iflock while handling init events -- race with chlock */
06622                ast_mutex_unlock(&iflock);
06623                handle_init_event(i, res);
06624                ast_mutex_lock(&iflock);   
06625             }
06626 #ifdef ZAPATA_R2
06627             if ((pollres & POLLPRI) || (i->r2 && !i->sigchecked)) 
06628 #else          
06629             if (pollres & POLLPRI) 
06630 #endif            
06631             {
06632                if (i->owner || i->subs[SUB_REAL].owner) {
06633 #ifdef ZAPATA_PRI
06634                   if (!i->pri)
06635 #endif                  
06636                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
06637                   i = i->next;
06638                   continue;
06639                }
06640                res = zt_get_event(i->subs[SUB_REAL].zfd);
06641                if (option_debug)
06642                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06643                /* Don't hold iflock while handling init events */
06644                ast_mutex_unlock(&iflock);
06645                handle_init_event(i, res);
06646                ast_mutex_lock(&iflock);   
06647             }
06648          }
06649          i=i->next;
06650       }
06651       ast_mutex_unlock(&iflock);
06652    }
06653    /* Never reached */
06654    return NULL;
06655    
06656 }

static void enable_dtmf_detect ( struct zt_pvt p  )  [static]

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

02973 {
02974 #ifdef ZT_TONEDETECT
02975    int val;
02976 #endif
02977 
02978    if (p->channel == CHAN_PSEUDO)
02979       return;
02980 
02981    p->ignoredtmf = 0;
02982 
02983 #ifdef ZT_TONEDETECT
02984    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
02985    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
02986 #endif      
02987    if (!p->hardwaredtmf && p->dsp) {
02988       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
02989       ast_dsp_set_features(p->dsp, p->dsp_features);
02990    }
02991 }

static char* event2str ( int  event  )  [static]

Definition at line 1097 of file chan_zap.c.

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

01098 {
01099         static char buf[256];
01100         if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01101                 return events[event];
01102         sprintf(buf, "Event %d", event); /* safe */
01103         return buf;
01104 }

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

Definition at line 1474 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_rxgain().

01475 {
01476    int j;
01477    int k;
01478    float linear_gain = pow(10.0, gain / 20.0);
01479 
01480    switch (law) {
01481    case ZT_LAW_ALAW:
01482       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01483          if (gain) {
01484             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01485             if (k > 32767) k = 32767;
01486             if (k < -32767) k = -32767;
01487             g->rxgain[j] = AST_LIN2A(k);
01488          } else {
01489             g->rxgain[j] = j;
01490          }
01491       }
01492       break;
01493    case ZT_LAW_MULAW:
01494       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01495          if (gain) {
01496             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01497             if (k > 32767) k = 32767;
01498             if (k < -32767) k = -32767;
01499             g->rxgain[j] = AST_LIN2MU(k);
01500          } else {
01501             g->rxgain[j] = j;
01502          }
01503       }
01504       break;
01505    }
01506 }

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

Definition at line 1440 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_txgain().

01441 {
01442    int j;
01443    int k;
01444    float linear_gain = pow(10.0, gain / 20.0);
01445 
01446    switch (law) {
01447    case ZT_LAW_ALAW:
01448       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01449          if (gain) {
01450             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01451             if (k > 32767) k = 32767;
01452             if (k < -32767) k = -32767;
01453             g->txgain[j] = AST_LIN2A(k);
01454          } else {
01455             g->txgain[j] = j;
01456          }
01457       }
01458       break;
01459    case ZT_LAW_MULAW:
01460       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01461          if (gain) {
01462             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01463             if (k > 32767) k = 32767;
01464             if (k < -32767) k = -32767;
01465             g->txgain[j] = AST_LIN2MU(k);
01466          } else {
01467             g->txgain[j] = j;
01468          }
01469       }
01470       break;
01471    }
01472 }

static struct zt_pvt* find_channel ( int  channel  )  [static]

Definition at line 9870 of file chan_zap.c.

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

09871 {
09872    struct zt_pvt *p = iflist;
09873    while(p) {
09874       if (p->channel == channel) {
09875          break;
09876       }
09877       p = p->next;
09878    }
09879    return p;
09880 }

static int get_alarms ( struct zt_pvt p  )  [static]

Definition at line 3496 of file chan_zap.c.

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

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

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

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

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

06240 {
06241    int res;
06242    pthread_t threadid;
06243    pthread_attr_t attr;
06244    struct ast_channel *chan;
06245    pthread_attr_init(&attr);
06246    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06247    /* Handle an event on a given channel for the monitor thread. */
06248    switch(event) {
06249    case ZT_EVENT_NONE:
06250    case ZT_EVENT_BITSCHANGED:
06251       if (i->radio) break;
06252 #ifdef ZAPATA_R2
06253       if (i->r2) {
06254          mfcr2_event_t *e;
06255          e = r2_get_event_bits(i);
06256          i->sigchecked = 1;
06257          if (e)
06258             handle_init_r2_event(i, e);
06259       }
06260 #endif      
06261       break;
06262    case ZT_EVENT_WINKFLASH:
06263    case ZT_EVENT_RINGOFFHOOK:
06264       if (i->inalarm) break;
06265       if (i->radio) break;
06266       /* Got a ring/answer.  What kind of channel are we? */
06267       switch(i->sig) {
06268       case SIG_FXOLS:
06269       case SIG_FXOGS:
06270       case SIG_FXOKS:
06271               zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06272          if (i->cidspill) {
06273             /* Cancel VMWI spill */
06274             free(i->cidspill);
06275             i->cidspill = NULL;
06276          }
06277          if (i->immediate) {
06278             zt_enable_ec(i);
06279             /* The channel is immediately up.  Start right away */
06280             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06281             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06282             if (!chan) {
06283                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06284                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06285                if (res < 0)
06286                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06287             }
06288          } else {
06289             /* Check for callerid, digits, etc */
06290             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06291             if (chan) {
06292                if (has_voicemail(i))
06293                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06294                else
06295                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06296                if (res < 0) 
06297                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
06298                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06299                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06300                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06301                   if (res < 0)
06302                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06303                   ast_hangup(chan);
06304                }
06305             } else
06306                ast_log(LOG_WARNING, "Unable to create channel\n");
06307          }
06308          break;
06309       case SIG_FXSLS:
06310       case SIG_FXSGS:
06311       case SIG_FXSKS:
06312             i->ringt = i->ringt_base;
06313             /* Fall through */
06314       case SIG_EMWINK:
06315       case SIG_FEATD:
06316       case SIG_FEATDMF:
06317       case SIG_E911:
06318       case SIG_FEATB:
06319       case SIG_EM:
06320       case SIG_EM_E1:
06321       case SIG_SFWINK:
06322       case SIG_SF_FEATD:
06323       case SIG_SF_FEATDMF:
06324       case SIG_SF_FEATB:
06325       case SIG_SF:
06326             /* Check for callerid, digits, etc */
06327             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06328             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06329                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06330                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06331                if (res < 0)
06332                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06333                ast_hangup(chan);
06334             } else if (!chan) {
06335                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06336             }
06337             break;
06338       default:
06339          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06340          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06341          if (res < 0)
06342                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06343          return -1;
06344       }
06345       break;
06346    case ZT_EVENT_NOALARM:
06347       i->inalarm = 0;
06348       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06349       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06350                     "Channel: %d\r\n", i->channel);
06351       break;
06352    case ZT_EVENT_ALARM:
06353       i->inalarm = 1;
06354       res = get_alarms(i);
06355       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06356       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06357                     "Alarm: %s\r\n"
06358                     "Channel: %d\r\n",
06359                     alarm2str(res), i->channel);
06360       /* fall thru intentionally */
06361    case ZT_EVENT_ONHOOK:
06362       if (i->radio) break;
06363       /* Back on hook.  Hang up. */
06364       switch(i->sig) {
06365       case SIG_FXOLS:
06366       case SIG_FXOGS:
06367       case SIG_FEATD:
06368       case SIG_FEATDMF:
06369       case SIG_E911:
06370       case SIG_FEATB:
06371       case SIG_EM:
06372       case SIG_EM_E1:
06373       case SIG_EMWINK:
06374       case SIG_SF_FEATD:
06375       case SIG_SF_FEATDMF:
06376       case SIG_SF_FEATB:
06377       case SIG_SF:
06378       case SIG_SFWINK:
06379       case SIG_FXSLS:
06380       case SIG_FXSGS:
06381       case SIG_FXSKS:
06382       case SIG_GR303FXSKS:
06383          zt_disable_ec(i);
06384          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06385          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06386          break;
06387       case SIG_GR303FXOKS:
06388       case SIG_FXOKS:
06389          zt_disable_ec(i);
06390          /* Diddle the battery for the zhone */
06391 #ifdef ZHONE_HACK
06392          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06393          usleep(1);
06394 #endif         
06395          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06396          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06397          break;
06398       case SIG_PRI:
06399          zt_disable_ec(i);
06400          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06401          break;
06402       default:
06403          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06404          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06405          return -1;
06406       }
06407       break;
06408    case ZT_EVENT_POLARITY:
06409       switch(i->sig) {
06410       case SIG_FXSLS:
06411       case SIG_FXSKS:
06412       case SIG_FXSGS:
06413          if (i->cid_start == CID_START_POLARITY) {
06414             i->polarity = POLARITY_REV;
06415             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06416                    "CID detection on channel %d\n",
06417                    i->channel);
06418             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06419             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06420                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06421             }
06422          }
06423          break;
06424       default:
06425          ast_log(LOG_WARNING, "handle_init_event detected "
06426             "polarity reversal on non-FXO (SIG_FXS) "
06427             "interface %d\n", i->channel);
06428       }
06429    }
06430    return 0;
06431 }

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

Definition at line 9734 of file chan_zap.c.

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

09735 {
09736    int i, j;
09737    for (i=0;i<num_cadence;i++) {
09738       char output[1024];
09739       char tmp[16], tmp2[64];
09740       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
09741       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
09742 
09743       for (j=0;j<16;j++) {
09744          if (cadences[i].ringcadence[j] == 0)
09745             break;
09746          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
09747          if (cidrings[i] * 2 - 1 == j)
09748             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
09749          else
09750             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
09751          if (j != 0)
09752             strncat(output, ",", sizeof(output) - strlen(output) - 1);
09753          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
09754       }
09755       ast_cli(fd,"%s\n",output);
09756    }
09757    return 0;
09758 }

static int has_voicemail ( struct zt_pvt p  )  [static]

Definition at line 1669 of file chan_zap.c.

References ast_app_has_voicemail(), and zt_pvt::mailbox.

01670 {
01671 
01672    return ast_app_has_voicemail(p->mailbox, NULL);
01673 }

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

Definition at line 1230 of file chan_zap.c.

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

Referenced by conf_del().

01231 {
01232    /* If they're listening to our channel, they're ours */  
01233    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01234       return 1;
01235    /* If they're a talker on our (allocated) conference, they're ours */
01236    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01237       return 1;
01238    return 0;
01239 }

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

Definition at line 1263 of file chan_zap.c.

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

Referenced by update_conf().

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

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

References ASTERISK_GPL_KEY.

11084 {
11085    return ASTERISK_GPL_KEY;
11086 }

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 10914 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, round_robin, setup_zap(), zap_cli, and zap_tech.

10915 {
10916    int res;
10917 
10918 #ifdef ZAPATA_PRI
10919    int y,i;
10920    memset(pris, 0, sizeof(pris));
10921    for (y=0;y<NUM_SPANS;y++) {
10922       ast_mutex_init(&pris[y].lock);
10923       pris[y].offset = -1;
10924       pris[y].master = AST_PTHREADT_NULL;
10925       for (i=0;i<NUM_DCHANS;i++)
10926          pris[y].fds[i] = -1;
10927    }
10928    pri_set_error(zt_pri_error);
10929    pri_set_message(zt_pri_message);
10930 #endif
10931    res = setup_zap(0);
10932    /* Make sure we can register our Zap channel type */
10933    if(res) {
10934      return -1;
10935    }
10936    if (ast_channel_register(&zap_tech)) {
10937       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
10938       __unload_module();
10939       return -1;
10940    }
10941 #ifdef ZAPATA_PRI
10942    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
10943 #endif   
10944 #ifdef ZAPATA_R2
10945    ast_cli_register_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
10946 #endif   
10947    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
10948    
10949    memset(round_robin, 0, sizeof(round_robin));
10950    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
10951    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
10952    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
10953    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
10954    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
10955    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
10956 
10957    return res;
10958 }

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

Definition at line 6810 of file chan_zap.c.

References ast_log(), ast_mutex_init(), ast_strlen_zero(), CHAN_PSEUDO, zt_pvt::channel, destroy_zt_pvt(), iflist, zt_pvt::lock, LOG_ERROR, malloc, MAX_CHANNELS, zt_pvt::next, zt_pvt::prev, sig2str, SIG_FXOKS, SIG_FXSKS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SUB_REAL, channel::subs, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().

Referenced by setup_zap().

06811 {
06812    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
06813    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
06814    char fn[80];
06815 #if 1
06816    struct zt_bufferinfo bi;
06817 #endif
06818    struct zt_spaninfo si;
06819    int res;
06820    int span=0;
06821    int here = 0;
06822    int x;
06823    struct zt_pvt **wlist;
06824    struct zt_pvt **wend;
06825    ZT_PARAMS p;
06826 
06827    wlist = &iflist;
06828    wend = &ifend;
06829 
06830 #ifdef ZAPATA_PRI
06831    if (pri) {
06832       wlist = &pri->crvs;
06833       wend = &pri->crvend;
06834    }
06835 #endif
06836 
06837    tmp2 = *wlist;
06838    prev = NULL;
06839 
06840    while (tmp2) {
06841       if (!tmp2->destroy) {
06842          if (tmp2->channel == channel) {
06843             tmp = tmp2;
06844             here = 1;
06845             break;
06846          }
06847          if (tmp2->channel > channel) {
06848             break;
06849          }
06850       }
06851       prev = tmp2;
06852       tmp2 = tmp2->next;
06853    }
06854 
06855    if (!here && !reloading) {
06856       tmp = (struct zt_pvt*)malloc(sizeof(struct zt_pvt));
06857       if (!tmp) {
06858          ast_log(LOG_ERROR, "MALLOC FAILED\n");
06859          destroy_zt_pvt(&tmp);
06860          return NULL;
06861       }
06862       memset(tmp, 0, sizeof(struct zt_pvt));
06863       ast_mutex_init(&tmp->lock);
06864       ifcount++;
06865       for (x=0;x<3;x++)
06866          tmp->subs[x].zfd = -1;
06867       tmp->channel = channel;
06868    }
06869 
06870    if (tmp) {
06871       if (!here) {
06872          if ((channel != CHAN_PSEUDO) && !pri) {
06873             snprintf(fn, sizeof(fn), "%d", channel);
06874             /* Open non-blocking */
06875             if (!here)
06876                tmp->subs[SUB_REAL].zfd = zt_open(fn);
06877             /* Allocate a zapata structure */
06878             if (tmp->subs[SUB_REAL].zfd < 0) {
06879                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);
06880                destroy_zt_pvt(&tmp);
06881                return NULL;
06882             }
06883             memset(&p, 0, sizeof(p));
06884             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
06885             if (res < 0) {
06886                ast_log(LOG_ERROR, "Unable to get parameters\n");
06887                destroy_zt_pvt(&tmp);
06888                return NULL;
06889             }
06890             if (p.sigtype != (signalling & 0x3ffff)) {
06891                ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(signalling), sig2str(p.sigtype));
06892                destroy_zt_pvt(&tmp);
06893                return tmp;
06894             }
06895             tmp->law = p.curlaw;
06896             tmp->span = p.spanno;
06897             span = p.spanno - 1;
06898          } else {
06899             if (channel == CHAN_PSEUDO)
06900                signalling = 0;
06901             else if ((signalling != SIG_FXOKS) && (signalling != SIG_FXSKS)) {
06902                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
06903                return NULL;
06904             }
06905          }
06906 #ifdef ZAPATA_PRI
06907          if ((signalling == SIG_PRI) || (signalling == SIG_GR303FXOKS) || (signalling == SIG_GR303FXSKS)) {
06908             int offset;
06909             int myswitchtype;
06910             int matchesdchan;
06911             int x,y;
06912             offset = 0;
06913             if ((signalling == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
06914                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
06915                destroy_zt_pvt(&tmp);
06916                return NULL;
06917             }
06918             if (span >= NUM_SPANS) {
06919                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
06920                destroy_zt_pvt(&tmp);
06921                return NULL;
06922             } else {
06923                si.spanno = 0;
06924                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
06925                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
06926                   destroy_zt_pvt(&tmp);
06927                   return NULL;
06928                }
06929                /* Store the logical span first based upon the real span */
06930                tmp->logicalspan = pris[span].prilogicalspan;
06931                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
06932                if (span < 0) {
06933                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
06934                   destroy_zt_pvt(&tmp);
06935                   return NULL;
06936                }
06937                if (signalling == SIG_PRI)
06938                   myswitchtype = switchtype;
06939                else
06940                   myswitchtype = PRI_SWITCH_GR303_TMC;
06941                /* Make sure this isn't a d-channel */
06942                matchesdchan=0;
06943                for (x=0;x<NUM_SPANS;x++) {
06944                   for (y=0;y<NUM_DCHANS;y++) {
06945                      if (pris[x].dchannels[y] == tmp->channel) {
06946                         matchesdchan = 1;
06947                         break;
06948                      }
06949                   }
06950                }
06951                offset = p.chanpos;
06952                if (!matchesdchan) {
06953                   if (pris[span].nodetype && (pris[span].nodetype != pritype)) {
06954                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
06955                      destroy_zt_pvt(&tmp);
06956                      return NULL;
06957                   }
06958                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
06959                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
06960                      destroy_zt_pvt(&tmp);
06961                      return NULL;
06962                   }
06963                   if ((pris[span].dialplan) && (pris[span].dialplan != dialplan)) {
06964                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
06965                      destroy_zt_pvt(&tmp);
06966                      return NULL;
06967                   }
06968                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, idledial)) {
06969                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, idledial);
06970                      destroy_zt_pvt(&tmp);
06971                      return NULL;
06972                   }
06973                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, idleext)) {
06974                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, idleext);
06975                      destroy_zt_pvt(&tmp);
06976                      return NULL;
06977                   }
06978                   if (pris[span].minunused && (pris[span].minunused != minunused)) {
06979                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, minunused);
06980                      destroy_zt_pvt(&tmp);
06981                      return NULL;
06982                   }
06983                   if (pris[span].minidle && (pris[span].minidle != minidle)) {
06984                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, minidle);
06985                      destroy_zt_pvt(&tmp);
06986                      return NULL;
06987                   }
06988                   if (pris[span].numchans >= MAX_CHANNELS) {
06989                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
06990                         pris[span].trunkgroup);
06991                      destroy_zt_pvt(&tmp);
06992                      return NULL;
06993                   }
06994                   pris[span].nodetype = pritype;
06995                   pris[span].switchtype = myswitchtype;
06996                   pris[span].nsf = nsf;
06997                   pris[span].dialplan = dialplan;
06998                   pris[span].localdialplan = localdialplan;
06999                   pris[span].pvts[pris[span].numchans++] = tmp;
07000                   pris[span].minunused = minunused;
07001                   pris[span].minidle = minidle;
07002                   pris[span].overlapdial = overlapdial;
07003                   pris[span].facilityenable = facilityenable;
07004                   ast_copy_string(pris[span].idledial, idledial, sizeof(pris[span].idledial));
07005                   ast_copy_string(pris[span].idleext, idleext, sizeof(pris[span].idleext));
07006                   ast_copy_string(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix));
07007                   ast_copy_string(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix));
07008                   ast_copy_string(pris[span].localprefix, localprefix, sizeof(pris[span].localprefix));
07009                   ast_copy_string(pris[span].privateprefix, privateprefix, sizeof(pris[span].privateprefix));
07010                   ast_copy_string(pris[span].unknownprefix, unknownprefix, sizeof(pris[span].unknownprefix));
07011                   pris[span].resetinterval = resetinterval;
07012                   
07013                   tmp->pri = &pris[span];
07014                   tmp->prioffset = offset;
07015                   tmp->call = NULL;
07016                } else {
07017                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07018                   destroy_zt_pvt(&tmp);
07019                   return NULL;
07020                }
07021             }
07022          } else {
07023             tmp->prioffset = 0;
07024          }
07025 #endif
07026 #ifdef ZAPATA_R2
07027          if (signalling == SIG_R2) {
07028             if (r2prot < 0) {
07029                ast_log(LOG_WARNING, "R2 Country not specified for channel %d -- Assuming China\n", tmp->channel);
07030                tmp->r2prot = MFCR2_PROT_CHINA;
07031             } else
07032                tmp->r2prot = r2prot;
07033             tmp->r2 = mfcr2_new(tmp->subs[SUB_REAL].zfd, tmp->r2prot, 1);
07034             if (!tmp->r2) {
07035                ast_log(LOG_WARNING, "Unable to create r2 call :(\n");
07036                zt_close(tmp->subs[SUB_REAL].zfd);
07037                destroy_zt_pvt(&tmp);
07038                return NULL;
07039             }
07040          } else {
07041             if (tmp->r2) 
07042                mfcr2_free(tmp->r2);
07043             tmp->r2 = NULL;
07044          }
07045 #endif
07046       } else {
07047          signalling = tmp->sig;
07048          radio = tmp->radio;
07049          memset(&p, 0, sizeof(p));
07050          if (tmp->subs[SUB_REAL].zfd > -1)
07051             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07052       }
07053       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07054       if ((signalling == SIG_FXSKS) || (signalling == SIG_FXSLS) ||
07055           (signalling == SIG_EM) || (signalling == SIG_EM_E1) ||  (signalling == SIG_EMWINK) ||
07056          (signalling == SIG_FEATD) || (signalling == SIG_FEATDMF) || (signalling == SIG_FEATDMF_TA) ||
07057            (signalling == SIG_FEATB) || (signalling == SIG_E911) ||
07058           (signalling == SIG_SF) || (signalling == SIG_SFWINK) ||
07059          (signalling == SIG_SF_FEATD) || (signalling == SIG_SF_FEATDMF) ||
07060            (signalling == SIG_SF_FEATB)) {
07061          p.starttime = 250;
07062       }
07063       if (radio) {
07064          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07065          p.channo = channel;
07066          p.rxwinktime = 1;
07067          p.rxflashtime = 1;
07068          p.starttime = 1;
07069          p.debouncetime = 5;
07070       }
07071       if (!radio) {
07072          p.channo = channel;
07073          /* Override timing settings based on config file */
07074          if (cur_prewink >= 0)
07075             p.prewinktime = cur_prewink;
07076          if (cur_preflash >= 0)
07077             p.preflashtime = cur_preflash;
07078          if (cur_wink >= 0)
07079             p.winktime = cur_wink;
07080          if (cur_flash >= 0)
07081             p.flashtime = cur_flash;
07082          if (cur_start >= 0)
07083             p.starttime = cur_start;
07084          if (cur_rxwink >= 0)
07085             p.rxwinktime = cur_rxwink;
07086          if (cur_rxflash >= 0)
07087             p.rxflashtime = cur_rxflash;
07088          if (cur_debounce >= 0)
07089             p.debouncetime = cur_debounce;
07090       }
07091       
07092       /* dont set parms on a pseudo-channel (or CRV) */
07093       if (tmp->subs[SUB_REAL].zfd >= 0)
07094       {
07095          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07096          if (res < 0) {
07097             ast_log(LOG_ERROR, "Unable to set parameters\n");
07098             destroy_zt_pvt(&tmp);
07099             return NULL;
07100          }
07101       }
07102 #if 1
07103       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07104          memset(&bi, 0, sizeof(bi));
07105          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07106          if (!res) {
07107             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07108             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07109             bi.numbufs = numbufs;
07110             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07111             if (res < 0) {
07112                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07113             }
07114          } else
07115             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07116       }
07117 #endif
07118       tmp->immediate = immediate;
07119       tmp->transfertobusy = transfertobusy;
07120       tmp->sig = signalling;
07121       tmp->radio = radio;
07122       tmp->ringt_base = ringt_base;
07123       tmp->firstradio = 0;
07124       if ((signalling == SIG_FXOKS) || (signalling == SIG_FXOLS) || (signalling == SIG_FXOGS))
07125          tmp->permcallwaiting = callwaiting;
07126       else
07127          tmp->permcallwaiting = 0;
07128       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07129       tmp->destroy = 0;
07130       tmp->drings = drings;
07131       tmp->usedistinctiveringdetection = usedistinctiveringdetection;
07132       tmp->callwaitingcallerid = callwaitingcallerid;
07133       tmp->threewaycalling = threewaycalling;
07134       tmp->adsi = adsi;
07135       tmp->permhidecallerid = hidecallerid;
07136       tmp->callreturn = callreturn;
07137       tmp->echocancel = echocancel;
07138       tmp->echotraining = echotraining;
07139       tmp->pulse = pulse;
07140       tmp->echocanbridged = echocanbridged;
07141       tmp->busydetect = busydetect;
07142       tmp->busycount = busycount;
07143       tmp->busy_tonelength = busy_tonelength;
07144       tmp->busy_quietlength = busy_quietlength;
07145       tmp->callprogress = callprogress;
07146       tmp->cancallforward = cancallforward;
07147       tmp->dtmfrelax = relaxdtmf;
07148       tmp->callwaiting = tmp->permcallwaiting;
07149       tmp->hidecallerid = tmp->permhidecallerid;
07150       tmp->channel = channel;
07151       tmp->stripmsd = stripmsd;
07152       tmp->use_callerid = use_callerid;
07153       tmp->cid_signalling = cid_signalling;
07154       tmp->cid_start = cid_start;
07155       tmp->zaptrcallerid = zaptrcallerid;
07156       tmp->restrictcid = restrictcid;
07157       tmp->use_callingpres = use_callingpres;
07158       tmp->priindication_oob = priindication_oob;
07159       tmp->priexclusive = cur_priexclusive;
07160       if (tmp->usedistinctiveringdetection) {
07161          if (!tmp->use_callerid) {
07162             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07163             tmp->use_callerid = 1;
07164          }
07165       }
07166 
07167       ast_copy_string(tmp->accountcode, accountcode, sizeof(tmp->accountcode));
07168       tmp->amaflags = amaflags;
07169       if (!here) {
07170          tmp->confno = -1;
07171          tmp->propconfno = -1;
07172       }
07173       tmp->canpark = canpark;
07174       tmp->transfer = transfer;
07175       ast_copy_string(tmp->defcontext,context,sizeof(tmp->defcontext));
07176       ast_copy_string(tmp->language, language, sizeof(tmp->language));
07177       ast_copy_string(tmp->musicclass, musicclass, sizeof(tmp->musicclass));
07178       ast_copy_string(tmp->context, context, sizeof(tmp->context));
07179       ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
07180       tmp->cid_ton = 0;
07181       ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));
07182       ast_copy_string(tmp->mailbox, mailbox, sizeof(tmp->mailbox));
07183       tmp->msgstate = -1;
07184       tmp->group = cur_group;
07185       tmp->callgroup=cur_callergroup;
07186       tmp->pickupgroup=cur_pickupgroup;
07187       tmp->rxgain = rxgain;
07188       tmp->txgain = txgain;
07189       tmp->tonezone = tonezone;
07190       tmp->onhooktime = time(NULL);
07191       if (tmp->subs[SUB_REAL].zfd > -1) {
07192          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07193          if (tmp->dsp)
07194             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07195          update_conf(tmp);
07196          if (!here) {
07197             if ((signalling != SIG_PRI) && (signalling != SIG_R2))
07198                /* Hang it up to be sure it's good */
07199                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07200          }
07201          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07202 #ifdef ZAPATA_PRI
07203          /* the dchannel is down so put the channel in alarm */
07204          if (tmp->pri && !pri_is_up(tmp->pri))
07205             tmp->inalarm = 1;
07206          else
07207             tmp->inalarm = 0;
07208 #endif            
07209          memset(&si, 0, sizeof(si));
07210          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07211             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07212             destroy_zt_pvt(&tmp);
07213             return NULL;
07214          }
07215          if (si.alarms) tmp->inalarm = 1;
07216       }
07217 
07218       tmp->polarityonanswerdelay = polarityonanswerdelay;
07219       tmp->answeronpolarityswitch = answeronpolarityswitch;
07220       tmp->hanguponpolarityswitch = hanguponpolarityswitch;
07221       tmp->sendcalleridafter = sendcalleridafter;
07222 
07223    }
07224    if (tmp && !here) {
07225       /* nothing on the iflist */
07226       if (!*wlist) {
07227          *wlist = tmp;
07228          tmp->prev = NULL;
07229          tmp->next = NULL;
07230          *wend = tmp;
07231       } else {
07232          /* at least one member on the iflist */
07233          struct zt_pvt *working = *wlist;
07234 
07235          /* check if we maybe have to put it on the begining */
07236          if (working->channel > tmp->channel) {
07237             tmp->next = *wlist;
07238             tmp->prev = NULL;
07239             (*wlist)->prev = tmp;
07240             *wlist = tmp;
07241          } else {
07242          /* go through all the members and put the member in the right place */
07243             while (working) {
07244                /* in the middle */
07245                if (working->next) {
07246                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07247                      tmp->next = working->next;
07248                      tmp->prev = working;
07249                      working->next->prev = tmp;
07250                      working->next = tmp;
07251                      break;
07252                   }
07253                } else {
07254                /* the last */
07255                   if (working->channel < tmp->channel) {
07256                      working->next = tmp;
07257                      tmp->next = NULL;
07258                      tmp->prev = working;
07259                      *wend = tmp;
07260                      break;
07261                   }
07262                }
07263                working = working->next;
07264             }
07265          }
07266       }
07267    }
07268    return tmp;
07269 }

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

Definition at line 5169 of file chan_zap.c.

References ast_waitfordigit().

Referenced by ss_thread().

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

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

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

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

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

References ast_log(), and setup_zap().

11062 {
11063    int res = 0;
11064 
11065    res = setup_zap(1);
11066    if (res) {
11067       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11068       return -1;
11069    }
11070    return 0;
11071 }

static int reset_conf ( struct zt_pvt p  )  [static]

Definition at line 1307 of file chan_zap.c.

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

Referenced by zt_hangup().

01308 {
01309    ZT_CONFINFO zi;
01310    memset(&zi, 0, sizeof(zi));
01311    p->confno = -1;
01312    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01313    if (p->subs[SUB_REAL].zfd > -1) {
01314       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01315          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01316    }
01317    return 0;
01318 }

static int restart_monitor ( void   )  [static]

Definition at line 6658 of file chan_zap.c.

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

06659 {
06660    pthread_attr_t attr;
06661    pthread_attr_init(&attr);
06662    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06663    /* If we're supposed to be stopped -- stay stopped */
06664    if (monitor_thread == AST_PTHREADT_STOP)
06665       return 0;
06666    if (ast_mutex_lock(&monlock)) {
06667       ast_log(LOG_WARNING, "Unable to lock monitor\n");
06668       return -1;
06669    }
06670    if (monitor_thread == pthread_self()) {
06671       ast_mutex_unlock(&monlock);
06672       ast_log(LOG_WARNING, "Cannot kill myself\n");
06673       return -1;
06674    }
06675    if (monitor_thread != AST_PTHREADT_NULL) {
06676       /* Just signal it to be sure it wakes up */
06677 #if 0
06678       pthread_cancel(monitor_thread);
06679 #endif
06680       pthread_kill(monitor_thread, SIGURG);
06681 #if 0
06682       pthread_join(monitor_thread, NULL);
06683 #endif
06684    } else {
06685       /* Start a new monitor */
06686       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
06687          ast_mutex_unlock(&monlock);
06688          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
06689          return -1;
06690       }
06691    }
06692    ast_mutex_unlock(&monlock);
06693    return 0;
06694 }

static int restore_conference ( struct zt_pvt p  )  [static]

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

01634 {
01635    int res;
01636    if (p->saveconf.confmode) {
01637       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01638       p->saveconf.confmode = 0;
01639       if (res) {
01640          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01641          return -1;
01642       }
01643    }
01644    if (option_debug)
01645       ast_log(LOG_DEBUG, "Restored conferencing\n");
01646    return 0;
01647 }

static int restore_gains ( struct zt_pvt p  )  [static]

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

01564 {
01565    int res;
01566 
01567    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01568    if (res) {
01569       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01570       return -1;
01571    }
01572 
01573    return 0;
01574 }

static int save_conference ( struct zt_pvt p  )  [static]

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

01606 {
01607    struct zt_confinfo c;
01608    int res;
01609    if (p->saveconf.confmode) {
01610       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01611       return -1;
01612    }
01613    p->saveconf.chan = 0;
01614    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01615    if (res) {
01616       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01617       p->saveconf.confmode = 0;
01618       return -1;
01619    }
01620    c.chan = 0;
01621    c.confno = 0;
01622    c.confmode = ZT_CONF_NORMAL;
01623    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01624    if (res) {
01625       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01626       return -1;
01627    }
01628    if (option_debug)
01629       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01630    return 0;
01631 }

static int send_callerid ( struct zt_pvt p  )  [static]

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

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

int send_cwcidspill ( struct zt_pvt p  ) 

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

01652 {
01653    p->callwaitcas = 0;
01654    p->cidcwexpire = 0;
01655    p->cidspill = malloc(MAX_CALLERID_SIZE);
01656    if (p->cidspill) {
01657       memset(p->cidspill, 0x7f, MAX_CALLERID_SIZE);
01658       p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01659       /* Make sure we account for the end */
01660       p->cidlen += READ_SIZE * 4;
01661       p->cidpos = 0;
01662       send_callerid(p);
01663       if (option_verbose > 2)
01664          ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01665    } else return -1;
01666    return 0;
01667 }

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

Definition at line 1544 of file chan_zap.c.

References set_actual_rxgain(), and set_actual_txgain().

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

01545 {
01546    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01547 }

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

Definition at line 1526 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

01527 {
01528    struct zt_gains g;
01529    int res;
01530 
01531    memset(&g, 0, sizeof(g));
01532    g.chan = chan;
01533    res = ioctl(fd, ZT_GETGAINS, &g);
01534    if (res) {
01535       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01536       return res;
01537    }
01538 
01539    fill_rxgain(&g, gain, law);
01540 
01541    return ioctl(fd, ZT_SETGAINS, &g);
01542 }

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

Definition at line 1508 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

01509 {
01510    struct zt_gains g;
01511    int res;
01512 
01513    memset(&g, 0, sizeof(g));
01514    g.chan = chan;
01515    res = ioctl(fd, ZT_GETGAINS, &g);
01516    if (res) {
01517       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01518       return res;
01519    }
01520 
01521    fill_txgain(&g, gain, law);
01522 
01523    return ioctl(fd, ZT_SETGAINS, &g);
01524 }

static int setup_zap ( int  reload  )  [static]

Definition at line 10122 of file chan_zap.c.

References 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(), cfg, CHAN_PSEUDO, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_V23, CID_START_POLARITY, CID_START_RING, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, ast_variable::lineno, LOG_ERROR, mkintf(), ast_variable::name, ast_variable::next, option_verbose, READ_SIZE, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, 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, strsep(), ast_variable::value, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.

Referenced by load_module(), and reload().

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

static void * ss_thread ( void *  data  )  [static]

Definition at line 5206 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_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, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, ast_frame::frametype, free, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, ast_channel::language, zt_pvt::lastcid_num, callerid_state::len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, manager_event(), my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, callerid_state::number, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::transfer, ast_channel::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().

Referenced by handle_init_event(), and zt_handle_event().

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

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

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

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

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

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

00991 {
00992    if (!x) {
00993       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
00994       return -1;
00995    }
00996    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
00997    if (p->subs[x].zfd > -1) {
00998       zt_close(p->subs[x].zfd);
00999    }
01000    p->subs[x].zfd = -1;
01001    p->subs[x].linear = 0;
01002    p->subs[x].chan = 0;
01003    p->subs[x].owner = NULL;
01004    p->subs[x].inthreeway = 0;
01005    p->polarity = POLARITY_IDLE;
01006    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01007    return 0;
01008 }

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

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

10113 {
10114 #ifdef ZAPATA_PRI    
10115    int y;
10116    for (y=0;y<NUM_SPANS;y++)
10117       ast_mutex_destroy(&pris[y].lock);
10118 #endif
10119    return __unload_module();
10120 }

static int update_conf ( struct zt_pvt p  )  [static]

Definition at line 1320 of file chan_zap.c.

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

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

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

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

11074 {
11075    return usecnt;
11076 }

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

Definition at line 800 of file chan_zap.c.

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

Referenced by swap_subs().

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

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

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

09507 {
09508    int channel = 0;
09509    struct zt_pvt *tmp = NULL;
09510    struct zt_pvt *prev = NULL;
09511    
09512    if (argc != 4) {
09513       return RESULT_SHOWUSAGE;
09514    }
09515    channel = atoi(argv[3]);
09516 
09517    tmp = iflist;
09518    while (tmp) {
09519       if (tmp->channel == channel) {
09520          destroy_channel(prev, tmp, 1);
09521          return RESULT_SUCCESS;
09522       }
09523       prev = tmp;
09524       tmp = tmp->next;
09525    }
09526    return RESULT_FAILURE;
09527 }

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

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

09855 {
09856    if (p) {
09857       switch(mode) {
09858          case TRANSFER:
09859             p->fake_event = ZT_EVENT_WINKFLASH;
09860             break;
09861          case HANGUP:
09862             p->fake_event = ZT_EVENT_ONHOOK;
09863             break;
09864          default:
09865             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
09866       }
09867    }
09868    return 0;
09869 }

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

Definition at line 831 of file chan_zap.c.

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

Referenced by action_zapdialoffhook().

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

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

Definition at line 9590 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, lock, zt_pvt::master, 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, and zt_pvt::subs.

09591 {
09592    int channel;
09593    struct zt_pvt *tmp = NULL;
09594    ZT_CONFINFO ci;
09595    ZT_PARAMS ps;
09596    int x;
09597    ast_mutex_t *lock;
09598    struct zt_pvt *start;
09599 #ifdef ZAPATA_PRI
09600    char *c;
09601    int trunkgroup;
09602    struct zt_pri *pri=NULL;
09603 #endif
09604 
09605    lock = &iflock;
09606    start = iflist;
09607 
09608    if (argc != 4)
09609       return RESULT_SHOWUSAGE;
09610 #ifdef ZAPATA_PRI
09611    if ((c = strchr(argv[3], ':'))) {
09612       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
09613          return RESULT_SHOWUSAGE;
09614       if ((trunkgroup < 1) || (channel < 1))
09615          return RESULT_SHOWUSAGE;
09616       for (x=0;x<NUM_SPANS;x++) {
09617          if (pris[x].trunkgroup == trunkgroup) {
09618             pri = pris + x;
09619             break;
09620          }
09621       }
09622       if (pri) {
09623          start = pri->crvs;
09624          lock = &pri->lock;
09625       } else {
09626          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09627          return RESULT_FAILURE;
09628       }
09629    } else
09630 #endif
09631       channel = atoi(argv[3]);
09632 
09633    ast_mutex_lock(lock);
09634    tmp = start;
09635    while (tmp) {
09636       if (tmp->channel == channel) {
09637 #ifdef ZAPATA_PRI
09638          if (pri) 
09639             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
09640          else
09641 #endif         
09642          ast_cli(fd, "Channel: %d\n", tmp->channel);
09643          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
09644          ast_cli(fd, "Span: %d\n", tmp->span);
09645          ast_cli(fd, "Extension: %s\n", tmp->exten);
09646          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
09647          ast_cli(fd, "Context: %s\n", tmp->context);
09648          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
09649          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
09650          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
09651          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
09652          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
09653          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
09654          ast_cli(fd, "Radio: %d\n", tmp->radio);
09655          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
09656          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)" : "");
09657          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)" : "");
09658          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)" : "");
09659          ast_cli(fd, "Confno: %d\n", tmp->confno);
09660          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
09661          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
09662          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
09663          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
09664          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
09665          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
09666          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
09667          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
09668          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
09669          if (tmp->master)
09670             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
09671          for (x=0;x<MAX_SLAVES;x++) {
09672             if (tmp->slaves[x])
09673                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
09674          }
09675 #ifdef ZAPATA_PRI
09676          if (tmp->pri) {
09677             ast_cli(fd, "PRI Flags: ");
09678             if (tmp->resetting)
09679                ast_cli(fd, "Resetting ");
09680             if (tmp->call)
09681                ast_cli(fd, "Call ");
09682             if (tmp->bearer)
09683                ast_cli(fd, "Bearer ");
09684             ast_cli(fd, "\n");
09685             if (tmp->logicalspan) 
09686                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
09687             else
09688                ast_cli(fd, "PRI Logical Span: Implicit\n");
09689          }
09690             
09691 #endif
09692 #ifdef ZAPATA_R2
09693          if (tmp->r2) {
09694             ast_cli(fd, "R2 Flags: ");
09695             if (tmp->r2blocked)
09696                ast_cli(fd, "Blocked ");
09697             if (tmp->hasr2call)
09698                ast_cli(fd, "Call ");
09699             ast_cli(fd, "\n");
09700          }
09701 #endif
09702          memset(&ci, 0, sizeof(ci));
09703          ps.channo = tmp->channel;
09704          if (tmp->subs[SUB_REAL].zfd > -1) {
09705             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
09706                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
09707             }
09708 #ifdef ZT_GETCONFMUTE
09709             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
09710                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
09711             }
09712 #endif
09713             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
09714                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
09715             } else {
09716                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
09717             }
09718          }
09719          ast_mutex_unlock(lock);
09720          return RESULT_SUCCESS;
09721       }
09722       tmp = tmp->next;
09723    }
09724    
09725    ast_cli(fd, "Unable to find given channel %d\n", channel);
09726    ast_mutex_unlock(lock);
09727    return RESULT_FAILURE;
09728 }

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

Definition at line 9529 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, lock, zt_pvt::musicclass, zt_pvt::next, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

09530 {
09531 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09532 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09533    struct zt_pvt *tmp = NULL;
09534    char tmps[20] = "";
09535    ast_mutex_t *lock;
09536    struct zt_pvt *start;
09537 #ifdef ZAPATA_PRI
09538    int trunkgroup;
09539    struct zt_pri *pri=NULL;
09540    int x;
09541 #endif
09542 
09543    lock = &iflock;
09544    start = iflist;
09545 
09546 #ifdef ZAPATA_PRI
09547    if (argc == 4) {
09548       if ((trunkgroup = atoi(argv[3])) < 1)
09549          return RESULT_SHOWUSAGE;
09550       for (x=0;x<NUM_SPANS;x++) {
09551          if (pris[x].trunkgroup == trunkgroup) {
09552             pri = pris + x;
09553             break;
09554          }
09555       }
09556       if (pri) {
09557          start = pri->crvs;
09558          lock = &pri->lock;
09559       } else {
09560          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09561          return RESULT_FAILURE;
09562       }
09563    } else
09564 #endif
09565    if (argc != 3)
09566       return RESULT_SHOWUSAGE;
09567 
09568    ast_mutex_lock(lock);
09569 #ifdef ZAPATA_PRI
09570    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MusicOnHold");
09571 #else
09572    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MusicOnHold");
09573 #endif   
09574    
09575    tmp = start;
09576    while (tmp) {
09577       if (tmp->channel > 0) {
09578          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09579       } else
09580          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09581       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->musicclass);
09582       tmp = tmp->next;
09583    }
09584    ast_mutex_unlock(lock);
09585    return RESULT_SUCCESS;
09586 #undef FORMAT
09587 #undef FORMAT2
09588 }

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

Definition at line 9761 of file chan_zap.c.

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

09761                                                            {
09762    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
09763    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
09764 
09765    int span;
09766    int res;
09767    char alarms[50];
09768 
09769    int ctl;
09770    ZT_SPANINFO s;
09771 
09772    ctl = open("/dev/zap/ctl", O_RDWR);
09773    if (ctl < 0) {
09774       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
09775       ast_cli(fd, "No Zaptel interface found.\n");
09776       return RESULT_FAILURE;
09777    }
09778    ast_cli(fd,FORMAT2, "Description", "Alarms","IRQ","bpviol","CRC4");
09779 
09780    for (span=1;span < ZT_MAX_SPANS;++span) {
09781       s.spanno = span;
09782       res = ioctl(ctl, ZT_SPANSTAT, &s);
09783       if (res) {
09784          continue;
09785       }
09786       alarms[0] = '\0';
09787       if (s.alarms > 0) {
09788          if (s.alarms & ZT_ALARM_BLUE)
09789             strcat(alarms,"BLU/");
09790          if (s.alarms & ZT_ALARM_YELLOW)
09791             strcat(alarms, "YEL/");
09792          if (s.alarms & ZT_ALARM_RED)
09793             strcat(alarms, "RED/");
09794          if (s.alarms & ZT_ALARM_LOOPBACK)
09795             strcat(alarms,"LB/");
09796          if (s.alarms & ZT_ALARM_RECOVER)
09797             strcat(alarms,"REC/");
09798          if (s.alarms & ZT_ALARM_NOTOPEN)
09799             strcat(alarms, "NOP/");
09800          if (!strlen(alarms))
09801             strcat(alarms, "UUU/");
09802          if (strlen(alarms)) {
09803             /* Strip trailing / */
09804             alarms[strlen(alarms)-1]='\0';
09805          }
09806       } else {
09807          if (s.numchans)
09808             strcpy(alarms, "OK");
09809          else
09810             strcpy(alarms, "UNCONFIGURED");
09811       }
09812 
09813       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
09814    }
09815    close(ctl);
09816 
09817    return RESULT_SUCCESS;
09818 #undef FORMAT
09819 #undef FORMAT2
09820 }

static char* zap_sig2str ( int  sig  )  [static]

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

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

static int zt_answer ( struct ast_channel ast  )  [static]

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

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

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 2993 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_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, master, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().

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

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

Definition at line 1739 of file chan_zap.c.

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

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

static int zt_callwait ( struct ast_channel ast  )  [static]

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

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

static void zt_close ( int  fd  )  [static]

Definition at line 930 of file chan_zap.c.

Referenced by __unload_module(), alloc_sub(), destroy_channel(), mkintf(), and unalloc_sub().

00931 {
00932    if(fd > 0)
00933       close(fd);
00934 }

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

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

01590 {
01591    int x, y, res;
01592    x = muted;
01593    if (p->sig == SIG_PRI) {
01594       y = 1;
01595       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01596       if (res)
01597          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01598    }
01599    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01600    if (res < 0) 
01601       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01602    return res;
01603 }

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

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

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

static void zt_disable_ec ( struct zt_pvt p  )  [static]

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

01426 {
01427    int x;
01428    int res;
01429    if (p->echocancel) {
01430       x = 0;
01431       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01432       if (res) 
01433          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01434       else
01435          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01436    }
01437    p->echocanon = 0;
01438 }

static void zt_enable_ec ( struct zt_pvt p  )  [static]

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

01377 {
01378    int x;
01379    int res;
01380    if (!p)
01381       return;
01382    if (p->echocanon) {
01383       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01384       return;
01385    }
01386    if (p->digital) {
01387       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01388       return;
01389    }
01390    if (p->echocancel) {
01391       if (p->sig == SIG_PRI) {
01392          x = 1;
01393          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01394          if (res)
01395             ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01396       }
01397       x = p->echocancel;
01398       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01399       if (res) 
01400          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01401       else {
01402          p->echocanon = 1;
01403          ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01404       }
01405    } else
01406       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01407 }

struct ast_frame * zt_exception ( struct ast_channel ast  ) 

Definition at line 4362 of file chan_zap.c.

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

04363 {
04364    struct zt_pvt *p = ast->tech_pvt;
04365    struct ast_frame *f;
04366    ast_mutex_lock(&p->lock);
04367    f = __zt_exception(ast);
04368    ast_mutex_unlock(&p->lock);
04369    return f;
04370 }

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

Definition at line 3276 of file chan_zap.c.

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

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

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_index ( struct ast_channel ast,
struct zt_pvt p,
int  nullok 
) [static]

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

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

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

Definition at line 3510 of file chan_zap.c.

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

Referenced by __zt_exception().

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

static int zt_hangup ( struct ast_channel ast  )  [static]

Definition at line 2298 of file chan_zap.c.

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

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

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

Definition at line 4809 of file chan_zap.c.

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

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

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

Definition at line 2931 of file chan_zap.c.

References ast_log(), LOG_WARNING, and master.

Referenced by zt_bridge().

02931                                                                  {
02932    int x;
02933    if (!slave || !master) {
02934       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
02935       return;
02936    }
02937    for (x=0;x<MAX_SLAVES;x++) {
02938       if (!master->slaves[x]) {
02939          master->slaves[x] = slave;
02940          break;
02941       }
02942    }
02943    if (x >= MAX_SLAVES) {
02944       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
02945       master->slaves[MAX_SLAVES - 1] = slave;
02946    }
02947    if (slave->master) 
02948       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
02949    slave->master = master;
02950    
02951    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
02952 }

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

Definition at line 4975 of file chan_zap.c.

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

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

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

static int zt_open ( char *  fn  )  [static]

Definition at line 889 of file chan_zap.c.

References ast_log(), LOG_WARNING, and READ_SIZE.

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

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

struct ast_frame * zt_read ( struct ast_channel ast  ) 

Definition at line 4372 of file chan_zap.c.

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

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

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

Definition at line 7446 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, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::name, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), round_robin, s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, and zt_new().

07447 {
07448    int oldformat;
07449    int groupmatch = 0;
07450    int channelmatch = -1;
07451    int roundrobin = 0;
07452    int callwait = 0;
07453    int busy = 0;
07454    struct zt_pvt *p;
07455    struct ast_channel *tmp = NULL;
07456    char *dest=NULL;
07457    int x;
07458    char *s;
07459    char opt=0;
07460    int res=0, y=0;
07461    int backwards = 0;
07462 #ifdef ZAPATA_PRI
07463    int crv;
07464    int bearer = -1;
07465    int trunkgroup;
07466    struct zt_pri *pri=NULL;
07467 #endif   
07468    struct zt_pvt *exit, *start, *end;
07469    ast_mutex_t *lock;
07470    int channelmatched = 0;
07471    int groupmatched = 0;
07472    
07473    /* Assume we're locking the iflock */
07474    lock = &iflock;
07475    start = iflist;
07476    end = ifend;
07477    /* We do signed linear */
07478    oldformat = format;
07479    format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
07480    if (!format) {
07481       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
07482       return NULL;
07483    }
07484    if (data) {
07485       dest = ast_strdupa((char *)data);
07486    } else {
07487       ast_log(LOG_WARNING, "Channel requested with no data\n");
07488       return NULL;
07489    }
07490    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07491       /* Retrieve the group number */
07492       char *stringp=NULL;
07493       stringp=dest + 1;
07494       s = strsep(&stringp, "/");
07495       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07496          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07497          return NULL;
07498       }
07499       groupmatch = 1 << x;
07500       if (toupper(dest[0]) == 'G') {
07501          if (dest[0] == 'G') {
07502             backwards = 1;
07503             p = ifend;
07504          } else
07505             p = iflist;
07506       } else {
07507          if (dest[0] == 'R') {
07508             backwards = 1;
07509             p = round_robin[x]?round_robin[x]->prev:ifend;
07510             if (!p)
07511                p = ifend;
07512          } else {
07513             p = round_robin[x]?round_robin[x]->next:iflist;
07514             if (!p)
07515                p = iflist;
07516          }
07517          roundrobin = 1;
07518       }
07519    } else {
07520       char *stringp=NULL;
07521       stringp=dest;
07522       s = strsep(&stringp, "/");
07523       p = iflist;
07524       if (!strcasecmp(s, "pseudo")) {
07525          /* Special case for pseudo */
07526          x = CHAN_PSEUDO;
07527          channelmatch = x;
07528       } 
07529 #ifdef ZAPATA_PRI
07530       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07531          if ((trunkgroup < 1) || (crv < 1)) {
07532             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07533             return NULL;
07534          }
07535          res--;
07536          for (x=0;x<NUM_SPANS;x++) {
07537             if (pris[x].trunkgroup == trunkgroup) {
07538                pri = pris + x;
07539                lock = &pri->lock;
07540                start = pri->crvs;
07541                end = pri->crvend;
07542                break;
07543             }
07544          }
07545          if (!pri) {
07546             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07547             return NULL;
07548          }
07549          channelmatch = crv;
07550          p = pris[x].crvs;
07551       }
07552 #endif   
07553       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07554          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07555          return NULL;
07556       } else {
07557          channelmatch = x;
07558       }
07559    }
07560    /* Search for an unowned channel */
07561    if (ast_mutex_lock(lock)) {
07562       ast_log(LOG_ERROR, "Unable to lock interface list???\n");
07563       return NULL;
07564    }
07565    exit = p;
07566    while(p && !tmp) {
07567       if (roundrobin)
07568          round_robin[x] = p;
07569 #if 0
07570       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07571 #endif
07572 
07573       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07574          if (option_debug)
07575             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07576             if (p->inalarm) 
07577                goto next;
07578 
07579          callwait = (p->owner != NULL);
07580 #ifdef ZAPATA_PRI
07581          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07582             if (p->sig != SIG_FXSKS) {
07583                /* Gotta find an actual channel to use for this
07584                   CRV if this isn't a callwait */
07585                bearer = pri_find_empty_chan(pri, 0);
07586                if (bearer < 0) {
07587                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07588                   p = NULL;
07589                   break;
07590                }
07591                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07592             } else {
07593                if (alloc_sub(p, 0)) {
07594                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07595                   p = NULL;
07596                   break;
07597                } else
07598                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07599                p->pri = pri;
07600             }
07601          }
07602 #endif         
07603          if (p->channel == CHAN_PSEUDO) {
07604             p = chandup(p);
07605             if (!p) {
07606                break;
07607             }
07608          }
07609          if (p->owner) {
07610             if (alloc_sub(p, SUB_CALLWAIT)) {
07611                p = NULL;
07612                break;
07613             }
07614          }
07615          p->outgoing = 1;
07616          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07617 #ifdef ZAPATA_PRI
07618          if (p->bearer) {
07619             /* Log owner to bearer channel, too */
07620             p->bearer->owner = tmp;
07621          }
07622 #endif         
07623          /* Make special notes */
07624          if (res > 1) {
07625             if (opt == 'c') {
07626                /* Confirm answer */
07627                p->confirmanswer = 1;
07628             } else if (opt == 'r') {
07629                /* Distinctive ring */
07630                if (res < 3)
07631                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07632                else
07633                   p->distinctivering = y;
07634             } else if (opt == 'd') {
07635                /* If this is an ISDN call, make it digital */
07636                p->digital = 1;
07637                if (tmp)
07638                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07639             } else {
07640                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07641             }
07642          }
07643          /* Note if the call is a call waiting call */
07644          if (tmp && callwait)
07645             tmp->cdrflags |= AST_CDR_CALLWAIT;
07646          break;
07647       }
07648 next:
07649       if (backwards) {
07650          p = p->prev;
07651          if (!p)
07652             p = end;
07653       } else {
07654          p = p->next;
07655          if (!p)
07656             p = start;
07657       }
07658       /* stop when you roll to the one that we started from */
07659       if (p == exit)
07660          break;
07661    }
07662    ast_mutex_unlock(lock);
07663    restart_monitor();
07664    if (callwait)
07665       *cause = AST_CAUSE_BUSY;
07666    else if (!tmp) {
07667       if (channelmatched) {
07668          if (busy)
07669             *cause = AST_CAUSE_BUSY;
07670       } else if (groupmatched) {
07671          *cause = AST_CAUSE_CONGESTION;
07672       }
07673    }
07674       
07675    return tmp;
07676 }

static int zt_ring_phone ( struct zt_pvt p  )  [static]

Definition at line 3298 of file chan_zap.c.

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

Referenced by __zt_exception(), and zt_handle_event().

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

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

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

10961 {
10962 #define  END_SILENCE_LEN 400
10963 #define  HEADER_MS 50
10964 #define  TRAILER_MS 5
10965 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
10966 #define  ASCII_BYTES_PER_CHAR 80
10967 
10968    unsigned char *buf,*mybuf;
10969    struct zt_pvt *p = c->tech_pvt;
10970    struct pollfd fds[1];
10971    int size,res,fd,len,x;
10972    int bytes=0;
10973    /* Initial carrier (imaginary) */
10974    float cr = 1.0;
10975    float ci = 0.0;
10976    float scont = 0.0;
10977    int index;
10978 
10979    index = zt_get_index(c, p, 0);
10980    if (index < 0) {
10981       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
10982       return -1;
10983    }
10984    if (!text[0]) return(0); /* if nothing to send, dont */
10985    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
10986    if (p->mate) 
10987       buf = malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
10988    else
10989       buf = malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
10990    if (!buf) {
10991       ast_log(LOG_ERROR, "MALLOC FAILED\n");
10992       return -1;
10993    }
10994    mybuf = buf;
10995    if (p->mate) {
10996       int codec = AST_LAW(p);
10997       for (x=0;x<HEADER_MS;x++) {   /* 50 ms of Mark */
10998          PUT_CLID_MARKMS;
10999          }
11000       /* Put actual message */
11001       for (x=0;text[x];x++)  {
11002          PUT_CLID(text[x]);
11003          }
11004       for (x=0;x<TRAILER_MS;x++) {  /* 5 ms of Mark */
11005          PUT_CLID_MARKMS;
11006          }
11007       len = bytes;
11008       buf = mybuf;
11009    }
11010    else {
11011       len = tdd_generate(p->tdd,buf,text);
11012       if (len < 1) {
11013          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n",(int)strlen(text));
11014          free(mybuf);
11015          return -1;
11016       }
11017    }
11018    memset(buf + len,0x7f,END_SILENCE_LEN);
11019    len += END_SILENCE_LEN;
11020    fd = p->subs[index].zfd;
11021    while(len) {
11022       if (ast_check_hangup(c)) {
11023          free(mybuf);
11024          return -1;
11025       }
11026       size = len;
11027       if (size > READ_SIZE)
11028          size = READ_SIZE;
11029       fds[0].fd = fd;
11030       fds[0].events = POLLOUT | POLLPRI;
11031       fds[0].revents = 0;
11032       res = poll(fds, 1, -1);
11033       if (!res) {
11034          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11035          continue;
11036       }
11037         /* if got exception */
11038       if (fds[0].revents & POLLPRI) return -1;
11039       if (!(fds[0].revents & POLLOUT)) {
11040          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11041          continue;
11042       }
11043       res = write(fd, buf, size);
11044       if (res != size) {
11045          if (res == -1) {
11046             free(mybuf);
11047             return -1;
11048          }
11049          if (option_debug)
11050             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11051          break;
11052       }
11053       len -= size;
11054       buf += size;
11055    }
11056    free(mybuf);
11057    return(0);
11058 }

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

Definition at line 1576 of file chan_zap.c.

References ast_log(), and LOG_WARNING.

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

01577 {
01578    int x, res;
01579    x = hs;
01580    res = ioctl(fd, ZT_HOOK, &x);
01581    if (res < 0) 
01582    {
01583       if (errno == EINPROGRESS) return 0;
01584       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01585    }
01586    return res;
01587 }

int zt_setlaw ( int  zfd,
int  law 
)

Definition at line 946 of file chan_zap.c.

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

int zt_setlinear ( int  zfd,
int  linear 
)

Definition at line 936 of file chan_zap.c.

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

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

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

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

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

static void zt_train_ec ( struct zt_pvt p  )  [static]

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

01410 {
01411    int x;
01412    int res;
01413    if (p && p->echocancel && p->echotraining) {
01414       x = p->echotraining;
01415       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01416       if (res) 
01417          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01418       else {
01419          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01420       }
01421    } else
01422       ast_log(LOG_DEBUG, "No echo training requested\n");
01423 }

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

Definition at line 2873 of file chan_zap.c.

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

Referenced by zt_bridge(), and zt_fixup().

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

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

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

Referenced by ss_thread().

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

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

Definition at line 4721 of file chan_zap.c.

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

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


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

Referenced by action_zapshowchannels().

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

Referenced by alarm2str(), and zap_show_status().

int amaflags = 0 [static]

Definition at line 273 of file chan_zap.c.

int answeronpolarityswitch = 0 [static]

Whether we answer on a Polarity Switch event.

Definition at line 335 of file chan_zap.c.

int busy_quietlength = 0 [static]

Definition at line 265 of file chan_zap.c.

int busy_tonelength = 0 [static]

Definition at line 264 of file chan_zap.c.

int busycount = 3 [static]

Definition at line 263 of file chan_zap.c.

int busydetect = 0 [static]

Definition at line 261 of file chan_zap.c.

struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static]

Definition at line 756 of file chan_zap.c.

int callprogress = 0 [static]

Definition at line 267 of file chan_zap.c.

int callreturn = 0 [static]

Definition at line 237 of file chan_zap.c.

int callwaiting = 0 [static]

Definition at line 227 of file chan_zap.c.

int callwaitingcallerid = 0 [static]

Definition at line 229 of file chan_zap.c.

int cancallforward = 0 [static]

Definition at line 245 of file chan_zap.c.

int canpark = 0 [static]

Definition at line 243 of file chan_zap.c.

char cid_name[256] = "" [static]

Definition at line 200 of file chan_zap.c.

char cid_num[256] = "" [static]

Definition at line 199 of file chan_zap.c.

int cid_signalling = CID_SIG_BELL [static]

Definition at line 213 of file chan_zap.c.

int cid_start = CID_START_RING [static]

Definition at line 214 of file chan_zap.c.

int cidrings[NUM_CADENCE_MAX] [static]

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

Definition at line 767 of file chan_zap.c.

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

Definition at line 160 of file chan_zap.c.

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

Definition at line 198 of file chan_zap.c.

ast_group_t cur_callergroup = 0 [static]

Definition at line 219 of file chan_zap.c.

int cur_debounce = -1 [static]

Definition at line 286 of file chan_zap.c.

int cur_flash = -1 [static]

Definition at line 282 of file chan_zap.c.

ast_group_t cur_group = 0 [static]

Definition at line 218 of file chan_zap.c.

ast_group_t cur_pickupgroup = 0 [static]

Definition at line 220 of file chan_zap.c.

int cur_preflash = -1 [static]

Definition at line 280 of file chan_zap.c.

int cur_prewink = -1 [static]

Definition at line 279 of file chan_zap.c.

int cur_priexclusive = 0 [static]

Definition at line 287 of file chan_zap.c.

int cur_rxflash = -1 [static]

Definition at line 285 of file chan_zap.c.

int cur_rxwink = -1 [static]

Definition at line 284 of file chan_zap.c.

int cur_signalling = -1 [static]

Definition at line 216 of file chan_zap.c.

int cur_start = -1 [static]

Definition at line 283 of file chan_zap.c.

int cur_wink = -1 [static]

Definition at line 281 of file chan_zap.c.

char defaultcic[64] = "" [static]

Definition at line 201 of file chan_zap.c.

char defaultozz[64] = "" [static]

Definition at line 202 of file chan_zap.c.

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

Definition at line 141 of file chan_zap.c.

char destroy_channel_usage[] [static]

Initial value:

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

Definition at line 9834 of file chan_zap.c.

struct zt_distRings drings [static]

Definition at line 482 of file chan_zap.c.

Referenced by setup_zap().

int echocanbridged = 0 [static]

Definition at line 259 of file chan_zap.c.

int echocancel [static]

Definition at line 253 of file chan_zap.c.

int echotraining [static]

Definition at line 255 of file chan_zap.c.

char* events[] [static]

Definition at line 1052 of file chan_zap.c.

Referenced by authenticate(), and geteventbyname().

int firstdigittimeout = 16000 [static]

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

Definition at line 313 of file chan_zap.c.

int gendigittimeout = 8000 [static]

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

Definition at line 316 of file chan_zap.c.

int hanguponpolarityswitch = 0 [static]

Whether we hang up on a Polarity Switch event.

Definition at line 338 of file chan_zap.c.

int hidecallerid = 0 [static]

Definition at line 231 of file chan_zap.c.

int ifcount = 0 [static]

Definition at line 328 of file chan_zap.c.

struct zt_pvt * ifend [static]

Referenced by __build_step().

struct zt_pvt * iflist [static]

int immediate = 0 [static]

Definition at line 223 of file chan_zap.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 204 of file chan_zap.c.

char mailbox[AST_MAX_EXTENSION] [static]

Definition at line 271 of file chan_zap.c.

int matchdigittimeout = 3000 [static]

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

Definition at line 319 of file chan_zap.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

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

Definition at line 352 of file chan_zap.c.

char musicclass[MAX_MUSICCLASS] = "" [static]

Definition at line 205 of file chan_zap.c.

char* name

Definition at line 1076 of file chan_zap.c.

int num_cadence = 4 [static]

Definition at line 753 of file chan_zap.c.

int numbufs = 4 [static]

Definition at line 277 of file chan_zap.c.

int polarityonanswerdelay = 600 [static]

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

Definition at line 341 of file chan_zap.c.

int priindication_oob = 0 [static]

Definition at line 289 of file chan_zap.c.

char progzone[10] = "" [static]

Definition at line 206 of file chan_zap.c.

int pulse [static]

Definition at line 257 of file chan_zap.c.

int relaxdtmf = 0 [static]

Definition at line 221 of file chan_zap.c.

int restrictcid = 0 [static]

Definition at line 233 of file chan_zap.c.

int ringt_base = DEFAULT_RINGT [static]

Definition at line 397 of file chan_zap.c.

struct zt_pvt* round_robin[32]

Definition at line 730 of file chan_zap.c.

Referenced by load_module(), and zt_request().

float rxgain = 0.0 [static]

Definition at line 247 of file chan_zap.c.

Referenced by load_module(), and misdn_set_opt_exec().

int sendcalleridafter = DEFAULT_CIDRINGS [static]

When to send the CallerID signals (rings).

Definition at line 344 of file chan_zap.c.

char show_channel_usage[] [static]

Initial value:

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

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

int stripmsd = 0 [static]

Definition at line 225 of file chan_zap.c.

char* subnames[] [static]

Initial value:

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

Definition at line 495 of file chan_zap.c.

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

Definition at line 150 of file chan_zap.c.

int threewaycalling = 0 [static]

Definition at line 239 of file chan_zap.c.

int tonezone = -1 [static]

Definition at line 251 of file chan_zap.c.

int transfer = 0 [static]

Definition at line 241 of file chan_zap.c.

int transfertobusy = 1 [static]

Definition at line 210 of file chan_zap.c.

float txgain = 0.0 [static]

Definition at line 249 of file chan_zap.c.

Referenced by load_module(), and misdn_set_opt_exec().

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

Definition at line 159 of file chan_zap.c.

int use_callerid = 1 [static]

Definition at line 212 of file chan_zap.c.

int use_callingpres = 0 [static]

Definition at line 235 of file chan_zap.c.

int usecnt = 0 [static]

Definition at line 321 of file chan_zap.c.

int usedistinctiveringdetection = 0 [static]

Definition at line 208 of file chan_zap.c.

int user_has_defined_cadences = 0 [static]

Definition at line 754 of file chan_zap.c.

struct ast_cli_entry zap_cli[] [static]

Definition at line 9838 of file chan_zap.c.

Referenced by __unload_module(), and load_module().

char zap_show_cadences_help[] [static]

Initial value:

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

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

struct ast_channel_tech zap_tech [static]

Definition at line 705 of file chan_zap.c.

Referenced by __unload_module(), load_module(), and zt_new().

int zaptrcallerid = 0 [static]

Definition at line 215 of file chan_zap.c.


Generated on Sat Sep 16 05:47:59 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7