Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:22 2007

Asterisk developer's documentation :: Codename Pineapple


chan_zap.c File Reference


Detailed Description

Zaptel Pseudo TDM interface.

Author:
Mark Spencer <markster@digium.com>
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
Todo:
Deprecate the "musiconhold" configuration option post 1.4

Definition in file chan_zap.c.

#include "asterisk.h"
#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 <math.h>
#include <ctype.h>
#include "asterisk/zapata.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj.h"

Include dependency graph for chan_zap.c:

Go to the source code of this file.

Data Structures

struct  distRingData
struct  ringContextData
struct  zt_chan_conf
 Channel configuration from zapata.conf . This struct is used for parsing the [channels] section of zapata.conf. Generally there is a field here for every possible configuration item. More...
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 %-10.10s %-10.10s\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 %-10.10s %-10.10s\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_CHANLIST_LEN   80
#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_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((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_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
#define SIG_FGC_CAMAMF   (0x8000000 | 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_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 SIG_SS7   (0x1000000 | ZT_SIG_CLEAR)
#define SMDI_MD_WAIT_TIMEOUT   1500
#define SUB_CALLWAIT   1
#define SUB_REAL   0
#define SUB_THREEWAY   2
#define tdesc   "Zapata Telephony"
#define TRAILER_MS   5
#define TRANSFER   0
#define ZT_EVENT_DTMFDOWN   0
#define ZT_EVENT_DTMFUP   0

Functions

static int __unload_module (void)
static struct ast_frame__zt_exception (struct ast_channel *ast)
static int action_transfer (struct mansession *s, const struct message *m)
static int action_transferhangup (struct mansession *s, const struct message *m)
static int action_zapdialoffhook (struct mansession *s, const struct message *m)
static int action_zapdndoff (struct mansession *s, const struct message *m)
static int action_zapdndon (struct mansession *s, const struct message *m)
static int action_zaprestart (struct mansession *s, const struct message *m)
static int action_zapshowchannels (struct mansession *s, const struct message *m)
static char * alarm2str (int alarm)
static int alloc_sub (struct zt_pvt *p, int x)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,)
 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).
static int attempt_transfer (struct zt_pvt *p)
static int available (struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
static int build_channels (struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
static int bump_gains (struct zt_pvt *p)
static struct zt_pvtchandup (struct zt_pvt *src)
static int check_for_conference (struct zt_pvt *p)
static int conf_add (struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
static int conf_del (struct zt_pvt *p, struct zt_subchannel *c, int index)
static int destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now)
static void destroy_zt_pvt (struct zt_pvt **pvt)
static int digit_to_dtmfindex (char digit)
static void disable_dtmf_detect (struct zt_pvt *p)
static void * do_monitor (void *data)
static void enable_dtmf_detect (struct zt_pvt *p)
static char * event2str (int event)
static void fill_rxgain (struct zt_gains *g, float gain, int law)
static void fill_txgain (struct zt_gains *g, float gain, int law)
static struct zt_pvtfind_channel (int channel)
static int get_alarms (struct zt_pvt *p)
static int handle_init_event (struct zt_pvt *i, int event)
static int handle_zap_show_cadences (int fd, int argc, char *argv[])
static int has_voicemail (struct zt_pvt *p)
static int isourconf (struct zt_pvt *p, struct zt_subchannel *c)
static int isslavenative (struct zt_pvt *p, struct zt_pvt **out)
static int load_module (void)
static struct zt_pvtmkintf (int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
static int my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms)
static int my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
static int process_zap (struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
static int reload (void)
static int reset_conf (struct zt_pvt *p)
static int restart_monitor (void)
 Start the channel monitor thread.
static int restore_conference (struct zt_pvt *p)
static int restore_gains (struct zt_pvt *p)
static int save_conference (struct zt_pvt *p)
static int send_callerid (struct zt_pvt *p)
static int send_cwcidspill (struct zt_pvt *p)
static int set_actual_gain (int fd, int chan, float rxgain, float txgain, int law)
static int set_actual_rxgain (int fd, int chan, float gain, int law)
static int set_actual_txgain (int fd, int chan, float gain, int law)
static int setup_zap (int reload)
static void * ss_thread (void *data)
static void swap_subs (struct zt_pvt *p, int a, int b)
static int unalloc_sub (struct zt_pvt *p, int x)
static int unload_module (void)
static int update_conf (struct zt_pvt *p)
static void wakeup_sub (struct zt_pvt *p, int a, void *pri)
static int zap_destroy_channel (int fd, int argc, char **argv)
static int zap_fake_event (struct zt_pvt *p, int mode)
static void zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *data)
static int zap_restart (void)
static int zap_restart_cmd (int fd, int argc, char **argv)
static int zap_show_channel (int fd, int argc, char **argv)
static int zap_show_channels (int fd, int argc, char **argv)
static int zap_show_status (int fd, int argc, char *argv[])
static char * zap_sig2str (int sig)
static int zt_answer (struct ast_channel *ast)
static enum ast_bridge_result zt_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int zt_call (struct ast_channel *ast, char *rdest, int timeout)
static int zt_callwait (struct ast_channel *ast)
static struct zt_chan_conf zt_chan_conf_default (void)
static void zt_close (int fd)
static int zt_confmute (struct zt_pvt *p, int muted)
static int zt_digit_begin (struct ast_channel *ast, char digit)
static int zt_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
static void zt_disable_ec (struct zt_pvt *p)
static void zt_enable_ec (struct zt_pvt *p)
static struct ast_framezt_exception (struct ast_channel *ast)
static int zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static int zt_func_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
static int zt_get_event (int fd)
 Avoid the silly zt_getevent which ignores a bunch of events.
static int zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok)
static struct ast_framezt_handle_event (struct ast_channel *ast)
static int zt_hangup (struct ast_channel *ast)
static int zt_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen)
static void zt_link (struct zt_pvt *slave, struct zt_pvt *master)
static struct ast_channelzt_new (struct zt_pvt *, int, int, int, int, int)
static int zt_open (char *fn)
static struct ast_framezt_read (struct ast_channel *ast)
static struct ast_channelzt_request (const char *type, int format, void *data, int *cause)
static int zt_ring_phone (struct zt_pvt *p)
static int zt_sendtext (struct ast_channel *c, const char *text)
static int zt_set_hook (int fd, int hs)
static int zt_setlinear (int zfd, int linear)
static int zt_setoption (struct ast_channel *chan, int option, void *data, int datalen)
static void zt_train_ec (struct zt_pvt *p)
static void zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock)
static int zt_wait_event (int fd)
 Avoid the silly zt_waitevent which ignores a bunch of events.
static int zt_wink (struct zt_pvt *p, int index)
static int zt_write (struct ast_channel *ast, struct ast_frame *frame)

Variables

struct {
   int   alarm
   const char *   description
   unsigned int   event_log:1
   char *   ext
   char *   mtype
   char *   name
   const char *   name
   rtpPayloadType   payloadType
   unsigned int   queue_log:1
   char *   subtype
   char *   type
   int   val
alarms []
static struct zt_ring_cadence cadences [NUM_CADENCE_MAX]
static int cidrings [NUM_CADENCE_MAX]
 cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.
static const char config [] = "zapata.conf"
static struct ast_jb_conf default_jbconf
static char defaultcic [64] = ""
static char defaultozz [64] = ""
static const char destroy_channel_usage []
static int distinctiveringaftercid = 0
static struct zt_distRings drings
static char * events []
static int firstdigittimeout = 16000
 Wait up to 16 seconds for first digit (FXO logic).
static int gendigittimeout = 8000
 How long to wait for following digits (FXO logic).
static struct ast_jb_conf global_jbconf
static int ifcount = 0
static struct zt_pvtifend
static struct zt_pvtiflist
static char language [MAX_LANGUAGE] = ""
static int matchdigittimeout = 3000
 How long to wait for an extra digit, if there is an ambiguous match.
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static int num_cadence = 4
static int numbufs = 4
static char progzone [10] = ""
static int ringt_base = DEFAULT_RINGT
zt_pvtround_robin [32]
static const char show_channel_usage []
static const char show_channels_usage []
static char * subnames []
static const char tdesc [] = "Zapata Telephony Driver"
static int usedistinctiveringdetection = 0
static int user_has_defined_cadences = 0
static struct ast_cli_entry zap_cli []
static const char zap_restart_usage []
static char zap_show_cadences_help []
static const char zap_show_status_usage []
static const struct ast_channel_tech zap_tech


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

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

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

300 ms

Definition at line 292 of file chan_zap.c.

Referenced by zt_callwait().

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

300 ms

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

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

Definition at line 839 of file chan_zap.c.

Referenced by zt_handle_event().

#define CHAN_PSEUDO   -2
 

Definition at line 203 of file chan_zap.c.

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

#define CHANNEL_PSEUDO   -12
 

Definition at line 155 of file chan_zap.c.

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

500 ms

Definition at line 293 of file chan_zap.c.

Referenced by send_callerid().

#define CONF_USER_REAL   (1 << 0)
 

Definition at line 450 of file chan_zap.c.

#define CONF_USER_THIRDCALL   (1 << 1)
 

Definition at line 451 of file chan_zap.c.

#define DCHAN_AVAILABLE   (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
 

Definition at line 209 of file chan_zap.c.

#define DCHAN_NOTINALARM   (1 << 1)
 

Definition at line 206 of file chan_zap.c.

#define DCHAN_PROVISIONED   (1 << 0)
 

Definition at line 205 of file chan_zap.c.

#define DCHAN_UP   (1 << 2)
 

Definition at line 207 of file chan_zap.c.

#define DEFAULT_CIDRINGS   1
 

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

Definition at line 153 of file chan_zap.c.

Referenced by zt_chan_conf_default().

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

Definition at line 295 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 %-10.10s %-10.10s\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 %-10.10s %-10.10s\n"
 

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

Definition at line 764 of file chan_zap.c.

#define HANGUP   1
 

Definition at line 11026 of file chan_zap.c.

Referenced by action_transferhangup(), and zap_fake_event().

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

Referenced by zt_sendtext().

#define HEADER_MS   50
 

Referenced by zt_sendtext().

#define ISTRUNK  ) 
 

Value:

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

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

#define MASK_INUSE   (1 << 1)
 

Channel currently in use

Definition at line 289 of file chan_zap.c.

#define MAX_CHANLIST_LEN   80
 

The length of the parameters list of 'zapchan'.

Todo:
Move definition of MAX_CHANLIST_LEN to a proper place.

Definition at line 11712 of file chan_zap.c.

Referenced by process_zap().

#define MAX_CHANNELS   672
 

No more than a DS3 per trunk group

Definition at line 201 of file chan_zap.c.

#define MAX_SLAVES   4
 

Definition at line 453 of file chan_zap.c.

#define MIN_MS_SINCE_FLASH   ( (2000) )
 

2000 ms

Definition at line 294 of file chan_zap.c.

Referenced by zt_handle_event().

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

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

Definition at line 160 of file chan_zap.c.

Referenced by ss_thread().

#define NUM_CADENCE_MAX   25
 

Definition at line 813 of file chan_zap.c.

#define NUM_DCHANS   4
 

No more than 4 d-channels

Definition at line 200 of file chan_zap.c.

#define NUM_SPANS   32
 

Definition at line 199 of file chan_zap.c.

#define POLARITY_IDLE   0
 

Definition at line 407 of file chan_zap.c.

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

#define POLARITY_REV   1
 

Definition at line 408 of file chan_zap.c.

Referenced by handle_init_event(), and zt_handle_event().

#define READ_SIZE   160
 

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

Definition at line 286 of file chan_zap.c.

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

#define sig2str   zap_sig2str
 

Definition at line 1336 of file chan_zap.c.

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

#define SIG_E911   (0x1000000 | ZT_SIG_EM)
 

Definition at line 178 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 173 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 195 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 174 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 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_FEATD   (0x0200000 | ZT_SIG_EM)
 

Definition at line 175 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 176 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 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_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
 

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_FGC_CAMAMF   (0x8000000 | ZT_SIG_EM)
 

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_FXOGS   ZT_SIG_FXOGS
 

Definition at line 186 of file chan_zap.c.

Referenced by available(), 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 187 of file chan_zap.c.

Referenced by available(), 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 185 of file chan_zap.c.

Referenced by available(), 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 183 of file chan_zap.c.

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

#define SIG_FXSKS   ZT_SIG_FXSKS
 

Definition at line 184 of file chan_zap.c.

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

#define SIG_FXSLS   ZT_SIG_FXSLS
 

Definition at line 182 of file chan_zap.c.

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

#define SIG_GR303FXOKS   (0x0100000 | ZT_SIG_FXOKS)
 

Definition at line 196 of file chan_zap.c.

Referenced by handle_init_event(), and zap_sig2str().

#define SIG_GR303FXSKS   (0x0100000 | ZT_SIG_FXSKS)
 

Definition at line 197 of file chan_zap.c.

Referenced by handle_init_event(), and zap_sig2str().

#define SIG_PRI   ZT_SIG_CLEAR
 

Definition at line 188 of file chan_zap.c.

Referenced by handle_init_event(), ss_thread(), zap_queue_frame(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit_begin(), zt_digit_end(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), and zt_write().

#define SIG_SF   ZT_SIG_SF
 

Definition at line 190 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 194 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 192 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 193 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 191 of file chan_zap.c.

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

#define SIG_SS7   (0x1000000 | ZT_SIG_CLEAR)
 

Definition at line 189 of file chan_zap.c.

Referenced by handle_init_event(), zap_queue_frame(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_enable_ec(), zt_hangup(), and zt_indicate().

#define SMDI_MD_WAIT_TIMEOUT   1500
 

Definition at line 109 of file chan_zap.c.

Referenced by ss_thread().

#define SUB_CALLWAIT   1
 

Call-Waiting call on hold

Definition at line 403 of file chan_zap.c.

#define SUB_REAL   0
 

Active call

Definition at line 402 of file chan_zap.c.

#define SUB_THREEWAY   2
 

Three-way call

Definition at line 404 of file chan_zap.c.

#define tdesc   "Zapata Telephony"
 

Definition at line 12772 of file chan_zap.c.

#define TRAILER_MS   5
 

#define TRANSFER   0
 

Definition at line 11025 of file chan_zap.c.

Referenced by action_transfer(), and zap_fake_event().

#define ZT_EVENT_DTMFDOWN   0
 

Definition at line 127 of file chan_zap.c.

Referenced by zt_handle_event().

#define ZT_EVENT_DTMFUP   0
 

Definition at line 128 of file chan_zap.c.

Referenced by zt_handle_event().


Function Documentation

static int __unload_module void   )  [static]
 

Definition at line 11207 of file chan_zap.c.

References AST_PTHREADT_NULL.

11208 {
11209    int x = 0;
11210    struct zt_pvt *p, *pl;
11211 #ifdef HAVE_PRI
11212    int i;
11213    for (i = 0; i < NUM_SPANS; i++) {
11214       if (pris[i].master != AST_PTHREADT_NULL) 
11215          pthread_cancel(pris[i].master);
11216    }
11217    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11218    ast_unregister_application(zap_send_keypad_facility_app);
11219 #endif
11220    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11221    ast_manager_unregister( "ZapDialOffhook" );
11222    ast_manager_unregister( "ZapHangup" );
11223    ast_manager_unregister( "ZapTransfer" );
11224    ast_manager_unregister( "ZapDNDoff" );
11225    ast_manager_unregister( "ZapDNDon" );
11226    ast_manager_unregister("ZapShowChannels");
11227    ast_manager_unregister("ZapRestart");
11228    ast_channel_unregister(&zap_tech);
11229    ast_mutex_lock(&iflock);
11230    /* Hangup all interfaces if they have an owner */
11231    p = iflist;
11232    while (p) {
11233       if (p->owner)
11234          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
11235       p = p->next;
11236    }
11237    ast_mutex_unlock(&iflock);
11238    ast_mutex_lock(&monlock);
11239    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
11240       pthread_cancel(monitor_thread);
11241       pthread_kill(monitor_thread, SIGURG);
11242       pthread_join(monitor_thread, NULL);
11243    }
11244    monitor_thread = AST_PTHREADT_STOP;
11245    ast_mutex_unlock(&monlock);
11246 
11247    ast_mutex_lock(&iflock);
11248    /* Destroy all the interfaces and free their memory */
11249    p = iflist;
11250    while (p) {
11251       /* Free any callerid */
11252       if (p->cidspill)
11253          free(p->cidspill);
11254       /* Close the zapata thingy */
11255       if (p->subs[SUB_REAL].zfd > -1)
11256          zt_close(p->subs[SUB_REAL].zfd);
11257       pl = p;
11258       p = p->next;
11259       x++;
11260       /* Free associated memory */
11261       if (pl)
11262          destroy_zt_pvt(&pl);
11263       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
11264    }
11265    iflist = NULL;
11266    ifcount = 0;
11267    ast_mutex_unlock(&iflock);
11268 #ifdef HAVE_PRI      
11269    for (i = 0; i < NUM_SPANS; i++) {
11270       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
11271          pthread_join(pris[i].master, NULL);
11272       zt_close(pris[i].fds[i]);
11273    }
11274 #endif
11275 #ifdef HAVE_SS7
11276    for (i = 0; i < NUM_SPANS; i++) {
11277       if (linksets[i].master && (linksets[i].master != AST_PTHREADT_NULL))
11278          pthread_join(linksets[i].master, NULL);
11279       zt_close(linksets[i].fds[i]);
11280    }
11281 #endif /* HAVE_SS7 */
11282    return 0;
11283 }

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

Definition at line 4676 of file chan_zap.c.

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

Referenced by zt_exception(), and zt_read().

04677 {
04678    struct zt_pvt *p = ast->tech_pvt;
04679    int res;
04680    int usedindex=-1;
04681    int index;
04682    struct ast_frame *f;
04683 
04684 
04685    index = zt_get_index(ast, p, 1);
04686    
04687    p->subs[index].f.frametype = AST_FRAME_NULL;
04688    p->subs[index].f.datalen = 0;
04689    p->subs[index].f.samples = 0;
04690    p->subs[index].f.mallocd = 0;
04691    p->subs[index].f.offset = 0;
04692    p->subs[index].f.subclass = 0;
04693    p->subs[index].f.delivery = ast_tv(0,0);
04694    p->subs[index].f.src = "zt_exception";
04695    p->subs[index].f.data = NULL;
04696    
04697    
04698    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04699       /* If nobody owns us, absorb the event appropriately, otherwise
04700          we loop indefinitely.  This occurs when, during call waiting, the
04701          other end hangs up our channel so that it no longer exists, but we
04702          have neither FLASH'd nor ONHOOK'd to signify our desire to
04703          change to the other channel. */
04704       if (p->fake_event) {
04705          res = p->fake_event;
04706          p->fake_event = 0;
04707       } else
04708          res = zt_get_event(p->subs[SUB_REAL].zfd);
04709       /* Switch to real if there is one and this isn't something really silly... */
04710       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04711          (res != ZT_EVENT_HOOKCOMPLETE)) {
04712          if (option_debug)
04713             ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04714          p->owner = p->subs[SUB_REAL].owner;
04715          if (p->owner && ast_bridged_channel(p->owner))
04716             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04717          p->subs[SUB_REAL].needunhold = 1;
04718       }
04719       switch (res) {
04720       case ZT_EVENT_ONHOOK:
04721          zt_disable_ec(p);
04722          if (p->owner) {
04723             if (option_verbose > 2) 
04724                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04725             zt_ring_phone(p);
04726             p->callwaitingrepeat = 0;
04727             p->cidcwexpire = 0;
04728          } else
04729             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04730          update_conf(p);
04731          break;
04732       case ZT_EVENT_RINGOFFHOOK:
04733          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04734          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04735             p->subs[SUB_REAL].needanswer = 1;
04736             p->dialing = 0;
04737          }
04738          break;
04739       case ZT_EVENT_HOOKCOMPLETE:
04740       case ZT_EVENT_RINGERON:
04741       case ZT_EVENT_RINGEROFF:
04742          /* Do nothing */
04743          break;
04744       case ZT_EVENT_WINKFLASH:
04745          gettimeofday(&p->flashtime, NULL);
04746          if (p->owner) {
04747             if (option_verbose > 2) 
04748                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04749             if (p->owner->_state != AST_STATE_UP) {
04750                /* Answer if necessary */
04751                usedindex = zt_get_index(p->owner, p, 0);
04752                if (usedindex > -1) {
04753                   p->subs[usedindex].needanswer = 1;
04754                }
04755                ast_setstate(p->owner, AST_STATE_UP);
04756             }
04757             p->callwaitingrepeat = 0;
04758             p->cidcwexpire = 0;
04759             if (ast_bridged_channel(p->owner))
04760                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04761             p->subs[SUB_REAL].needunhold = 1;
04762          } else
04763             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04764          update_conf(p);
04765          break;
04766       default:
04767          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04768       }
04769       f = &p->subs[index].f;
04770       return f;
04771    }
04772    if (!(p->radio || (p->oprmode < 0))) {
04773       if (option_debug)
04774          ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04775    }
04776    /* If it's not us, return NULL immediately */
04777    if (ast != p->owner) {
04778       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04779       f = &p->subs[index].f;
04780       return f;
04781    }
04782    f = zt_handle_event(ast);
04783    return f;
04784 }

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

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

11095 {
11096    struct zt_pvt *p = NULL;
11097    const char *channel = astman_get_header(m, "ZapChannel");
11098 
11099    if (ast_strlen_zero(channel)) {
11100       astman_send_error(s, m, "No channel specified");
11101       return 0;
11102    }
11103    p = find_channel(atoi(channel));
11104    if (!p) {
11105       astman_send_error(s, m, "No such channel");
11106       return 0;
11107    }
11108    zap_fake_event(p,TRANSFER);
11109    astman_send_ack(s, m, "ZapTransfer");
11110    return 0;
11111 }

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

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

11114 {
11115    struct zt_pvt *p = NULL;
11116    const char *channel = astman_get_header(m, "ZapChannel");
11117 
11118    if (ast_strlen_zero(channel)) {
11119       astman_send_error(s, m, "No channel specified");
11120       return 0;
11121    }
11122    p = find_channel(atoi(channel));
11123    if (!p) {
11124       astman_send_error(s, m, "No such channel");
11125       return 0;
11126    }
11127    zap_fake_event(p,HANGUP);
11128    astman_send_ack(s, m, "ZapHangup");
11129    return 0;
11130 }

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

Definition at line 11132 of file chan_zap.c.

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

11133 {
11134    struct zt_pvt *p = NULL;
11135    const char *channel = astman_get_header(m, "ZapChannel");
11136    const char *number = astman_get_header(m, "Number");
11137    int i;
11138 
11139    if (ast_strlen_zero(channel)) {
11140       astman_send_error(s, m, "No channel specified");
11141       return 0;
11142    }
11143    if (ast_strlen_zero(number)) {
11144       astman_send_error(s, m, "No number specified");
11145       return 0;
11146    }
11147    p = find_channel(atoi(channel));
11148    if (!p) {
11149       astman_send_error(s, m, "No such channel");
11150       return 0;
11151    }
11152    if (!p->owner) {
11153       astman_send_error(s, m, "Channel does not have it's owner");
11154       return 0;
11155    }
11156    for (i = 0; i < strlen(number); i++) {
11157       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
11158       zap_queue_frame(p, &f, NULL); 
11159    }
11160    astman_send_ack(s, m, "ZapDialOffhook");
11161    return 0;
11162 }

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

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

11076 {
11077    struct zt_pvt *p = NULL;
11078    const char *channel = astman_get_header(m, "ZapChannel");
11079 
11080    if (ast_strlen_zero(channel)) {
11081       astman_send_error(s, m, "No channel specified");
11082       return 0;
11083    }
11084    p = find_channel(atoi(channel));
11085    if (!p) {
11086       astman_send_error(s, m, "No such channel");
11087       return 0;
11088    }
11089    p->dnd = 0;
11090    astman_send_ack(s, m, "DND Disabled");
11091    return 0;
11092 }

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

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

11057 {
11058    struct zt_pvt *p = NULL;
11059    const char *channel = astman_get_header(m, "ZapChannel");
11060 
11061    if (ast_strlen_zero(channel)) {
11062       astman_send_error(s, m, "No channel specified");
11063       return 0;
11064    }
11065    p = find_channel(atoi(channel));
11066    if (!p) {
11067       astman_send_error(s, m, "No such channel");
11068       return 0;
11069    }
11070    p->dnd = 1;
11071    astman_send_ack(s, m, "DND Enabled");
11072    return 0;
11073 }

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

Definition at line 10661 of file chan_zap.c.

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

10662 {
10663    if (zap_restart() != 0) {
10664       astman_send_error(s, m, "Failed rereading zaptel configuration");
10665       return 1;
10666    }
10667    astman_send_ack(s, m, "ZapRestart: Success");
10668    return 0;
10669 }

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

Definition at line 11164 of file chan_zap.c.

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

11165 {
11166    struct zt_pvt *tmp = NULL;
11167    const char *id = astman_get_header(m, "ActionID");
11168    char idText[256] = "";
11169 
11170    astman_send_ack(s, m, "Zapata channel status will follow");
11171    if (!ast_strlen_zero(id))
11172       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
11173 
11174    ast_mutex_lock(&iflock);
11175    
11176    tmp = iflist;
11177    while (tmp) {
11178       if (tmp->channel > 0) {
11179          int alarm = get_alarms(tmp);
11180          astman_append(s,
11181             "Event: ZapShowChannels\r\n"
11182             "Channel: %d\r\n"
11183             "Signalling: %s\r\n"
11184             "Context: %s\r\n"
11185             "DND: %s\r\n"
11186             "Alarm: %s\r\n"
11187             "%s"
11188             "\r\n",
11189             tmp->channel, sig2str(tmp->sig), tmp->context, 
11190             tmp->dnd ? "Enabled" : "Disabled",
11191             alarm2str(alarm), idText);
11192       } 
11193 
11194       tmp = tmp->next;
11195    }
11196 
11197    ast_mutex_unlock(&iflock);
11198    
11199    astman_append(s, 
11200       "Event: ZapShowChannelsComplete\r\n"
11201       "%s"
11202       "\r\n", 
11203       idText);
11204    return 0;
11205 }

static char* alarm2str int  alarm  )  [static]
 

Definition at line 1245 of file chan_zap.c.

References alarms, and name.

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

01246 {
01247    int x;
01248    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01249       if (alarms[x].alarm & alarm)
01250          return alarms[x].name;
01251    }
01252    return alarm ? "Unknown Alarm" : "No Alarm";
01253 }

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

Definition at line 1038 of file chan_zap.c.

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

Referenced by ss_thread(), and zt_handle_event().

01039 {
01040    ZT_BUFFERINFO bi;
01041    int res;
01042    if (p->subs[x].zfd < 0) {
01043       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
01044       if (p->subs[x].zfd > -1) {
01045          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
01046          if (!res) {
01047             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
01048             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
01049             bi.numbufs = numbufs;
01050             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
01051             if (res < 0) {
01052                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
01053             }
01054          } else 
01055             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
01056          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
01057             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
01058             zt_close(p->subs[x].zfd);
01059             p->subs[x].zfd = -1;
01060             return -1;
01061          }
01062          if (option_debug)
01063             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
01064          return 0;
01065       } else
01066          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
01067       return -1;
01068    }
01069    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
01070    return -1;
01071 }

AST_MODULE_INFO ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
tdesc  ,
load = load_module,
unload = unload_module,
reload = reload
 

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

static int attempt_transfer struct zt_pvt p  )  [static]
 

Definition at line 3717 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_CONTROL_UNHOLD, ast_indicate(), ast_log(), ast_mutex_unlock(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.

03718 {
03719    /* In order to transfer, we need at least one of the channels to
03720       actually be in a call bridge.  We can't conference two applications
03721       together (but then, why would we want to?) */
03722    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03723       /* The three-way person we're about to transfer to could still be in MOH, so
03724          stop if now if appropriate */
03725       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03726          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03727       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03728          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03729       }
03730       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03731          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03732       }
03733       if (p->subs[SUB_REAL].owner->cdr) {
03734          /* Move CDR from second channel to current one */
03735          p->subs[SUB_THREEWAY].owner->cdr =
03736             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03737          p->subs[SUB_REAL].owner->cdr = NULL;
03738       }
03739       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03740          /* Move CDR from second channel's bridge to current one */
03741          p->subs[SUB_THREEWAY].owner->cdr =
03742             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03743          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03744       }
03745        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03746          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03747                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03748          return -1;
03749       }
03750       /* Orphan the channel after releasing the lock */
03751       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03752       unalloc_sub(p, SUB_THREEWAY);
03753    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03754       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03755       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03756          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03757       }
03758       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03759          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03760       }
03761       if (p->subs[SUB_THREEWAY].owner->cdr) {
03762          /* Move CDR from second channel to current one */
03763          p->subs[SUB_REAL].owner->cdr = 
03764             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03765          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03766       }
03767       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03768          /* Move CDR from second channel's bridge to current one */
03769          p->subs[SUB_REAL].owner->cdr = 
03770             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03771          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03772       }
03773       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03774          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03775                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03776          return -1;
03777       }
03778       /* Three-way is now the REAL */
03779       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03780       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03781       unalloc_sub(p, SUB_THREEWAY);
03782       /* Tell the caller not to hangup */
03783       return 1;
03784    } else {
03785       if (option_debug)
03786          ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03787                   p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03788       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03789       return -1;
03790    }
03791    return 0;
03792 }

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

Definition at line 7913 of file chan_zap.c.

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

07914 {
07915    int res;
07916    ZT_PARAMS par;
07917 
07918    /* First, check group matching */
07919    if (groupmatch) {
07920       if ((p->group & groupmatch) != groupmatch)
07921          return 0;
07922       *groupmatched = 1;
07923    }
07924    /* Check to see if we have a channel match */
07925    if (channelmatch != -1) {
07926       if (p->channel != channelmatch)
07927          return 0;
07928       *channelmatched = 1;
07929    }
07930    /* We're at least busy at this point */
07931    if (busy) {
07932       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07933          *busy = 1;
07934    }
07935    /* If do not disturb, definitely not */
07936    if (p->dnd)
07937       return 0;
07938    /* If guard time, definitely not */
07939    if (p->guardtime && (time(NULL) < p->guardtime)) 
07940       return 0;
07941 
07942    if (p->locallyblocked || p->remotelyblocked)
07943       return 0;
07944       
07945    /* If no owner definitely available */
07946    if (!p->owner) {
07947 #ifdef HAVE_PRI
07948       /* Trust PRI */
07949       if (p->pri) {
07950          if (p->resetting || p->call)
07951             return 0;
07952          else
07953             return 1;
07954       }
07955 #endif
07956 #ifdef HAVE_SS7
07957       /* Trust SS7 */
07958       if (p->ss7) {
07959          if (p->ss7call)
07960             return 0;
07961          else
07962             return 1;
07963       }
07964 #endif
07965       if (!(p->radio || (p->oprmode < 0)))
07966       {
07967          if (!p->sig || (p->sig == SIG_FXSLS))
07968             return 1;
07969          /* Check hook state */
07970          if (p->subs[SUB_REAL].zfd > -1)
07971             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07972          else {
07973             /* Assume not off hook on CVRS */
07974             res = 0;
07975             par.rxisoffhook = 0;
07976          }
07977          if (res) {
07978             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07979          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07980             /* When "onhook" that means no battery on the line, and thus
07981               it is out of service..., if it's on a TDM card... If it's a channel
07982               bank, there is no telling... */
07983             if (par.rxbits > -1)
07984                return 1;
07985             if (par.rxisoffhook)
07986                return 1;
07987             else
07988 #ifdef ZAP_CHECK_HOOKSTATE
07989                return 0;
07990 #else
07991                return 1;
07992 #endif
07993          } else if (par.rxisoffhook) {
07994             if (option_debug)
07995                ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07996             /* Not available when the other end is off hook */
07997             return 0;
07998          }
07999       }
08000       return 1;
08001    }
08002 
08003    /* If it's not an FXO, forget about call wait */
08004    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
08005       return 0;
08006 
08007    if (!p->callwaiting) {
08008       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
08009       return 0;
08010    }
08011 
08012    if (p->subs[SUB_CALLWAIT].zfd > -1) {
08013       /* If there is already a call waiting call, then we can't take a second one */
08014       return 0;
08015    }
08016    
08017    if ((p->owner->_state != AST_STATE_UP) &&
08018        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
08019       /* If the current call is not up, then don't allow the call */
08020       return 0;
08021    }
08022    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
08023       /* Can't take a call wait when the three way calling hasn't been merged yet. */
08024       return 0;
08025    }
08026    /* We're cool */
08027    return 1;
08028 }

static int build_channels struct zt_chan_conf  conf,
int  iscrv,
const char *  value,
int  reload,
int  lineno,
int *  found_pseudo
[static]
 

Definition at line 11620 of file chan_zap.c.

References ast_log(), ast_strdupa, zt_chan_conf::chan, LOG_ERROR, and zt_pvt::sig.

Referenced by process_zap().

11621 {
11622    char *c, *chan;
11623    int x, start, finish;
11624    struct zt_pvt *tmp;
11625 #ifdef HAVE_PRI
11626    struct zt_pri *pri;
11627    int trunkgroup, y;
11628 #endif
11629    
11630    if ((reload == 0) && (conf.chan.sig < 0)) {
11631       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
11632       return -1;
11633    }
11634 
11635    c = ast_strdupa(value);
11636 
11637 #ifdef HAVE_PRI
11638    pri = NULL;
11639    if (iscrv) {
11640       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
11641          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
11642          return -1;
11643       }
11644       if (trunkgroup < 1) {
11645          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
11646          return -1;
11647       }
11648       c += y;
11649       for (y = 0; y < NUM_SPANS; y++) {
11650          if (pris[y].trunkgroup == trunkgroup) {
11651             pri = pris + y;
11652             break;
11653          }
11654       }
11655       if (!pri) {
11656          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
11657          return -1;
11658       }
11659    }
11660 #endif         
11661 
11662    while ((chan = strsep(&c, ","))) {
11663       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
11664          /* Range */
11665       } else if (sscanf(chan, "%d", &start)) {
11666          /* Just one */
11667          finish = start;
11668       } else if (!strcasecmp(chan, "pseudo")) {
11669          finish = start = CHAN_PSEUDO;
11670          if (found_pseudo)
11671             *found_pseudo = 1;
11672       } else {
11673          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
11674          return -1;
11675       }
11676       if (finish < start) {
11677          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
11678          x = finish;
11679          finish = start;
11680          start = x;
11681       }
11682 
11683       for (x = start; x <= finish; x++) {
11684 #ifdef HAVE_PRI
11685          tmp = mkintf(x, conf, pri, reload);
11686 #else       
11687          tmp = mkintf(x, conf, NULL, reload);
11688 #endif         
11689 
11690          if (tmp) {
11691             if (option_verbose > 2) {
11692 #ifdef HAVE_PRI
11693                if (pri)
11694                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
11695                else
11696 #endif
11697                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
11698             }
11699          } else {
11700             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
11701                (reload == 1) ? "reconfigure" : "register", value);
11702             return -1;
11703          }
11704       }
11705    }
11706 
11707    return 0;
11708 }

static int bump_gains struct zt_pvt p  )  [static]
 

Definition at line 1710 of file chan_zap.c.

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

Referenced by ss_thread().

01711 {
01712    int res;
01713 
01714    /* Bump receive gain by 5.0db */
01715    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01716    if (res) {
01717       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01718       return -1;
01719    }
01720 
01721    return 0;
01722 }

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

Definition at line 8030 of file chan_zap.c.

References ast_log(), ast_malloc, ast_mutex_init(), destroy_zt_pvt(), iflist, LOG_ERROR, SUB_REAL, and zt_open().

08031 {
08032    struct zt_pvt *p;
08033    ZT_BUFFERINFO bi;
08034    int res;
08035    
08036    if ((p = ast_malloc(sizeof(*p)))) {
08037       memcpy(p, src, sizeof(struct zt_pvt));
08038       ast_mutex_init(&p->lock);
08039       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
08040       /* Allocate a zapata structure */
08041       if (p->subs[SUB_REAL].zfd < 0) {
08042          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
08043          destroy_zt_pvt(&p);
08044          return NULL;
08045       }
08046       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
08047       if (!res) {
08048          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
08049          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
08050          bi.numbufs = numbufs;
08051          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
08052          if (res < 0) {
08053             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
08054          }
08055       } else
08056          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
08057    }
08058    p->destroy = 1;
08059    p->next = iflist;
08060    iflist = p;
08061    return p;
08062 }

static int check_for_conference struct zt_pvt p  )  [static]
 

Definition at line 3794 of file chan_zap.c.

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

Referenced by zt_handle_event().

03795 {
03796    ZT_CONFINFO ci;
03797    /* Fine if we already have a master, etc */
03798    if (p->master || (p->confno > -1))
03799       return 0;
03800    memset(&ci, 0, sizeof(ci));
03801    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03802       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03803       return 0;
03804    }
03805    /* If we have no master and don't have a confno, then 
03806       if we're in a conference, it's probably a MeetMe room or
03807       some such, so don't let us 3-way out! */
03808    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03809       if (option_verbose > 2) 
03810          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03811       return 1;
03812    }
03813    return 0;
03814 }

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

Definition at line 1338 of file chan_zap.c.

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

Referenced by update_conf().

01339 {
01340    /* If the conference already exists, and we're already in it
01341       don't bother doing anything */
01342    ZT_CONFINFO zi;
01343    
01344    memset(&zi, 0, sizeof(zi));
01345    zi.chan = 0;
01346 
01347    if (slavechannel > 0) {
01348       /* If we have only one slave, do a digital mon */
01349       zi.confmode = ZT_CONF_DIGITALMON;
01350       zi.confno = slavechannel;
01351    } else {
01352       if (!index) {
01353          /* Real-side and pseudo-side both participate in conference */
01354          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01355             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01356       } else
01357          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01358       zi.confno = p->confno;
01359    }
01360    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01361       return 0;
01362    if (c->zfd < 0)
01363       return 0;
01364    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01365       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01366       return -1;
01367    }
01368    if (slavechannel < 1) {
01369       p->confno = zi.confno;
01370    }
01371    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01372    if (option_debug)
01373       ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01374    return 0;
01375 }

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

Definition at line 1388 of file chan_zap.c.

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

Referenced by zt_unlink().

01389 {
01390    ZT_CONFINFO zi;
01391    if (/* Can't delete if there's no zfd */
01392       (c->zfd < 0) ||
01393       /* Don't delete from the conference if it's not our conference */
01394       !isourconf(p, c)
01395       /* Don't delete if we don't think it's conferenced at all (implied) */
01396       ) return 0;
01397    memset(&zi, 0, sizeof(zi));
01398    zi.chan = 0;
01399    zi.confno = 0;
01400    zi.confmode = 0;
01401    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01402       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01403       return -1;
01404    }
01405    if (option_debug)
01406       ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01407    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01408    return 0;
01409 }

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

Definition at line 2386 of file chan_zap.c.

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

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

02387 {
02388    int owned = 0;
02389    int i = 0;
02390 
02391    if (!now) {
02392       if (cur->owner) {
02393          owned = 1;
02394       }
02395 
02396       for (i = 0; i < 3; i++) {
02397          if (cur->subs[i].owner) {
02398             owned = 1;
02399          }
02400       }
02401       if (!owned) {
02402          if (prev) {
02403             prev->next = cur->next;
02404             if (prev->next)
02405                prev->next->prev = prev;
02406             else
02407                ifend = prev;
02408          } else {
02409             iflist = cur->next;
02410             if (iflist)
02411                iflist->prev = NULL;
02412             else
02413                ifend = NULL;
02414          }
02415          if (cur->subs[SUB_REAL].zfd > -1) {
02416             zt_close(cur->subs[SUB_REAL].zfd);
02417          }
02418          destroy_zt_pvt(&cur);
02419       }
02420    } else {
02421       if (prev) {
02422          prev->next = cur->next;
02423          if (prev->next)
02424             prev->next->prev = prev;
02425          else
02426             ifend = prev;
02427       } else {
02428          iflist = cur->next;
02429          if (iflist)
02430             iflist->prev = NULL;
02431          else
02432             ifend = NULL;
02433       }
02434       if (cur->subs[SUB_REAL].zfd > -1) {
02435          zt_close(cur->subs[SUB_REAL].zfd);
02436       }
02437       destroy_zt_pvt(&cur);
02438    }
02439    return 0;
02440 }

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

Definition at line 2371 of file chan_zap.c.

References ast_mutex_destroy(), ast_smdi_interface_destroy(), ASTOBJ_UNREF, free, zt_pvt::lock, zt_pvt::next, zt_pvt::prev, zt_pvt::smdi_iface, and zt_pvt::use_smdi.

Referenced by chandup(), and mkintf().

02372 {
02373    struct zt_pvt *p = *pvt;
02374    /* Remove channel from the list */
02375    if (p->prev)
02376       p->prev->next = p->next;
02377    if (p->next)
02378       p->next->prev = p->prev;
02379    if (p->use_smdi)
02380       ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
02381    ast_mutex_destroy(&p->lock);
02382    free(p);
02383    *pvt = NULL;
02384 }

static int digit_to_dtmfindex char  digit  )  [static]
 

Definition at line 1094 of file chan_zap.c.

Referenced by zt_digit_begin().

01095 {
01096    if (isdigit(digit))
01097       return ZT_TONE_DTMF_BASE + (digit - '0');
01098    else if (digit >= 'A' && digit <= 'D')
01099       return ZT_TONE_DTMF_A + (digit - 'A');
01100    else if (digit >= 'a' && digit <= 'd')
01101       return ZT_TONE_DTMF_A + (digit - 'a');
01102    else if (digit == '*')
01103       return ZT_TONE_DTMF_s;
01104    else if (digit == '#')
01105       return ZT_TONE_DTMF_p;
01106    else
01107       return -1;
01108 }

static void disable_dtmf_detect struct zt_pvt p  )  [static]
 

Definition at line 3328 of file chan_zap.c.

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

Referenced by zt_bridge().

03329 {
03330 #ifdef ZT_TONEDETECT
03331    int val;
03332 #endif
03333 
03334    p->ignoredtmf = 1;
03335 
03336 #ifdef ZT_TONEDETECT
03337    val = 0;
03338    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03339 #endif      
03340    if (!p->hardwaredtmf && p->dsp) {
03341       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03342       ast_dsp_set_features(p->dsp, p->dsp_features);
03343    }
03344 }

static void* do_monitor void *  data  )  [static]
 

Definition at line 7055 of file chan_zap.c.

References ast_calloc, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), free, last, and LOG_DEBUG.

07056 {
07057    int count, res, res2, spoint, pollres=0;
07058    struct zt_pvt *i;
07059    struct zt_pvt *last = NULL;
07060    time_t thispass = 0, lastpass = 0;
07061    int found;
07062    char buf[1024];
07063    struct pollfd *pfds=NULL;
07064    int lastalloc = -1;
07065    /* This thread monitors all the frame relay interfaces which are not yet in use
07066       (and thus do not have a separate thread) indefinitely */
07067    /* From here on out, we die whenever asked */
07068 #if 0
07069    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
07070       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
07071       return NULL;
07072    }
07073    if (option_debug)
07074       ast_log(LOG_DEBUG, "Monitor starting...\n");
07075 #endif
07076    for (;;) {
07077       /* Lock the interface list */
07078       ast_mutex_lock(&iflock);
07079       if (!pfds || (lastalloc != ifcount)) {
07080          if (pfds)
07081             free(pfds);
07082          if (ifcount) {
07083             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
07084                ast_mutex_unlock(&iflock);
07085                return NULL;
07086             }
07087          }
07088          lastalloc = ifcount;
07089       }
07090       /* Build the stuff we're going to poll on, that is the socket of every
07091          zt_pvt that does not have an associated owner channel */
07092       count = 0;
07093       i = iflist;
07094       while (i) {
07095          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
07096             if (!i->owner && !i->subs[SUB_REAL].owner) {
07097                /* This needs to be watched, as it lacks an owner */
07098                pfds[count].fd = i->subs[SUB_REAL].zfd;
07099                pfds[count].events = POLLPRI;
07100                pfds[count].revents = 0;
07101                /* Message waiting or r2 channels also get watched for reading */
07102                if (i->cidspill)
07103                   pfds[count].events |= POLLIN;
07104                count++;
07105             }
07106          }
07107          i = i->next;
07108       }
07109       /* Okay, now that we know what to do, release the interface lock */
07110       ast_mutex_unlock(&iflock);
07111       
07112       pthread_testcancel();
07113       /* Wait at least a second for something to happen */
07114       res = poll(pfds, count, 1000);
07115       pthread_testcancel();
07116       /* Okay, poll has finished.  Let's see what happened.  */
07117       if (res < 0) {
07118          if ((errno != EAGAIN) && (errno != EINTR))
07119             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
07120          continue;
07121       }
07122       /* Alright, lock the interface list again, and let's look and see what has
07123          happened */
07124       ast_mutex_lock(&iflock);
07125       found = 0;
07126       spoint = 0;
07127       lastpass = thispass;
07128       thispass = time(NULL);
07129       i = iflist;
07130       while (i) {
07131          if (thispass != lastpass) {
07132             if (!found && ((i == last) || ((i == iflist) && !last))) {
07133                last = i;
07134                if (last) {
07135                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
07136                      (last->sig & __ZT_SIG_FXO)) {
07137                      res = ast_app_has_voicemail(last->mailbox, NULL);
07138                      if (last->msgstate != res) {
07139                         int x;
07140                         if (option_debug)
07141                            ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
07142                         x = ZT_FLUSH_BOTH;
07143                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
07144                         if (res2)
07145                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
07146                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
07147                            /* Turn on on hook transfer for 4 seconds */
07148                            x = 4000;
07149                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
07150                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
07151                            last->cidpos = 0;
07152                            last->msgstate = res;
07153                            last->onhooktime = thispass;
07154                         }
07155                         found ++;
07156                      }
07157                   }
07158                   last = last->next;
07159                }
07160             }
07161          }
07162          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
07163             if (i->radio && !i->owner)
07164             {
07165                res = zt_get_event(i->subs[SUB_REAL].zfd);
07166                if (res)
07167                {
07168                   if (option_debug)
07169                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
07170                   /* Don't hold iflock while handling init events */
07171                   ast_mutex_unlock(&iflock);
07172                   handle_init_event(i, res);
07173                   ast_mutex_lock(&iflock);   
07174                }
07175                i = i->next;
07176                continue;
07177             }              
07178             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
07179             if (pollres & POLLIN) {
07180                if (i->owner || i->subs[SUB_REAL].owner) {
07181 #ifdef HAVE_PRI
07182                   if (!i->pri)
07183 #endif                  
07184                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
07185                   i = i->next;
07186                   continue;
07187                }
07188                if (!i->cidspill) {
07189                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
07190                   i = i->next;
07191                   continue;
07192                }
07193                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
07194                if (res > 0) {
07195                   /* We read some number of bytes.  Write an equal amount of data */
07196                   if (res > i->cidlen - i->cidpos) 
07197                      res = i->cidlen - i->cidpos;
07198                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
07199                   if (res2 > 0) {
07200                      i->cidpos += res2;
07201                      if (i->cidpos >= i->cidlen) {
07202                         free(i->cidspill);
07203                         i->cidspill = 0;
07204                         i->cidpos = 0;
07205                         i->cidlen = 0;
07206                      }
07207                   } else {
07208                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
07209                      i->msgstate = -1;
07210                   }
07211                } else {
07212                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
07213                }
07214                if (option_debug)
07215                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07216                /* Don't hold iflock while handling init events -- race with chlock */
07217                ast_mutex_unlock(&iflock);
07218                handle_init_event(i, res);
07219                ast_mutex_lock(&iflock);   
07220             }
07221             if (pollres & POLLPRI) {
07222                if (i->owner || i->subs[SUB_REAL].owner) {
07223 #ifdef HAVE_PRI
07224                   if (!i->pri)
07225 #endif                  
07226                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
07227                   i = i->next;
07228                   continue;
07229                }
07230                res = zt_get_event(i->subs[SUB_REAL].zfd);
07231                if (option_debug)
07232                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07233                /* Don't hold iflock while handling init events */
07234                ast_mutex_unlock(&iflock);
07235                handle_init_event(i, res);
07236                ast_mutex_lock(&iflock);   
07237             }
07238          }
07239          i=i->next;
07240       }
07241       ast_mutex_unlock(&iflock);
07242    }
07243    /* Never reached */
07244    return NULL;
07245    
07246 }

static void enable_dtmf_detect struct zt_pvt p  )  [static]
 

Definition at line 3346 of file chan_zap.c.

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

03347 {
03348 #ifdef ZT_TONEDETECT
03349    int val;
03350 #endif
03351 
03352    if (p->channel == CHAN_PSEUDO)
03353       return;
03354 
03355    p->ignoredtmf = 0;
03356 
03357 #ifdef ZT_TONEDETECT
03358    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03359    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03360 #endif      
03361    if (!p->hardwaredtmf && p->dsp) {
03362       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03363       ast_dsp_set_features(p->dsp, p->dsp_features);
03364    }
03365 }

static char* event2str int  event  )  [static]
 

Definition at line 1255 of file chan_zap.c.

References events.

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

01256 {
01257    static char buf[256];
01258    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01259       return events[event];
01260    sprintf(buf, "Event %d", event); /* safe */
01261    return buf;
01262 }

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

Definition at line 1633 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_rxgain().

01634 {
01635    int j;
01636    int k;
01637    float linear_gain = pow(10.0, gain / 20.0);
01638 
01639    switch (law) {
01640    case ZT_LAW_ALAW:
01641       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01642          if (gain) {
01643             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01644             if (k > 32767) k = 32767;
01645             if (k < -32767) k = -32767;
01646             g->rxgain[j] = AST_LIN2A(k);
01647          } else {
01648             g->rxgain[j] = j;
01649          }
01650       }
01651       break;
01652    case ZT_LAW_MULAW:
01653       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01654          if (gain) {
01655             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01656             if (k > 32767) k = 32767;
01657             if (k < -32767) k = -32767;
01658             g->rxgain[j] = AST_LIN2MU(k);
01659          } else {
01660             g->rxgain[j] = j;
01661          }
01662       }
01663       break;
01664    }
01665 }

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

Definition at line 1599 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_txgain().

01600 {
01601    int j;
01602    int k;
01603    float linear_gain = pow(10.0, gain / 20.0);
01604 
01605    switch (law) {
01606    case ZT_LAW_ALAW:
01607       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01608          if (gain) {
01609             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01610             if (k > 32767) k = 32767;
01611             if (k < -32767) k = -32767;
01612             g->txgain[j] = AST_LIN2A(k);
01613          } else {
01614             g->txgain[j] = j;
01615          }
01616       }
01617       break;
01618    case ZT_LAW_MULAW:
01619       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01620          if (gain) {
01621             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01622             if (k > 32767) k = 32767;
01623             if (k < -32767) k = -32767;
01624             g->txgain[j] = AST_LIN2MU(k);
01625          } else {
01626             g->txgain[j] = j;
01627          }
01628       }
01629       break;
01630    }
01631 }

static struct zt_pvt* find_channel int  channel  )  [static]
 

Definition at line 11044 of file chan_zap.c.

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

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

11045 {
11046    struct zt_pvt *p = iflist;
11047    while (p) {
11048       if (p->channel == channel) {
11049          break;
11050       }
11051       p = p->next;
11052    }
11053    return p;
11054 }

static int get_alarms struct zt_pvt p  )  [static]
 

Definition at line 3816 of file chan_zap.c.

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

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

03817 {
03818    int res;
03819    ZT_SPANINFO zi;
03820    memset(&zi, 0, sizeof(zi));
03821    zi.spanno = p->span;
03822    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03823    if (res < 0) {
03824       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03825       return 0;
03826    }
03827    return zi.alarms;
03828 }

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

Definition at line 6861 of file chan_zap.c.

References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, EVENT_FLAG_SYSTEM, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, manager_event, zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, 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, SIG_SS7, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().

06862 {
06863    int res;
06864    pthread_t threadid;
06865    pthread_attr_t attr;
06866    struct ast_channel *chan;
06867    pthread_attr_init(&attr);
06868    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06869    /* Handle an event on a given channel for the monitor thread. */
06870    switch (event) {
06871    case ZT_EVENT_NONE:
06872    case ZT_EVENT_BITSCHANGED:
06873       break;
06874    case ZT_EVENT_WINKFLASH:
06875    case ZT_EVENT_RINGOFFHOOK:
06876       if (i->inalarm) break;
06877       if (i->radio) break;
06878       /* Got a ring/answer.  What kind of channel are we? */
06879       switch (i->sig) {
06880       case SIG_FXOLS:
06881       case SIG_FXOGS:
06882       case SIG_FXOKS:
06883          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06884          if (res && (errno == EBUSY))
06885             break;
06886          if (i->cidspill) {
06887             /* Cancel VMWI spill */
06888             free(i->cidspill);
06889             i->cidspill = NULL;
06890          }
06891          if (i->immediate) {
06892             zt_enable_ec(i);
06893             /* The channel is immediately up.  Start right away */
06894             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06895             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06896             if (!chan) {
06897                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06898                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06899                if (res < 0)
06900                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06901             }
06902          } else {
06903             /* Check for callerid, digits, etc */
06904             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06905             if (chan) {
06906                if (has_voicemail(i))
06907                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06908                else
06909                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06910                if (res < 0) 
06911                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
06912                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06913                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06914                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06915                   if (res < 0)
06916                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06917                   ast_hangup(chan);
06918                }
06919             } else
06920                ast_log(LOG_WARNING, "Unable to create channel\n");
06921          }
06922          break;
06923       case SIG_FXSLS:
06924       case SIG_FXSGS:
06925       case SIG_FXSKS:
06926             i->ringt = i->ringt_base;
06927             /* Fall through */
06928       case SIG_EMWINK:
06929       case SIG_FEATD:
06930       case SIG_FEATDMF:
06931       case SIG_FEATDMF_TA:
06932       case SIG_E911:
06933       case SIG_FGC_CAMA:
06934       case SIG_FGC_CAMAMF:
06935       case SIG_FEATB:
06936       case SIG_EM:
06937       case SIG_EM_E1:
06938       case SIG_SFWINK:
06939       case SIG_SF_FEATD:
06940       case SIG_SF_FEATDMF:
06941       case SIG_SF_FEATB:
06942       case SIG_SF:
06943             /* Check for callerid, digits, etc */
06944             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06945             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06946                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06947                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06948                if (res < 0)
06949                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06950                ast_hangup(chan);
06951             } else if (!chan) {
06952                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06953             }
06954             break;
06955       default:
06956          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06957          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06958          if (res < 0)
06959                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06960          return -1;
06961       }
06962       break;
06963    case ZT_EVENT_NOALARM:
06964       i->inalarm = 0;
06965       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06966       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06967          "Channel: %d\r\n", i->channel);
06968       break;
06969    case ZT_EVENT_ALARM:
06970       i->inalarm = 1;
06971       res = get_alarms(i);
06972       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06973       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06974          "Alarm: %s\r\n"
06975          "Channel: %d\r\n",
06976          alarm2str(res), i->channel);
06977       /* fall thru intentionally */
06978    case ZT_EVENT_ONHOOK:
06979       if (i->radio)
06980          break;
06981       /* Back on hook.  Hang up. */
06982       switch (i->sig) {
06983       case SIG_FXOLS:
06984       case SIG_FXOGS:
06985       case SIG_FEATD:
06986       case SIG_FEATDMF:
06987       case SIG_FEATDMF_TA:
06988       case SIG_E911:
06989       case SIG_FGC_CAMA:
06990       case SIG_FGC_CAMAMF:
06991       case SIG_FEATB:
06992       case SIG_EM:
06993       case SIG_EM_E1:
06994       case SIG_EMWINK:
06995       case SIG_SF_FEATD:
06996       case SIG_SF_FEATDMF:
06997       case SIG_SF_FEATB:
06998       case SIG_SF:
06999       case SIG_SFWINK:
07000       case SIG_FXSLS:
07001       case SIG_FXSGS:
07002       case SIG_FXSKS:
07003       case SIG_GR303FXSKS:
07004          zt_disable_ec(i);
07005          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07006          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
07007          break;
07008       case SIG_GR303FXOKS:
07009       case SIG_FXOKS:
07010          zt_disable_ec(i);
07011          /* Diddle the battery for the zhone */
07012 #ifdef ZHONE_HACK
07013          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
07014          usleep(1);
07015 #endif         
07016          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07017          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
07018          break;
07019       case SIG_PRI:
07020       case SIG_SS7:
07021          zt_disable_ec(i);
07022          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07023          break;
07024       default:
07025          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
07026          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07027          return -1;
07028       }
07029       break;
07030    case ZT_EVENT_POLARITY:
07031       switch (i->sig) {
07032       case SIG_FXSLS:
07033       case SIG_FXSKS:
07034       case SIG_FXSGS:
07035          if (i->cid_start == CID_START_POLARITY) {
07036             i->polarity = POLARITY_REV;
07037             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
07038                    "CID detection on channel %d\n",
07039                    i->channel);
07040             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
07041             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
07042                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
07043             }
07044          }
07045          break;
07046       default:
07047          ast_log(LOG_WARNING, "handle_init_event detected "
07048             "polarity reversal on non-FXO (SIG_FXS) "
07049             "interface %d\n", i->channel);
07050       }
07051    }
07052    return 0;
07053 }

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

Definition at line 10888 of file chan_zap.c.

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

10889 {
10890    int i, j;
10891    for (i = 0; i < num_cadence; i++) {
10892       char output[1024];
10893       char tmp[16], tmp2[64];
10894       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
10895       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
10896 
10897       for (j = 0; j < 16; j++) {
10898          if (cadences[i].ringcadence[j] == 0)
10899             break;
10900          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
10901          if (cidrings[i] * 2 - 1 == j)
10902             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
10903          else
10904             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
10905          if (j != 0)
10906             strncat(output, ",", sizeof(output) - strlen(output) - 1);
10907          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
10908       }
10909       ast_cli(fd,"%s\n",output);
10910    }
10911    return 0;
10912 }

static int has_voicemail struct zt_pvt p  )  [static]
 

Definition at line 1828 of file chan_zap.c.

References ast_app_has_voicemail(), and zt_pvt::mailbox.

01829 {
01830 
01831    return ast_app_has_voicemail(p->mailbox, NULL);
01832 }

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

Definition at line 1377 of file chan_zap.c.

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

Referenced by conf_del().

01378 {
01379    /* If they're listening to our channel, they're ours */  
01380    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01381       return 1;
01382    /* If they're a talker on our (allocated) conference, they're ours */
01383    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01384       return 1;
01385    return 0;
01386 }

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

Definition at line 1411 of file chan_zap.c.

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

Referenced by update_conf().

01412 {
01413    int x;
01414    int useslavenative;
01415    struct zt_pvt *slave = NULL;
01416    /* Start out optimistic */
01417    useslavenative = 1;
01418    /* Update conference state in a stateless fashion */
01419    for (x = 0; x < 3; x++) {
01420       /* Any three-way calling makes slave native mode *definitely* out
01421          of the question */
01422       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01423          useslavenative = 0;
01424    }
01425    /* If we don't have any 3-way calls, check to see if we have
01426       precisely one slave */
01427    if (useslavenative) {
01428       for (x = 0; x < MAX_SLAVES; x++) {
01429          if (p->slaves[x]) {
01430             if (slave) {
01431                /* Whoops already have a slave!  No 
01432                   slave native and stop right away */
01433                slave = NULL;
01434                useslavenative = 0;
01435                break;
01436             } else {
01437                /* We have one slave so far */
01438                slave = p->slaves[x];
01439             }
01440          }
01441       }
01442    }
01443    /* If no slave, slave native definitely out */
01444    if (!slave)
01445       useslavenative = 0;
01446    else if (slave->law != p->law) {
01447       useslavenative = 0;
01448       slave = NULL;
01449    }
01450    if (out)
01451       *out = slave;
01452    return useslavenative;
01453 }

static int load_module void   )  [static]
 

Definition at line 12588 of file chan_zap.c.

References ast_mutex_init(), AST_PTHREADT_NULL, and lock.

12589 {
12590    int res;
12591 #if defined(HAVE_PRI) || defined(HAVE_SS7)
12592    int y, i;
12593 #endif
12594 
12595 #ifdef HAVE_PRI
12596    memset(pris, 0, sizeof(pris));
12597    for (y = 0; y < NUM_SPANS; y++) {
12598       ast_mutex_init(&pris[y].lock);
12599       pris[y].offset = -1;
12600       pris[y].master = AST_PTHREADT_NULL;
12601       for (i = 0; i < NUM_DCHANS; i++)
12602          pris[y].fds[i] = -1;
12603    }
12604    pri_set_error(zt_pri_error);
12605    pri_set_message(zt_pri_message);
12606    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
12607          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
12608 #endif
12609 #ifdef HAVE_SS7
12610    memset(linksets, 0, sizeof(linksets));
12611    for (y = 0; y < NUM_SPANS; y++) {
12612       ast_mutex_init(&linksets[y].lock);
12613       linksets[y].master = AST_PTHREADT_NULL;
12614       for (i = 0; i < NUM_DCHANS; i++)
12615          linksets[y].fds[i] = -1;
12616    }
12617    ss7_set_error(zt_ss7_error);
12618    ss7_set_message(zt_ss7_message);
12619 #endif /* HAVE_SS7 */
12620    res = setup_zap(0);
12621    /* Make sure we can register our Zap channel type */
12622    if (res)
12623       return AST_MODULE_LOAD_DECLINE;
12624    if (ast_channel_register(&zap_tech)) {
12625       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
12626       __unload_module();
12627       return -1;
12628    }
12629 #ifdef HAVE_PRI
12630    ast_string_field_init(&inuse, 16);
12631    ast_string_field_set(&inuse, name, "GR-303InUse");
12632    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
12633 #endif   
12634 #ifdef HAVE_SS7
12635    ast_cli_register_multiple(zap_ss7_cli, sizeof(zap_ss7_cli) / sizeof(zap_ss7_cli[0]));
12636 #endif
12637 
12638    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
12639    
12640    memset(round_robin, 0, sizeof(round_robin));
12641    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
12642    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
12643    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
12644    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
12645    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
12646    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
12647    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
12648 
12649    return res;
12650 }

static struct zt_pvt* mkintf int  channel,
struct zt_chan_conf  conf,
struct zt_pri *  pri,
int  reloading
[static]
 

Definition at line 7423 of file chan_zap.c.

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

07424 {
07425    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07426    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07427    char fn[80];
07428 #if 1
07429    struct zt_bufferinfo bi;
07430 #endif
07431    struct zt_spaninfo si;
07432    int res;
07433    int span=0;
07434    int here = 0;
07435    int x;
07436    struct zt_pvt **wlist;
07437    struct zt_pvt **wend;
07438    ZT_PARAMS p;
07439 
07440    wlist = &iflist;
07441    wend = &ifend;
07442 
07443 #ifdef HAVE_PRI
07444    if (pri) {
07445       wlist = &pri->crvs;
07446       wend = &pri->crvend;
07447    }
07448 #endif
07449 
07450    tmp2 = *wlist;
07451    prev = NULL;
07452 
07453    while (tmp2) {
07454       if (!tmp2->destroy) {
07455          if (tmp2->channel == channel) {
07456             tmp = tmp2;
07457             here = 1;
07458             break;
07459          }
07460          if (tmp2->channel > channel) {
07461             break;
07462          }
07463       }
07464       prev = tmp2;
07465       tmp2 = tmp2->next;
07466    }
07467 
07468    if (!here && !reloading) {
07469       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07470          destroy_zt_pvt(&tmp);
07471          return NULL;
07472       }
07473       ast_mutex_init(&tmp->lock);
07474       ifcount++;
07475       for (x = 0; x < 3; x++)
07476          tmp->subs[x].zfd = -1;
07477       tmp->channel = channel;
07478    }
07479 
07480    if (tmp) {
07481       if (!here) {
07482          if ((channel != CHAN_PSEUDO) && !pri) {
07483             snprintf(fn, sizeof(fn), "%d", channel);
07484             /* Open non-blocking */
07485             if (!here)
07486                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07487             /* Allocate a zapata structure */
07488             if (tmp->subs[SUB_REAL].zfd < 0) {
07489                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);
07490                destroy_zt_pvt(&tmp);
07491                return NULL;
07492             }
07493             memset(&p, 0, sizeof(p));
07494             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07495             if (res < 0) {
07496                ast_log(LOG_ERROR, "Unable to get parameters\n");
07497                destroy_zt_pvt(&tmp);
07498                return NULL;
07499             }
07500             if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
07501                ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(conf.chan.sig), sig2str(p.sigtype));
07502                destroy_zt_pvt(&tmp);
07503                return NULL;
07504             }
07505             tmp->law = p.curlaw;
07506             tmp->span = p.spanno;
07507             span = p.spanno - 1;
07508          } else {
07509             if (channel == CHAN_PSEUDO)
07510                conf.chan.sig = 0;
07511             else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
07512                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07513                return NULL;
07514             }
07515          }
07516 #ifdef HAVE_SS7
07517          if (conf.chan.sig == SIG_SS7) {
07518             struct zt_ss7 *ss7;
07519             int clear = 0;
07520             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &clear)) {
07521                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07522                destroy_zt_pvt(&tmp);
07523                return NULL;
07524             }
07525 
07526             ss7 = ss7_resolve_linkset(cur_linkset);
07527             if (!ss7) {
07528                ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset);
07529                destroy_zt_pvt(&tmp);
07530                return NULL;
07531             }
07532             if (cur_cicbeginswith < 0) {
07533                ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n");
07534                destroy_zt_pvt(&tmp);
07535                return NULL;
07536             }
07537 
07538             tmp->cic = cur_cicbeginswith++;
07539 
07540             tmp->ss7 = ss7;
07541             tmp->ss7call = NULL;
07542             ss7->pvts[ss7->numchans++] = tmp;
07543          }
07544 #endif
07545 #ifdef HAVE_PRI
07546          if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
07547             int offset;
07548             int myswitchtype;
07549             int matchesdchan;
07550             int x,y;
07551             offset = 0;
07552             if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07553                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07554                destroy_zt_pvt(&tmp);
07555                return NULL;
07556             }
07557             if (span >= NUM_SPANS) {
07558                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07559                destroy_zt_pvt(&tmp);
07560                return NULL;
07561             } else {
07562                si.spanno = 0;
07563                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07564                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07565                   destroy_zt_pvt(&tmp);
07566                   return NULL;
07567                }
07568                /* Store the logical span first based upon the real span */
07569                tmp->logicalspan = pris[span].prilogicalspan;
07570                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07571                if (span < 0) {
07572                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07573                   destroy_zt_pvt(&tmp);
07574                   return NULL;
07575                }
07576                if (conf.chan.sig == SIG_PRI)
07577                   myswitchtype = conf.pri.switchtype;
07578                else
07579                   myswitchtype = PRI_SWITCH_GR303_TMC;
07580                /* Make sure this isn't a d-channel */
07581                matchesdchan=0;
07582                for (x = 0; x < NUM_SPANS; x++) {
07583                   for (y = 0; y < NUM_DCHANS; y++) {
07584                      if (pris[x].dchannels[y] == tmp->channel) {
07585                         matchesdchan = 1;
07586                         break;
07587                      }
07588                   }
07589                }
07590                offset = p.chanpos;
07591                if (!matchesdchan) {
07592                   if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
07593                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07594                      destroy_zt_pvt(&tmp);
07595                      return NULL;
07596                   }
07597                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07598                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07599                      destroy_zt_pvt(&tmp);
07600                      return NULL;
07601                   }
07602                   if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
07603                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07604                      destroy_zt_pvt(&tmp);
07605                      return NULL;
07606                   }
07607                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
07608                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
07609                      destroy_zt_pvt(&tmp);
07610                      return NULL;
07611                   }
07612                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
07613                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
07614                      destroy_zt_pvt(&tmp);
07615                      return NULL;
07616                   }
07617                   if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
07618                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
07619                      destroy_zt_pvt(&tmp);
07620                      return NULL;
07621                   }
07622                   if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
07623                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
07624                      destroy_zt_pvt(&tmp);
07625                      return NULL;
07626                   }
07627                   if (pris[span].numchans >= MAX_CHANNELS) {
07628                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07629                         pris[span].trunkgroup);
07630                      destroy_zt_pvt(&tmp);
07631                      return NULL;
07632                   }
07633                   pris[span].nodetype = conf.pri.nodetype;
07634                   pris[span].switchtype = myswitchtype;
07635                   pris[span].nsf = conf.pri.nsf;
07636                   pris[span].dialplan = conf.pri.dialplan;
07637                   pris[span].localdialplan = conf.pri.localdialplan;
07638                   pris[span].pvts[pris[span].numchans++] = tmp;
07639                   pris[span].minunused = conf.pri.minunused;
07640                   pris[span].minidle = conf.pri.minidle;
07641                   pris[span].overlapdial = conf.pri.overlapdial;
07642                   pris[span].facilityenable = conf.pri.facilityenable;
07643                   ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
07644                   ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
07645                   ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
07646                   ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
07647                   ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
07648                   ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
07649                   ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
07650                   pris[span].resetinterval = conf.pri.resetinterval;
07651                   
07652                   tmp->pri = &pris[span];
07653                   tmp->prioffset = offset;
07654                   tmp->call = NULL;
07655                } else {
07656                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07657                   destroy_zt_pvt(&tmp);
07658                   return NULL;
07659                }
07660             }
07661          } else {
07662             tmp->prioffset = 0;
07663          }
07664 #endif
07665       } else {
07666          conf.chan.sig = tmp->sig;
07667          conf.chan.radio = tmp->radio;
07668          memset(&p, 0, sizeof(p));
07669          if (tmp->subs[SUB_REAL].zfd > -1)
07670             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07671       }
07672       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07673       if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
07674           (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) ||  (conf.chan.sig == SIG_EMWINK) ||
07675          (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
07676            (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
07677           (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
07678          (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
07679            (conf.chan.sig == SIG_SF_FEATB)) {
07680          p.starttime = 250;
07681       }
07682       if (conf.chan.radio) {
07683          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07684          p.channo = channel;
07685          p.rxwinktime = 1;
07686          p.rxflashtime = 1;
07687          p.starttime = 1;
07688          p.debouncetime = 5;
07689       }
07690       if (!conf.chan.radio) {
07691          p.channo = channel;
07692          /* Override timing settings based on config file */
07693          if (conf.timing.prewinktime >= 0)
07694             p.prewinktime = conf.timing.prewinktime;
07695          if (conf.timing.preflashtime >= 0)
07696             p.preflashtime = conf.timing.preflashtime;
07697          if (conf.timing.winktime >= 0)
07698             p.winktime = conf.timing.winktime;
07699          if (conf.timing.flashtime >= 0)
07700             p.flashtime = conf.timing.flashtime;
07701          if (conf.timing.starttime >= 0)
07702             p.starttime = conf.timing.starttime;
07703          if (conf.timing.rxwinktime >= 0)
07704             p.rxwinktime = conf.timing.rxwinktime;
07705          if (conf.timing.rxflashtime >= 0)
07706             p.rxflashtime = conf.timing.rxflashtime;
07707          if (conf.timing.debouncetime >= 0)
07708             p.debouncetime = conf.timing.debouncetime;
07709       }
07710       
07711       /* dont set parms on a pseudo-channel (or CRV) */
07712       if (tmp->subs[SUB_REAL].zfd >= 0)
07713       {
07714          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07715          if (res < 0) {
07716             ast_log(LOG_ERROR, "Unable to set parameters\n");
07717             destroy_zt_pvt(&tmp);
07718             return NULL;
07719          }
07720       }
07721 #if 1
07722       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07723          memset(&bi, 0, sizeof(bi));
07724          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07725          if (!res) {
07726             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07727             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07728             bi.numbufs = numbufs;
07729             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07730             if (res < 0) {
07731                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07732             }
07733          } else
07734             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07735       }
07736 #endif
07737       tmp->immediate = conf.chan.immediate;
07738       tmp->transfertobusy = conf.chan.transfertobusy;
07739       tmp->sig = conf.chan.sig;
07740       tmp->outsigmod = conf.chan.outsigmod;
07741       tmp->radio = conf.chan.radio;
07742       tmp->ringt_base = ringt_base;
07743       tmp->firstradio = 0;
07744       if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
07745          tmp->permcallwaiting = conf.chan.callwaiting;
07746       else
07747          tmp->permcallwaiting = 0;
07748       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07749       tmp->destroy = 0;
07750       tmp->drings = drings;
07751       tmp->usedistinctiveringdetection = usedistinctiveringdetection;
07752       tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
07753       tmp->threewaycalling = conf.chan.threewaycalling;
07754       tmp->adsi = conf.chan.adsi;
07755       tmp->use_smdi = conf.chan.use_smdi;
07756       tmp->permhidecallerid = conf.chan.hidecallerid;
07757       tmp->callreturn = conf.chan.callreturn;
07758       tmp->echocancel = conf.chan.echocancel;
07759       tmp->echotraining = conf.chan.echotraining;
07760       tmp->pulse = conf.chan.pulse;
07761       tmp->echocanbridged = conf.chan.echocanbridged;
07762       tmp->busydetect = conf.chan.busydetect;
07763       tmp->busycount = conf.chan.busycount;
07764       tmp->busy_tonelength = conf.chan.busy_tonelength;
07765       tmp->busy_quietlength = conf.chan.busy_quietlength;
07766       tmp->callprogress = conf.chan.callprogress;
07767       tmp->cancallforward = conf.chan.cancallforward;
07768       tmp->dtmfrelax = conf.chan.dtmfrelax;
07769       tmp->callwaiting = tmp->permcallwaiting;
07770       tmp->hidecallerid = tmp->permhidecallerid;
07771       tmp->channel = channel;
07772       tmp->stripmsd = conf.chan.stripmsd;
07773       tmp->use_callerid = conf.chan.use_callerid;
07774       tmp->cid_signalling = conf.chan.cid_signalling;
07775       tmp->cid_start = conf.chan.cid_start;
07776       tmp->zaptrcallerid = conf.chan.zaptrcallerid;
07777       tmp->restrictcid = conf.chan.restrictcid;
07778       tmp->use_callingpres = conf.chan.use_callingpres;
07779       tmp->priindication_oob = conf.chan.priindication_oob;
07780       tmp->priexclusive = conf.chan.priexclusive;
07781       if (tmp->usedistinctiveringdetection) {
07782          if (!tmp->use_callerid) {
07783             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07784             tmp->use_callerid = 1;
07785          }
07786       }
07787 
07788       if (tmp->cid_signalling == CID_SIG_SMDI) {
07789          if (!tmp->use_smdi) {
07790             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07791             tmp->use_smdi = 1;
07792          }
07793       }
07794       if (tmp->use_smdi) {
07795          tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
07796          if (!(tmp->smdi_iface)) {
07797             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07798             tmp->use_smdi = 0;
07799          }
07800       }
07801 
07802       ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
07803       tmp->amaflags = conf.chan.amaflags;
07804       if (!here) {
07805          tmp->confno = -1;
07806          tmp->propconfno = -1;
07807       }
07808       tmp->canpark = conf.chan.canpark;
07809       tmp->transfer = conf.chan.transfer;
07810       ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
07811       ast_copy_string(tmp->language, language, sizeof(tmp->language));
07812       ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
07813       ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
07814       ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
07815       ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
07816       tmp->cid_ton = 0;
07817       ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
07818       ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
07819       tmp->msgstate = -1;
07820       tmp->group = conf.chan.group;
07821       tmp->callgroup = conf.chan.callgroup;
07822       tmp->pickupgroup= conf.chan.pickupgroup;
07823       tmp->rxgain = conf.chan.rxgain;
07824       tmp->txgain = conf.chan.txgain;
07825       tmp->tonezone = conf.chan.tonezone;
07826       tmp->onhooktime = time(NULL);
07827       if (tmp->subs[SUB_REAL].zfd > -1) {
07828          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07829          if (tmp->dsp)
07830             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07831          update_conf(tmp);
07832          if (!here) {
07833             if ((conf.chan.sig != SIG_PRI) && (conf.chan.sig != SIG_SS7))
07834                /* Hang it up to be sure it's good */
07835                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07836          }
07837          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07838 #ifdef HAVE_PRI
07839          /* the dchannel is down so put the channel in alarm */
07840          if (tmp->pri && !pri_is_up(tmp->pri))
07841             tmp->inalarm = 1;
07842          else
07843             tmp->inalarm = 0;
07844 #endif            
07845          memset(&si, 0, sizeof(si));
07846          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07847             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));