Mon Mar 20 08:25:55 2006

Asterisk developer's documentation


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

chan_zap.c File Reference

Zaptel Pseudo TDM interface. More...

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

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

int __unload_module (void)
ast_frame__zt_exception (struct ast_channel *ast)
int action_transfer (struct mansession *s, struct message *m)
int action_transferhangup (struct mansession *s, struct message *m)
int action_zapdialoffhook (struct mansession *s, struct message *m)
int action_zapdndoff (struct mansession *s, struct message *m)
int action_zapdndon (struct mansession *s, struct message *m)
int action_zapshowchannels (struct mansession *s, struct message *m)
char * alarm2str (int alarm)
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)
int attempt_transfer (struct zt_pvt *p)
int available (struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
int bump_gains (struct zt_pvt *p)
zt_pvtchandup (struct zt_pvt *src)
int check_for_conference (struct zt_pvt *p)
int conf_add (struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
int conf_del (struct zt_pvt *p, struct zt_subchannel *c, int index)
char * description ()
 Provides a description of the module.
int destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now)
void destroy_zt_pvt (struct zt_pvt **pvt)
void disable_dtmf_detect (struct zt_pvt *p)
void * do_monitor (void *data)
void enable_dtmf_detect (struct zt_pvt *p)
char * event2str (int event)
void fill_rxgain (struct zt_gains *g, float gain, int law)
void fill_txgain (struct zt_gains *g, float gain, int law)
zt_pvtfind_channel (int channel)
int get_alarms (struct zt_pvt *p)
int handle_init_event (struct zt_pvt *i, int event)
int handle_zap_show_cadences (int fd, int argc, char *argv[])
int has_voicemail (struct zt_pvt *p)
int isourconf (struct zt_pvt *p, struct zt_subchannel *c)
int isslavenative (struct zt_pvt *p, struct zt_pvt **out)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
zt_pvtmkintf (int channel, int signalling, int radio, struct zt_pri *pri, int reloading)
int my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
int my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
int reload (void)
 Reload stuff.
int reset_conf (struct zt_pvt *p)
int restart_monitor (void)
int restore_conference (struct zt_pvt *p)
int restore_gains (struct zt_pvt *p)
int save_conference (struct zt_pvt *p)
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)
int setup_zap (int reload)
void * ss_thread (void *data)
void swap_subs (struct zt_pvt *p, int a, int b)
int unalloc_sub (struct zt_pvt *p, int x)
int unload_module ()
 Cleanup all module structures, sockets, etc.
int update_conf (struct zt_pvt *p)
int usecount ()
 Provides a usecount.
void wakeup_sub (struct zt_pvt *p, int a, void *pri)
int zap_destroy_channel (int fd, int argc, char **argv)
int zap_fake_event (struct zt_pvt *p, int mode)
void zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *pri)
int zap_show_channel (int fd, int argc, char **argv)
int zap_show_channels (int fd, int argc, char **argv)
int zap_show_status (int fd, int argc, char *argv[])
char * zap_sig2str (int sig)
int zt_answer (struct ast_channel *ast)
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)
int zt_call (struct ast_channel *ast, char *rdest, int timeout)
int zt_callwait (struct ast_channel *ast)
void zt_close (int fd)
int zt_confmute (struct zt_pvt *p, int muted)
int zt_digit (struct ast_channel *ast, char digit)
void zt_disable_ec (struct zt_pvt *p)
void zt_enable_ec (struct zt_pvt *p)
ast_framezt_exception (struct ast_channel *ast)
int zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
int zt_get_event (int fd)
 Avoid the silly zt_getevent which ignores a bunch of events.
int zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok)
ast_framezt_handle_event (struct ast_channel *ast)
int zt_hangup (struct ast_channel *ast)
int zt_indicate (struct ast_channel *chan, int condition)
void zt_link (struct zt_pvt *slave, struct zt_pvt *master)
ast_channelzt_new (struct zt_pvt *, int, int, int, int, int)
int zt_open (char *fn)
ast_framezt_read (struct ast_channel *ast)
ast_channelzt_request (const char *type, int format, void *data, int *cause)
int zt_ring_phone (struct zt_pvt *p)
int zt_sendtext (struct ast_channel *c, const char *text)
int zt_set_hook (int fd, int hs)
int zt_setlaw (int zfd, int law)
int zt_setlinear (int zfd, int linear)
int zt_setoption (struct ast_channel *chan, int option, void *data, int datalen)
void zt_train_ec (struct zt_pvt *p)
void zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock)
int zt_wait_event (int fd)
 Avoid the silly zt_waitevent which ignores a bunch of events.
int zt_wink (struct zt_pvt *p, int index)
int zt_write (struct ast_channel *ast, struct ast_frame *frame)

Variables

char accountcode [AST_MAX_ACCOUNT_CODE] = ""
int adsi = 0
struct {
   int   alarm
   char *   name
alarms []
int amaflags = 0
int answeronpolarityswitch = 0
 Whether we answer on a Polarity Switch event.
int busy_quietlength = 0
int busy_tonelength = 0
int busycount = 3
int busydetect = 0
zt_ring_cadence cadences [NUM_CADENCE_MAX]
int callprogress = 0
int callreturn = 0
int callwaiting = 0
int callwaitingcallerid = 0
int cancallforward = 0
int canpark = 0
char cid_name [256] = ""
char cid_num [256] = ""
int cid_signalling = CID_SIG_BELL
int cid_start = CID_START_RING
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.
const char config [] = "zapata.conf"
char context [AST_MAX_CONTEXT] = "default"
ast_group_t cur_callergroup = 0
int cur_debounce = -1
int cur_flash = -1
ast_group_t cur_group = 0
ast_group_t cur_pickupgroup = 0
int cur_preflash = -1
int cur_prewink = -1
int cur_priexclusive = 0
int cur_rxflash = -1
int cur_rxwink = -1
int cur_signalling = -1
int cur_start = -1
int cur_wink = -1
char defaultcic [64] = ""
char defaultozz [64] = ""
const char desc [] = "Zapata Telephony"
char destroy_channel_usage []
zt_distRings drings
int echocanbridged = 0
int echocancel
int echotraining
char * events []
int firstdigittimeout = 16000
 Wait up to 16 seconds for first digit (FXO logic).
int gendigittimeout = 8000
 How long to wait for following digits (FXO logic).
int hanguponpolarityswitch = 0
 Whether we hang up on a Polarity Switch event.
int hidecallerid = 0
int ifcount = 0
zt_pvtiflist
int immediate = 0
char language [MAX_LANGUAGE] = ""
char mailbox [AST_MAX_EXTENSION]
int matchdigittimeout = 3000
 How long to wait for an extra digit, if there is an ambiguous match.
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.
char musicclass [MAX_MUSICCLASS] = ""
int num_cadence = 4
int numbufs = 4
int polarityonanswerdelay = 600
 How long (ms) to ignore Polarity Switch events after we answer a call.
int priindication_oob = 0
char progzone [10] = ""
int pulse
int receivedRingT
int relaxdtmf = 0
int restrictcid = 0
int ringt_base = DEFAULT_RINGT
zt_pvtround_robin [32]
float rxgain = 0.0
int sendcalleridafter = DEFAULT_CIDRINGS
 When to send the CallerID signals (rings).
char show_channel_usage []
char show_channels_usage []
int stripmsd = 0
char * subnames []
const char tdesc [] = "Zapata Telephony Driver"
int threewaycalling = 0
int tonezone = -1
int transfer = 0
int transfertobusy = 1
float txgain = 0.0
const char type [] = "Zap"
int use_callerid = 1
int use_callingpres = 0
int usecnt = 0
int usedistinctiveringdetection = 0
int user_has_defined_cadences = 0
ast_cli_entry zap_cli []
char zap_show_cadences_help []
char zap_show_status_usage []
const struct ast_channel_tech zap_tech
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.

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

300 ms

Definition at line 384 of file chan_zap.c.

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

Definition at line 779 of file chan_zap.c.

Referenced by zt_new().

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

Definition at line 780 of file chan_zap.c.

Referenced by zt_handle_event(), and zt_new().

#define CHAN_PSEUDO   -2
 

Definition at line 190 of file chan_zap.c.

Referenced by setup_zap().

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

#define CONF_USER_REAL   (1 << 0)
 

Definition at line 518 of file chan_zap.c.

#define CONF_USER_THIRDCALL   (1 << 1)
 

Definition at line 519 of file chan_zap.c.

#define DCHAN_AVAILABLE   (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
 

Definition at line 196 of file chan_zap.c.

#define DCHAN_NOTINALARM   (1 << 1)
 

Definition at line 193 of file chan_zap.c.

#define DCHAN_PROVISIONED   (1 << 0)
 

Definition at line 192 of file chan_zap.c.

#define DCHAN_UP   (1 << 2)
 

Definition at line 194 of file chan_zap.c.

#define DEFAULT_CIDRINGS   1
 

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

Definition at line 132 of file chan_zap.c.

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

Definition at line 388 of file chan_zap.c.

#define END_SILENCE_LEN   400
 

Referenced by zt_sendtext().

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

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

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

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

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

Definition at line 727 of file chan_zap.c.

Referenced by update_conf().

#define HANGUP   1
 

Definition at line 9856 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
 

#define ISTRUNK  ) 
 

Value:

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

Definition at line 776 of file chan_zap.c.

Referenced by ss_thread(), and zt_indicate().

#define MASK_AVAIL   (1 << 0)
 

Channel available for PRI use

Definition at line 381 of file chan_zap.c.

#define MASK_INUSE   (1 << 1)
 

Channel currently in use

Definition at line 382 of file chan_zap.c.

#define MAX_CHANNELS   672
 

No more than a DS3 per trunk group

Definition at line 188 of file chan_zap.c.

#define MAX_SLAVES   4
 

Definition at line 521 of file chan_zap.c.

Referenced by zt_link().

#define MIN_MS_SINCE_FLASH   ( (2000) )
 

2000 ms

Definition at line 387 of file chan_zap.c.

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

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

Definition at line 139 of file chan_zap.c.

Referenced by ss_thread(), and zt_new().

#define NUM_CADENCE_MAX   25
 

Definition at line 752 of file chan_zap.c.

Referenced by setup_zap().

#define NUM_DCHANS   4
 

No more than 4 d-channels

Definition at line 187 of file chan_zap.c.

#define NUM_SPANS   32
 

Definition at line 186 of file chan_zap.c.

#define POLARITY_IDLE   0
 

Definition at line 478 of file chan_zap.c.

#define POLARITY_REV   1
 

Definition at line 479 of file chan_zap.c.

#define READ_SIZE   160
 

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

Definition at line 379 of file chan_zap.c.

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

#define sig2str   zap_sig2str
 

Definition at line 1192 of file chan_zap.c.

Referenced by action_zapshowchannels(), handle_init_event(), mkintf(), setup_zap(), ss_thread(), zap_show_channel(), and zt_handle_event().

#define SIG_E911   (0x1000000 | ZT_SIG_EM)
 

Definition at line 167 of file chan_zap.c.

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

#define SIG_EM   ZT_SIG_EM
 

Definition at line 162 of file chan_zap.c.

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

#define SIG_EM_E1   ZT_SIG_EM_E1
 

Definition at line 182 of file chan_zap.c.

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

#define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
 

Definition at line 163 of file chan_zap.c.

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

#define SIG_FEATB   (0x0800000 | ZT_SIG_EM)
 

Definition at line 166 of file chan_zap.c.

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

#define SIG_FEATD   (0x0200000 | ZT_SIG_EM)
 

Definition at line 164 of file chan_zap.c.

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

#define SIG_FEATDMF   (0x0400000 | ZT_SIG_EM)
 

Definition at line 165 of file chan_zap.c.

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

#define SIG_FEATDMF_TA   (0x2000000 | ZT_SIG_EM)
 

Definition at line 168 of file chan_zap.c.

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

#define SIG_FXOGS   ZT_SIG_FXOGS
 

Definition at line 173 of file chan_zap.c.

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

#define SIG_FXOKS   ZT_SIG_FXOKS
 

Definition at line 174 of file chan_zap.c.

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

#define SIG_FXOLS   ZT_SIG_FXOLS
 

Definition at line 172 of file chan_zap.c.

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

#define SIG_FXSGS   ZT_SIG_FXSGS
 

Definition at line 170 of file chan_zap.c.

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

#define SIG_FXSKS   ZT_SIG_FXSKS
 

Definition at line 171 of file chan_zap.c.

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

#define SIG_FXSLS   ZT_SIG_FXSLS
 

Definition at line 169 of file chan_zap.c.

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

#define SIG_GR303FXOKS   (0x0100000 | ZT_SIG_FXOKS)
 

Definition at line 183 of file chan_zap.c.

Referenced by handle_init_event(), and zap_sig2str().

#define SIG_GR303FXSKS   (0x0100000 | ZT_SIG_FXSKS)
 

Definition at line 184 of file chan_zap.c.

Referenced by handle_init_event(), and zap_sig2str().

#define SIG_PRI   ZT_SIG_CLEAR
 

Definition at line 175 of file chan_zap.c.

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

#define SIG_R2   ZT_SIG_CAS
 

Definition at line 176 of file chan_zap.c.

Referenced by zap_sig2str(), and zt_answer().

#define SIG_SF   ZT_SIG_SF
 

Definition at line 177 of file chan_zap.c.

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

#define SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
 

Definition at line 181 of file chan_zap.c.

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

#define SIG_SF_FEATD   (0x0200000 | ZT_SIG_SF)
 

Definition at line 179 of file chan_zap.c.

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

#define SIG_SF_FEATDMF   (0x0400000 | ZT_SIG_SF)
 

Definition at line 180 of file chan_zap.c.

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

#define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
 

Definition at line 178 of file chan_zap.c.

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

#define SUB_CALLWAIT   1
 

Call-Waiting call on hold

Definition at line 474 of file chan_zap.c.

#define SUB_REAL   0
 

Active call

Definition at line 473 of file chan_zap.c.

#define SUB_THREEWAY   2
 

Three-way call

Definition at line 475 of file chan_zap.c.

#define TRAILER_MS   5
 

#define TRANSFER   0
 

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

#define ZT_EVENT_DTMFUP   0
 

Definition at line 107 of file chan_zap.c.


Function Documentation

int __unload_module void   )  [static]
 

Definition at line 10032 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_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_verbose(), zt_pvt::cidspill, destroy_zt_pvt(), free, ifcount, iflist, LOG_WARNING, monitor_thread, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, zap_cli, zap_tech, zt_subchannel::zfd, and zt_close().

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

struct ast_frame* __zt_exception struct ast_channel ast  )  [static]
 

Definition at line 4258 of file chan_zap.c.

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

Referenced by zt_exception(), and zt_read().

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

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

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

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

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

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

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

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

Definition at line 9958 of file chan_zap.c.

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

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

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

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

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

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

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

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

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

Definition at line 9989 of file chan_zap.c.

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

Referenced by load_module().

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

char* alarm2str int  alarm  )  [static]
 

Definition at line 1089 of file chan_zap.c.

References alarm, and alarms.

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

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

int alloc_sub struct zt_pvt p,
int  x
[static]
 

Definition at line 957 of file chan_zap.c.

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

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

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

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   ) 
 

int attempt_transfer struct zt_pvt p  )  [static]
 

Definition at line 3332 of file chan_zap.c.

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

Referenced by handle_message(), handle_request(), handle_request_refer(), and zt_handle_event().

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

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

Definition at line 7271 of file chan_zap.c.

References ast_channel::_state, ast_log(), zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.

Referenced by zt_request().

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

int bump_gains struct zt_pvt p  )  [static]
 

Definition at line 1551 of file chan_zap.c.

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

Referenced by ss_thread().

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

struct zt_pvt* chandup struct zt_pvt src  )  [static]
 

Definition at line 7384 of file chan_zap.c.

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

Referenced by zt_request().

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

int check_for_conference struct zt_pvt p  )  [static]
 

Definition at line 3474 of file chan_zap.c.

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

Referenced by zt_handle_event().

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

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

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

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

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

Definition at line 1243 of file chan_zap.c.

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

Referenced by update_conf(), and zt_unlink().

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

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 11080 of file chan_zap.c.

11081 {
11082    return (char *) desc;
11083 }

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

Definition at line 2165 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, zt_subchannel::zfd, and zt_close().

Referenced by zap_destroy_channel(), and zt_hangup().

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

void destroy_zt_pvt struct zt_pvt **  pvt  )  [static]
 

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

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

void disable_dtmf_detect struct zt_pvt p  )  [static]
 

Definition at line 2957 of file chan_zap.c.

References ast_dsp_set_features(), zt_pvt::dsp, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, val, and zt_subchannel::zfd.

Referenced by zt_bridge().

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

void* do_monitor void *  data  )  [static]
 

Definition at line 6421 of file chan_zap.c.

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

Referenced by restart_monitor().

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

void enable_dtmf_detect struct zt_pvt p  )  [static]
 

Definition at line 2975 of file chan_zap.c.

References ast_dsp_set_features(), zt_pvt::channel, zt_pvt::dsp, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, val, and zt_subchannel::zfd.

Referenced by zt_bridge().

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

char* event2str int  event  )  [static]
 

Definition at line 1099 of file chan_zap.c.

References events.

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

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

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

Definition at line 1476 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and zt_pvt::rxgain.

Referenced by set_actual_rxgain().

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

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

Definition at line 1442 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and zt_pvt::txgain.

Referenced by set_actual_txgain().

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

struct zt_pvt* find_channel int  channel  )  [static]
 

Definition at line 9874 of file chan_zap.c.

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

Referenced by action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), hangup_chan(), and offhook_chan().

09875 {
09876    struct zt_pvt *p = iflist;
09877    while(p) {
09878       if (p->channel == channel) {
09879          break;
09880       }
09881       p = p->next;
09882    }
09883    return p;
09884 }

int get_alarms struct zt_pvt p  )  [static]
 

Definition at line 3496 of file chan_zap.c.

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

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

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

int handle_init_event struct zt_pvt i,
int  event
[static]
 

Definition at line 6227 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, zt_pvt::cidspill, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, LOG_WARNING, zt_pvt::polarity, 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_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().

Referenced by do_monitor().

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

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

Definition at line 9738 of file chan_zap.c.

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

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

int has_voicemail struct zt_pvt p  )  [static]
 

Definition at line 1671 of file chan_zap.c.

References ast_app_has_voicemail(), and zt_pvt::mailbox.

01672 {
01673 
01674    return ast_app_has_voicemail(p->mailbox, NULL);
01675 }

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

Definition at line 1232 of file chan_zap.c.

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

Referenced by conf_del().

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

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

Definition at line 1265 of file chan_zap.c.

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

Referenced by update_conf().

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

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

11086 {
11087    return ASTERISK_GPL_KEY;
11088 }

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 10916 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(), lock, LOG_ERROR, zt_pvt::master, round_robin, setup_zap(), type, zap_cli, and zap_tech.

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

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

Definition at line 6810 of file chan_zap.c.

References accountcode, zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_dsp_digitmode(), ast_log(), ast_mutex_init(), ast_strlen_zero(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, cid_name, zt_pvt::cid_name, cid_num, zt_pvt::cid_num, zt_pvt::cid_signalling, zt_pvt::cid_start, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, context, cur_debounce, cur_flash, cur_preflash, cur_prewink, cur_rxflash, cur_rxwink, cur_start, cur_wink, zt_pvt::defcontext, zt_pvt::destroy, destroy_zt_pvt(), zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, zt_pvt::firstradio, zt_pvt::flashtime, zt_pvt::group, zt_pvt::hanguponpolarityswitch, zt_pvt::hidecallerid, ifcount, zt_pvt::immediate, zt_pvt::inalarm, language, zt_pvt::language, zt_pvt::law, zt_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, zt_pvt::mailbox, malloc, zt_pvt::msgstate, musicclass, zt_pvt::musicclass, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::overlapdial, zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::prev, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::propconfno, zt_pvt::pulse, zt_pvt::radio, zt_pvt::restrictcid, zt_pvt::ringt_base, zt_pvt::rxgain, zt_pvt::sendcalleridafter, set_actual_gain(), si, zt_pvt::sig, sig2str, zt_pvt::span, zt_pvt::stripmsd, SUB_REAL, zt_pvt::subs, zt_pvt::threewaycalling, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, update_conf(), zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::usedistinctiveringdetection, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_close(), zt_open(), and zt_set_hook().

Referenced by setup_zap().

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

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

Definition at line 5157 of file chan_zap.c.

References ast_waitfordigit().

Referenced by ss_thread().

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

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

Definition at line 4698 of file chan_zap.c.

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

Referenced by zt_write().

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

int reload void   ) 
 

Reload stuff.

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

Returns:
The return value is not used.

Definition at line 11063 of file chan_zap.c.

References ast_log(), LOG_WARNING, and setup_zap().

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

int reset_conf struct zt_pvt p  )  [static]
 

Definition at line 1309 of file chan_zap.c.

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

Referenced by zt_hangup().

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

int restart_monitor void   )  [static]
 

Definition at line 6655 of file chan_zap.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread.

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

int restore_conference struct zt_pvt p  )  [static]
 

Definition at line 1635 of file chan_zap.c.

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

Referenced by send_callerid(), and zt_read().

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

int restore_gains struct zt_pvt p  )  [static]
 

Definition at line 1565 of file chan_zap.c.

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

Referenced by ss_thread(), and zt_hangup().

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

int save_conference struct zt_pvt p  )  [static]
 

Definition at line 1607 of file chan_zap.c.

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

Referenced by zt_callwait().

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

int send_callerid struct zt_pvt p  )  [static]
 

Definition at line 1677 of file chan_zap.c.

References ast_log(), zt_pvt::callwaitcas, 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, zt_subchannel::zfd, and zt_setlinear().

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

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

int send_cwcidspill struct zt_pvt p  ) 
 

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

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

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

Definition at line 1546 of file chan_zap.c.

References rxgain, set_actual_rxgain(), set_actual_txgain(), and txgain.

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

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

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

Definition at line 1528 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

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

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

Definition at line 1510 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

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

int setup_zap int  reload  )  [static]
 

Definition at line 10126 of file chan_zap.c.

References accountcode, adsi, amaflags, answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_get_group(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose(), busy_quietlength, busy_tonelength, busycount, busydetect, cadences, callprogress, callreturn, callwaiting, callwaitingcallerid, cancallforward, canpark, cfg, CHAN_PSEUDO, cid_name, cid_num, cid_signalling, cid_start, cidrings, config, context, ringContextData::contextData, cur_callergroup, cur_debounce, cur_flash, cur_group, cur_pickupgroup, cur_preflash, cur_prewink, cur_priexclusive, cur_rxflash, cur_rxwink, cur_signalling, cur_start, cur_wink, defaultcic, defaultozz, drings, echocanbridged, echocancel, echotraining, hanguponpolarityswitch, hidecallerid, immediate, language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mkintf(), musicclass, ast_variable::name, ast_variable::next, num_cadence, NUM_CADENCE_MAX, numbufs, option_verbose, polarityonanswerdelay, priindication_oob, progzone, pulse, relaxdtmf, reload(), restart_monitor(), restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ringt_base, rxgain, sendcalleridafter, zt_pvt::sig, sig2str, stripmsd, strsep(), threewaycalling, tonezone, transfer, transfertobusy, txgain, use_callerid, use_callingpres, usedistinctiveringdetection, user_has_defined_cadences, ast_variable::value, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and zaptrcallerid.

Referenced by load_module(), and reload().

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

void * ss_thread void *  data  )  [static]
 

Definition at line 5194 of file chan_zap.c.

References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_moh_stop(), ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_read(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_shrink_phone_number(), AST_STATE_PRERING, AST_STATE_RING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, cid_signalling, zt_pvt::cid_signalling, zt_pvt::cid_start, 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, ast_frame::frametype, free, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, ast_channel::language, zt_pvt::lastcid_num, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, option_verbose, zt_pvt::owner, zt_subchannel::owner, receivedRingT, restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::transfer, type, ast_channel::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().

Referenced by handle_init_event(), and zt_handle_event().

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

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

Definition at line 863 of file chan_zap.c.

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

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

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

int unalloc_sub struct zt_pvt p,
int  x
[static]
 

Definition at line 992 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, zt_pvt::subs, zt_subchannel::zfd, and zt_close().

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

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

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

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

10117 {
10118 #ifdef ZAPATA_PRI    
10119    int y;
10120    for (y=0;y<NUM_SPANS;y++)
10121       ast_mutex_destroy(&pris[y].lock);
10122 #endif
10123    return __unload_module();
10124 }

int update_conf struct zt_pvt p  )  [static]
 

Definition at line 1322 of file chan_zap.c.

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

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

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

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

11076 {
11077    return usecnt;
11078 }

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

Definition at line 802 of file chan_zap.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and ast_queue_frame().

Referenced by swap_subs().

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

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

Definition at line 9510 of file chan_zap.c.

References zt_pvt::channel, destroy_channel(), and zt_pvt::next.

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

int zap_fake_event struct zt_pvt p,
int  mode
[static]
 

Definition at line 9858 of file chan_zap.c.

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

Referenced by action_transfer(), and action_transferhangup().

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

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

Definition at line 833 of file chan_zap.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and ast_queue_frame().

Referenced by action_zapdialoffhook().

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

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

Definition at line 9594 of file chan_zap.c.

References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_t, 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, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, zt_pvt::lock, lock, LOG_WARNING, zt_pvt::master, ast_channel::name, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.

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

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

Definition at line 9533 of file chan_zap.c.

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

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

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

Definition at line 9765 of file chan_zap.c.

References alarms, ast_cli(), FORMAT, FORMAT2, and s.

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

char* zap_sig2str int  sig  )  [static]
 

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

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

int zt_answer struct ast_channel ast  )  [static]
 

Definition at line 2639 of file chan_zap.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_subchannel::inthreeway, 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().

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

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

References ast_channel::_state, AST_BRIDGE_DTMF_CHANNEL_0, ast_bridge_result, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), ast_channel::fds, ast_frame::frametype, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, subnames, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().

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

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

Definition at line 1741 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_DIALING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), cadences, zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::callwaitrings, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cidlen, zt_pvt::cidpos, cidrings, zt_pvt::cidrings, zt_pvt::cidspill, 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, 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().

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

int zt_callwait struct ast_channel ast  )  [static]
 

Definition at line 1710 of file chan_zap.c.

References ast_gen_cas(), AST_LAW, ast_log(), zt_pvt::callwaitcas, 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().

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

void zt_close int  fd  )  [static]
 

Definition at line 932 of file chan_zap.c.

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

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

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

Definition at line 1591 of file chan_zap.c.

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

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

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

int zt_digit struct ast_channel ast,
char  digit
[static]
 

Definition at line 1012 of file chan_zap.c.

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

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

void zt_disable_ec struct zt_pvt p  )  [static]
 

Definition at line 1427 of file chan_zap.c.

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

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

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

void zt_enable_ec struct zt_pvt p  )  [static]
 

Definition at line 1378 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, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.

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

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

struct ast_frame * zt_exception struct ast_channel ast  ) 
 

Definition at line 4362 of file chan_zap.c.

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

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

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

Definition at line 3273 of file chan_zap.c.

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

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

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 }

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

Definition at line 782 of file chan_zap.c.

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

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

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

struct ast_frame* zt_handle_event struct ast_channel ast  )  [static]
 

Definition at line 3510 of file chan_zap.c.

References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), ast_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_EXPLICIT, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::dop, zt_pvt::dsp, 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, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event(), zt_pvt::msgstate, ast_channel::name, zt_subchannel::needanswer, zt_subchannel::needflash, zt_subchannel::needringing, ast_frame::offset, zt_pvt::onhooktime, 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, 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_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_get_event(), zt_get_index(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().

Referenced by __zt_exception().

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

int zt_hangup struct ast_channel ast  )  [static]
 

Definition at line 2301 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_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, 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_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, 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, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), usecnt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().

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

int zt_indicate struct ast_channel chan,
int  condition
[static]
 

Definition at line 4809 of file chan_zap.c.

References ast_channel::_softhangup, ast_channel::_state, AST_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_STATE_RINGING, zt_pvt::digital, zt_pvt::dop, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().

Referenced by zt_fixup().

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

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

Definition at line 2934 of file chan_zap.c.

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

Referenced by zt_bridge().

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

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

Definition at line 4975 of file chan_zap.c.

References ast_channel::accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, ast_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_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_set_callerid(), ast_setstate(), 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, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_dnid, zt_pvt::cid_name, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, zt_pvt::context, ast_channel::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dsp_features, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, zt_pvt::hardwaredtmf, ast_channel::language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, 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, progzone, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, strdup, SUB_REAL, subnames, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::type, usecnt, ast_channel::writeformat, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().

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

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

int zt_open char *  fn  )  [static]
 

Definition at line 891 of file chan_zap.c.

References ast_log(), and LOG_WARNING.

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

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

struct ast_frame * zt_read struct ast_channel ast  ) 
 

Definition at line 4372 of file chan_zap.c.

References __zt_exception(), ast_channel::_state, ast_async_goto(), ast_clear_flag, ast_dsp_process(), ast_exists_extension(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, 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_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_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_frame::mallocd, ast_channel::name, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, ast_frame::offset, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, pbx_builtin_setvar_helper(), zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, ast_frame::samples, send_callerid(), send_cwcidspill(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_confmute(), zt_get_index(), and zt_setlinear().

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

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

Definition at line 7446 of file chan_zap.c.

References alloc_sub(), AST_FORMAT_SLINEAR, ast_log(), ast_mutex_lock(), ast_mutex_t, ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, ast_verbose(), available(), ast_channel::cdrflags, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::inalarm, zt_pvt::lock, lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, zt_pvt::next, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), round_robin, s, zt_pvt::sig, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, zt_subchannel::zfd, and zt_new().

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

int zt_ring_phone struct zt_pvt p  )  [static]
 

Definition at line 3295 of file chan_zap.c.

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

Referenced by __zt_exception(), and zt_handle_event().

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

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

Definition at line 10962 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, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, zt_pvt::mate, poll(), POLLOUT, PUT_CLID, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, text, zt_subchannel::zfd, and zt_get_index().

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

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

Definition at line 1578 of file chan_zap.c.

References ast_log(), and LOG_WARNING.

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

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

int zt_setlaw int  zfd,
int  law
 

Definition at line 948 of file chan_zap.c.

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

int zt_setlinear int  zfd,
int  linear
 

Definition at line 938 of file chan_zap.c.

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

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

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

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

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

void zt_train_ec struct zt_pvt p  )  [static]
 

Definition at line 1411 of file chan_zap.c.

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

Referenced by zt_answer(), and zt_handle_event().

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

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

Definition at line 2876 of file chan_zap.c.

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

Referenced by zt_bridge(), and zt_fixup().

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

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.

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 }

int zt_wink struct zt_pvt p,
int  index
[static]
 

Definition at line 5176 of file chan_zap.c.

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

Referenced by ss_thread().

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

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

Definition at line 4721 of file chan_zap.c.

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

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


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] = "" [static]
 

Definition at line 269 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int adsi = 0 [static]
 

Definition at line 275 of file chan_zap.c.

Referenced by setup_zap().

int alarm
 

Definition at line 1077 of file chan_zap.c.

Referenced by action_zapshowchannels(), and alarm2str().

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

Referenced by alarm2str(), and zap_show_status().

int amaflags = 0 [static]
 

Definition at line 273 of file chan_zap.c.

Referenced by setup_zap().

int answeronpolarityswitch = 0 [static]
 

Whether we answer on a Polarity Switch event.

Definition at line 335 of file chan_zap.c.

Referenced by setup_zap().

int busy_quietlength = 0 [static]
 

Definition at line 265 of file chan_zap.c.

Referenced by setup_zap().

int busy_tonelength = 0 [static]
 

Definition at line 264 of file chan_zap.c.

Referenced by setup_zap().

int busycount = 3 [static]
 

Definition at line 263 of file chan_zap.c.

Referenced by setup_zap().

int busydetect = 0 [static]
 

Definition at line 261 of file chan_zap.c.

Referenced by setup_zap().

struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static]
 

Definition at line 756 of file chan_zap.c.

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

int callprogress = 0 [static]
 

Definition at line 267 of file chan_zap.c.

Referenced by setup_zap().

int callreturn = 0 [static]
 

Definition at line 237 of file chan_zap.c.

Referenced by setup_zap().

int callwaiting = 0 [static]
 

Definition at line 227 of file chan_zap.c.

Referenced by setup_zap().

int callwaitingcallerid = 0 [static]
 

Definition at line 229 of file chan_zap.c.

Referenced by setup_zap().

int cancallforward = 0 [static]
 

Definition at line 245 of file chan_zap.c.

Referenced by setup_zap().

int canpark = 0 [static]
 

Definition at line 243 of file chan_zap.c.

Referenced by setup_zap().

char cid_name[256] = "" [static]
 

Definition at line 200 of file chan_zap.c.

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

char cid_num[256] = "" [static]
 

Definition at line 199 of file chan_zap.c.

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

int cid_signalling = CID_SIG_BELL [static]
 

Definition at line 213 of file chan_zap.c.

Referenced by setup_zap(), and ss_thread().

int cid_start = CID_START_RING [static]
 

Definition at line 214 of file chan_zap.c.

Referenced by setup_zap().

int cidrings[NUM_CADENCE_MAX] [static]
 

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

Definition at line 769 of file chan_zap.c.

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

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

Definition at line 160 of file chan_zap.c.

Referenced by setup_zap().

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

Definition at line 198 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

ast_group_t cur_callergroup = 0 [static]
 

Definition at line 219 of file chan_zap.c.

Referenced by setup_zap().

int cur_debounce = -1 [static]
 

Definition at line 286 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_flash = -1 [static]
 

Definition at line 282 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

ast_group_t cur_group = 0 [static]
 

Definition at line 218 of file chan_zap.c.

Referenced by setup_zap().

ast_group_t cur_pickupgroup = 0 [static]
 

Definition at line 220 of file chan_zap.c.

Referenced by setup_zap().

int cur_preflash = -1 [static]
 

Definition at line 280 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_prewink = -1 [static]
 

Definition at line 279 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_priexclusive = 0 [static]
 

Definition at line 287 of file chan_zap.c.

Referenced by setup_zap().

int cur_rxflash = -1 [static]
 

Definition at line 285 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_rxwink = -1 [static]
 

Definition at line 284 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_signalling = -1 [static]
 

Definition at line 216 of file chan_zap.c.

Referenced by setup_zap().

int cur_start = -1 [static]
 

Definition at line 283 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

int cur_wink = -1 [static]
 

Definition at line 281 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char defaultcic[64] = "" [static]
 

Definition at line 201 of file chan_zap.c.

Referenced by setup_zap().

char defaultozz[64] = "" [static]
 

Definition at line 202 of file chan_zap.c.

Referenced by setup_zap().

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

Referenced by setup_zap().

int echocancel [static]
 

Definition at line 253 of file chan_zap.c.

Referenced by setup_zap().

int echotraining [static]
 

Definition at line 255 of file chan_zap.c.

Referenced by setup_zap().

char* events[] [static]
 

Definition at line 1054 of file chan_zap.c.

Referenced by event2str().

int firstdigittimeout = 16000 [static]
 

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

Definition at line 313 of file chan_zap.c.

int gendigittimeout = 8000 [static]
 

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

Definition at line 316 of file chan_zap.c.

int hanguponpolarityswitch = 0 [static]
 

Whether we hang up on a Polarity Switch event.

Definition at line 338 of file chan_zap.c.

Referenced by setup_zap().

int hidecallerid = 0 [static]
 

Definition at line 231 of file chan_zap.c.

Referenced by setup_zap().

int ifcount = 0 [static]
 

Definition at line 328 of file chan_zap.c.

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

struct zt_pvt * iflist [static]
 

int immediate = 0 [static]
 

Definition at line 223 of file chan_zap.c.

Referenced by setup_zap().

char language[MAX_LANGUAGE] = "" [static]
 

Definition at line 204 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char mailbox[AST_MAX_EXTENSION] [static]
 

Definition at line 271 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

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.

Referenced by __unload_module(), and restart_monitor().

char musicclass[MAX_MUSICCLASS] = "" [static]
 

Definition at line 205 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char* name
 

Definition at line 1078 of file chan_zap.c.

int num_cadence = 4 [static]
 

Definition at line 753 of file chan_zap.c.

Referenced by setup_zap().

int numbufs = 4 [static]
 

Definition at line 277 of file chan_zap.c.

Referenced by setup_zap().

int polarityonanswerdelay = 600 [static]
 

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

Definition at line 341 of file chan_zap.c.

Referenced by setup_zap().

int priindication_oob = 0 [static]
 

Definition at line 289 of file chan_zap.c.

Referenced by setup_zap().

char progzone[10] = "" [static]
 

Definition at line 206 of file chan_zap.c.

Referenced by setup_zap(), and zt_new().

int pulse [static]
 

Definition at line 257 of file chan_zap.c.

Referenced by setup_zap().

int receivedRingT
 

Used to find out what ringtone we are on

Definition at line 763 of file chan_zap.c.

Referenced by ss_thread().

int relaxdtmf = 0 [static]
 

Definition at line 221 of file chan_zap.c.

Referenced by setup_zap().

int restrictcid = 0 [static]
 

Definition at line 233 of file chan_zap.c.

Referenced by setup_zap().

int ringt_base = DEFAULT_RINGT [static]
 

Definition at line 397 of file chan_zap.c.

Referenced by setup_zap().

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

int sendcalleridafter = DEFAULT_CIDRINGS [static]
 

When to send the CallerID signals (rings).

Definition at line 344 of file chan_zap.c.

Referenced by setup_zap().

char show_channel_usage[] [static]
 

Initial value:

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

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

int stripmsd = 0 [static]
 

Definition at line 225 of file chan_zap.c.

Referenced by setup_zap().

char* subnames[] [static]
 

Initial value:

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

Definition at line 495 of file chan_zap.c.

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

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

Definition at line 150 of file chan_zap.c.

int threewaycalling = 0 [static]
 

Definition at line 239 of file chan_zap.c.

Referenced by setup_zap().

int tonezone = -1 [static]
 

Definition at line 251 of file chan_zap.c.

Referenced by setup_zap().

int transfer = 0 [static]
 

Definition at line 241 of file chan_zap.c.

Referenced by setup_zap().

int transfertobusy = 1 [static]
 

Definition at line 210 of file chan_zap.c.

Referenced by setup_zap().

float txgain = 0.0 [static]
 

Definition at line 249 of file chan_zap.c.

Referenced by set_actual_gain(), and setup_zap().

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

Definition at line 159 of file chan_zap.c.

int use_callerid = 1 [static]
 

Definition at line 212 of file chan_zap.c.

Referenced by setup_zap().

int use_callingpres = 0 [static]
 

Definition at line 235 of file chan_zap.c.

Referenced by setup_zap().

int usecnt = 0 [static]
 

Definition at line 321 of file chan_zap.c.

Referenced by zt_hangup(), and zt_new().

int usedistinctiveringdetection = 0 [static]
 

Definition at line 208 of file chan_zap.c.

Referenced by setup_zap().

int user_has_defined_cadences = 0 [static]
 

Definition at line 754 of file chan_zap.c.

Referenced by setup_zap().

struct ast_cli_entry zap_cli[] [static]
 

Definition at line 9842 of file chan_zap.c.

Referenced by __unload_module(), and load_module().

char zap_show_cadences_help[] [static]
 

Initial value:

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

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

const struct ast_channel_tech zap_tech [static]
 

Definition at line 705 of file chan_zap.c.

Referenced by __unload_module(), and load_module().

int zaptrcallerid = 0 [static]
 

Definition at line 215 of file chan_zap.c.

Referenced by setup_zap().


Generated on Mon Mar 20 08:25:56 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1