Fri Sep 29 11:13:25 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 <tonezone.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"

Include dependency graph for chan_zap.c:

Go to the source code of this file.

Data Structures

struct  distRingData
struct  ringContextData
struct  zt_distRings
struct  zt_pvt
struct  zt_subchannel

Defines

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

Functions

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

Variables

static char accountcode [AST_MAX_ACCOUNT_CODE] = ""
static int adsi = 0
struct {
   int   alarm
   char *   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_restart_usage []
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 10021 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 1198 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 10020 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 10197 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().

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

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

Definition at line 4266 of file chan_zap.c.

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

Referenced by zt_exception(), and zt_read().

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

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

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

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

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

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

10106 {
10107    struct zt_pvt *p = NULL;
10108    char *channel = astman_get_header(m, "ZapChannel");
10109    if (ast_strlen_zero(channel)) {
10110       astman_send_error(s, m, "No channel specified");
10111       return 0;
10112    }
10113    p = find_channel(atoi(channel));
10114    if (!p) {
10115       astman_send_error(s, m, "No such channel");
10116       return 0;
10117    }
10118    zap_fake_event(p,HANGUP);
10119    astman_send_ack(s, m, "ZapHangup");
10120    return 0;
10121 }

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

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

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

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

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

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

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

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

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

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

Definition at line 9682 of file chan_zap.c.

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

09683 {
09684    if (zap_restart() != 0) {
09685       astman_send_error(s, m, "Failed rereading zaptel configuration");
09686       return 1;
09687    }
09688    astman_send_ack(s, m, "ZapRestart: Success");
09689    return 0;
09690 }

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

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

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

static char* alarm2str ( int  alarm  )  [static]

Definition at line 1095 of file chan_zap.c.

References alarms, and name.

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

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

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

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

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

AST_MUTEX_DEFINE_STATIC ( monlock   ) 

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

AST_MUTEX_DEFINE_STATIC ( iflock   ) 

Protect the interface list (of zt_pvt's).

AST_MUTEX_DEFINE_STATIC ( usecnt_lock   ) 

static int attempt_transfer ( struct zt_pvt p  )  [static]

Definition at line 3340 of file chan_zap.c.

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

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

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

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

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

static int bump_gains ( struct zt_pvt p  )  [static]

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

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

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

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

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

static int check_for_conference ( struct zt_pvt p  )  [static]

Definition at line 3482 of file chan_zap.c.

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

Referenced by zt_handle_event().

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

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

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

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

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

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

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

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 11249 of file chan_zap.c.

11250 {
11251    return (char *) desc;
11252 }

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

Definition at line 2170 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(), zap_restart(), and zt_hangup().

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

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

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

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

static void disable_dtmf_detect ( struct zt_pvt p  )  [static]

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

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

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

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

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

static void enable_dtmf_detect ( struct zt_pvt p  )  [static]

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

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

static char* event2str ( int  event  )  [static]

Definition at line 1105 of file chan_zap.c.

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

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

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

Definition at line 1482 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_rxgain().

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

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

Definition at line 1448 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_txgain().

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

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

Definition at line 10039 of file chan_zap.c.

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

10040 {
10041    struct zt_pvt *p = iflist;
10042    while(p) {
10043       if (p->channel == channel) {
10044          break;
10045       }
10046       p = p->next;
10047    }
10048    return p;
10049 }

static int get_alarms ( struct zt_pvt p  )  [static]

Definition at line 3504 of file chan_zap.c.

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

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

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

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

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

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

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

Definition at line 9897 of file chan_zap.c.

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

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

static int has_voicemail ( struct zt_pvt p  )  [static]

Definition at line 1677 of file chan_zap.c.

References ast_app_has_voicemail(), and zt_pvt::mailbox.

01678 {
01679 
01680    return ast_app_has_voicemail(p->mailbox, NULL);
01681 }

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

Definition at line 1238 of file chan_zap.c.

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

Referenced by conf_del().

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

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

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

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

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

References ASTERISK_GPL_KEY.

11255 {
11256    return ASTERISK_GPL_KEY;
11257 }

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

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

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

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

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

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

Definition at line 5177 of file chan_zap.c.

References ast_waitfordigit().

Referenced by ss_thread().

05178 {
05179    char c;
05180 
05181    *str = 0; /* start with empty output buffer */
05182    for (;;)
05183    {
05184       /* Wait for the first digit (up to specified ms). */
05185       c = ast_waitfordigit(chan, ms);
05186       /* if timeout, hangup or error, return as such */
05187       if (c < 1)
05188          return c;
05189       *str++ = c;
05190       *str = 0;
05191       if (strchr(term, c))
05192          return 1;
05193    }
05194 }

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

Definition at line 4706 of file chan_zap.c.

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

Referenced by zt_write().

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

int reload ( void   ) 

Reload stuff.

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

Returns:
The return value is not used.

Definition at line 11232 of file chan_zap.c.

References ast_log(), and setup_zap().

11233 {
11234    int res = 0;
11235 
11236    res = setup_zap(1);
11237    if (res) {
11238       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11239       return -1;
11240    }
11241    return 0;
11242 }

static int reset_conf ( struct zt_pvt p  )  [static]

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

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

static int restart_monitor ( void   )  [static]

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

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

static int restore_conference ( struct zt_pvt p  )  [static]

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

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

static int restore_gains ( struct zt_pvt p  )  [static]

Definition at line 1571 of file chan_zap.c.

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

Referenced by zt_hangup().

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

static int save_conference ( struct zt_pvt p  )  [static]

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

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

static int send_callerid ( struct zt_pvt p  )  [static]

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

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

int send_cwcidspill ( struct zt_pvt p  ) 

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

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

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

Definition at line 1552 of file chan_zap.c.

References set_actual_rxgain(), and set_actual_txgain().

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

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

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

Definition at line 1534 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

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

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

Definition at line 1516 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

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

static int setup_zap ( int  reload  )  [static]

Definition at line 10291 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, CID_START_USEHIST, 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(), reload(), and zap_restart().

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

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

Definition at line 5214 of file chan_zap.c.

References alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_moh_stop(), ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_read(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_free(), callerid_get(), callerid_new(), zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, zt_pvt::cid_start, CID_START_USEHIST, zt_pvt::context, ast_channel::context, 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, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, manager_event(), my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, callerid_state::number, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::transfer, ast_channel::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_history(), zt_get_index(), zt_set_hook(), zt_wait_event(), and zt_wink().

Referenced by handle_init_event(), and zt_handle_event().

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

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

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

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

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

10282 {
10283 #ifdef ZAPATA_PRI    
10284    int y;
10285    for (y=0;y<NUM_SPANS;y++)
10286       ast_mutex_destroy(&pris[y].lock);
10287 #endif
10288    return __unload_module();
10289 }

static int update_conf ( struct zt_pvt p  )  [static]

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

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

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

11245 {
11246    return usecnt;
11247 }

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

09629 {
09630    int channel = 0;
09631    struct zt_pvt *tmp = NULL;
09632    struct zt_pvt *prev = NULL;
09633    
09634    if (argc != 4) {
09635       return RESULT_SHOWUSAGE;
09636    }
09637    channel = atoi(argv[3]);
09638 
09639    tmp = iflist;
09640    while (tmp) {
09641       if (tmp->channel == channel) {
09642          destroy_channel(prev, tmp, 1);
09643          return RESULT_SUCCESS;
09644       }
09645       prev = tmp;
09646       tmp = tmp->next;
09647    }
09648    return RESULT_FAILURE;
09649 }

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

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

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

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_restart ( void   )  [static]

Definition at line 9652 of file chan_zap.c.

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

Referenced by action_zaprestart(), and zap_restart_cmd().

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

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

Definition at line 9671 of file chan_zap.c.

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

09672 {
09673    if (argc != 2) {
09674       return RESULT_SHOWUSAGE;
09675    }
09676 
09677    if (zap_restart() != 0)
09678       return RESULT_FAILURE;
09679    return RESULT_SUCCESS;
09680 }

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

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

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

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

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

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

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

Definition at line 9924 of file chan_zap.c.

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

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

static char* zap_sig2str ( int  sig  )  [static]

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

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

static int zt_answer ( struct ast_channel ast  )  [static]

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

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

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

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

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

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

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

static int zt_callwait ( struct ast_channel ast  )  [static]

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

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

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

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

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

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

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

static void zt_disable_ec ( struct zt_pvt p  )  [static]

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

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

static void zt_enable_ec ( struct zt_pvt p  )  [static]

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

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

struct ast_frame * zt_exception ( struct ast_channel ast  ) 

Definition at line 4370 of file chan_zap.c.

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

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

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

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

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

static int zt_get_event ( int  fd  )  [inline, static]

Avoid the silly zt_getevent which ignores a bunch of events.

Definition at line 361 of file chan_zap.c.

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

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

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

Definition at line 955 of file chan_zap.c.

Referenced by ss_thread().

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

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

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

Referenced by __zt_exception().

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

static int zt_hangup ( struct ast_channel ast  )  [static]

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

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

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

Definition at line 4817 of file chan_zap.c.

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

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

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

Definition at line 2939 of file chan_zap.c.

References ast_log(), LOG_WARNING, and master.

Referenced by zt_bridge().

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

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

Definition at line 4983 of file chan_zap.c.

References ast_channel::accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_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().

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

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

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

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

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

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

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

static int zt_ring_phone ( struct zt_pvt p  )  [static]

Definition at line 3306 of file chan_zap.c.

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

Referenced by __zt_exception(), and zt_handle_event().

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

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

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

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

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

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

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

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

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

static void zt_train_ec ( struct zt_pvt p  )  [static]

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

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

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

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

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

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

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

Referenced by ss_thread().

05197 {
05198    int j;
05199    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05200    for(;;)
05201    {
05202          /* set bits of interest */
05203       j = ZT_IOMUX_SIGEVENT;
05204           /* wait for some happening */
05205       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05206          /* exit loop if we have it */
05207       if (j & ZT_IOMUX_SIGEVENT) break;
05208    }
05209      /* get the event info */
05210    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05211    return 0;
05212 }

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

Definition at line 4729 of file chan_zap.c.

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

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


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] = "" [static]

Definition at line 269 of file chan_zap.c.

int adsi = 0 [static]

Definition at line 275 of file chan_zap.c.

int alarm

Definition at line 1083 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 9997 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 1060 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 1084 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 9989 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 9985 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 10005 of file chan_zap.c.

Referenced by __unload_module(), and load_module().

char zap_restart_usage[] [static]

Initial value:

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

Definition at line 10001 of file chan_zap.c.

char zap_show_cadences_help[] [static]

Initial value:

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

Definition at line 9893 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 9993 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 Fri Sep 29 11:13:27 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7