Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:38 2009

## Asterisk developer's documentation

# chan_zap.c File Reference

Zaptel Pseudo TDM interface. More...

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

Include dependency graph for chan_zap.c:

Go to the source code of this file.

## Data Structures

struct | distRingData
struct | ringContextData
struct | zt_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_pri_conf
| The PRI part of the channel configuration. Separated as it is is applied to the span rather than to the channel. More...
struct | zt_pvt
struct | zt_subchannel

## Defines

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

## Functions

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

## Variables

struct {
int alarm
char * name
} | 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 char | defaultcic [64] = ""
static char | defaultozz [64] = ""
static const char | desc [] = "Zapata Telephony"
static char | destroy_channel_usage []
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 int | ifcount = 0
static struct zt_pvt * | ifend
static struct zt_pvt * | iflist
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
struct zt_pvt * | round_robin [32]
static char | show_channel_usage []
static char | show_channels_usage []
static char * | subnames []
static const char | tdesc [] = "Zapata Telephony Driver"
static const char | type [] = "Zap"
static int | usecnt = 0
static int | usedistinctiveringdetection = 0
static int | user_has_defined_cadences = 0
static struct ast_cli_entry | zap_cli []
static char | zap_show_cadences_help []
static char | zap_show_status_usage []
static struct ast_channel_tech | zap_tech

## Detailed Description

Zaptel Pseudo TDM interface.

Connects to the zaptel telephony library as well as libpri. Libpri is optional and needed only if you are going to use ISDN connections.

You need to install libraries before you attempt to compile and install the zaptel channel.

See also
  - Zaptel configuration

Definition in file chan_zap.c.

## Define Documentation

#define ASCII_BYTES_PER_CHAR 80

Referenced by zt_sendtext().

#define AST_LAW | ( | p |  | ) | (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)

Definition at line 136 of file chan_zap.c.

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

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

300 ms

Definition at line 278 of file chan_zap.c.

Referenced by zt_callwait().

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

300 ms

Definition at line 277 of file chan_zap.c.

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

Definition at line 928 of file chan_zap.c.

Referenced by zt_new().

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

Definition at line 929 of file chan_zap.c.

Referenced by zt_handle_event(), and zt_new().

#define CHAN_PSEUDO -2

Definition at line 190 of file chan_zap.c.

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

#define CHANNEL_PSEUDO -12

Definition at line 134 of file chan_zap.c.

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

500 ms

Definition at line 279 of file chan_zap.c.

Referenced by send_callerid().

#define CONF_USER_REAL (1 << 0)

Definition at line 411 of file chan_zap.c.

#define CONF_USER_THIRDCALL (1 << 1)

Definition at line 412 of file chan_zap.c.

#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)

Definition at line 196 of file chan_zap.c.

#define DCHAN_NOTINALARM (1 << 1)

Definition at line 193 of file chan_zap.c.

#define DCHAN_PROVISIONED (1 << 0)

Definition at line 192 of file chan_zap.c.

#define DCHAN_UP (1 << 2)

Definition at line 194 of file chan_zap.c.

#define DEFAULT_CIDRINGS 1

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

Note:
  Define ZHONE_HACK to cause us to go off hook and then back on hook when the user hangs up to reset the state machine so ring works properly. This is used to be able to support kewlstart by putting the zhone in groundstart mode since their forward disconnect supervision is entirely broken even though their documentation says it isn't and their support is entirely unwilling to provide any assistance with their channel banks even though their web site says they support their products for life.

  Define if you want to check the hook state for an FXO (FXS signalled) interface before dialing on it. Certain FXO interfaces always think they're out of service with this method however.

Definition at line 132 of file chan_zap.c.

Referenced by zt_chan_conf_default().

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

Definition at line 281 of file chan_zap.c.

#define END_SILENCE_LEN 400

Referenced by zt_sendtext().

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

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

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

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

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

Definition at line 878 of file chan_zap.c.

Referenced by update_conf().

#define HANGUP 1

Definition at line 10040 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 | ( | p |  | ) |

Value:

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

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

#define MASK_INUSE (1 << 1)

Channel currently in use

Definition at line 275 of file chan_zap.c.

#define MAX_CHANNELS 672

No more than a DS3 per trunk group

Definition at line 188 of file chan_zap.c.

Referenced by mkintf().

#define MAX_SLAVES 4

Definition at line 414 of file chan_zap.c.

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

#define MIN_MS_SINCE_FLASH ( (2000) )

2000 ms

Definition at line 280 of file chan_zap.c.

Referenced by zt_handle_event().

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

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

Definition at line 139 of file chan_zap.c.

Referenced by ss_thread(), and zt_new().

#define NUM_CADENCE_MAX 25

Definition at line 903 of file chan_zap.c.

Referenced by setup_zap().

#define NUM_DCHANS 4

No more than 4 d-channels

Definition at line 187 of file chan_zap.c.

#define NUM_SPANS 32

Definition at line 186 of file chan_zap.c.

#define POLARITY_IDLE 0

Definition at line 371 of file chan_zap.c.

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

#define POLARITY_REV 1

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

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

#define sig2str zap_sig2str

Definition at line 1341 of file chan_zap.c.

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

#define SIG_E911 (0x1000000 | ZT_SIG_EM)

Definition at line 167 of file chan_zap.c.

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

#define SIG_EM ZT_SIG_EM

Definition at line 162 of file chan_zap.c.

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

#define SIG_EM_E1 ZT_SIG_EM_E1

Definition at line 182 of file chan_zap.c.

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

#define SIG_EMWINK (0x0100000 | ZT_SIG_EM)

Definition at line 163 of file chan_zap.c.

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

#define SIG_FEATB (0x0800000 | ZT_SIG_EM)

Definition at line 166 of file chan_zap.c.

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

#define SIG_FEATD (0x0200000 | ZT_SIG_EM)

Definition at line 164 of file chan_zap.c.

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

#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM)

Definition at line 165 of file chan_zap.c.

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

#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)

Definition at line 168 of file chan_zap.c.

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

#define SIG_FXOGS ZT_SIG_FXOGS

Definition at line 173 of file chan_zap.c.

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

#define SIG_FXOKS ZT_SIG_FXOKS

Definition at line 174 of file chan_zap.c.

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

#define SIG_FXOLS ZT_SIG_FXOLS

Definition at line 172 of file chan_zap.c.

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

#define SIG_FXSGS ZT_SIG_FXSGS

Definition at line 170 of file chan_zap.c.

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

#define SIG_FXSKS ZT_SIG_FXSKS

Definition at line 171 of file chan_zap.c.

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

#define SIG_FXSLS ZT_SIG_FXSLS

Definition at line 169 of file chan_zap.c.

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

#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS)

Definition at line 183 of file chan_zap.c.

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

#define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS)

Definition at line 184 of file chan_zap.c.

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

#define SIG_PRI ZT_SIG_CLEAR

Definition at line 175 of file chan_zap.c.

Referenced by handle_init_event(), mkintf(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().

#define SIG_R2 ZT_SIG_CAS

Definition at line 176 of file chan_zap.c.

Referenced by mkintf(), setup_zap(), zap_sig2str(), zt_answer(), zt_handle_event(), and zt_hangup().

#define SIG_SF ZT_SIG_SF

Definition at line 177 of file chan_zap.c.

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

#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF)

Definition at line 181 of file chan_zap.c.

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

#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)

Definition at line 179 of file chan_zap.c.

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

#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)

Definition at line 180 of file chan_zap.c.

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

#define SIG_SFWINK (0x0100000 | ZT_SIG_SF)

Definition at line 178 of file chan_zap.c.

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

#define SUB_CALLWAIT 1

Call-Waiting call on hold

Definition at line 367 of file chan_zap.c.

#define SUB_REAL 0

Active call

Definition at line 366 of file chan_zap.c.

#define SUB_THREEWAY 2

Three-way call

Definition at line 368 of file chan_zap.c.

#define TRAILER_MS 5

Referenced by zt_sendtext().

#define TRANSFER 0

Definition at line 10039 of file chan_zap.c.

Referenced by action_transfer(), and zap_fake_event().

#define ZT_EVENT_DTMFDOWN 0

Definition at line 106 of file chan_zap.c.

Referenced by zt_handle_event().

#define ZT_EVENT_DTMFUP 0

Definition at line 107 of file chan_zap.c.

Referenced by zt_handle_event().

## Function Documentation

static int __unload_module | ( | void |  | ) | `[static]`

Definition at line 10216 of file chan_zap.c.

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

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

static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | `[static, read]`

Definition at line 4482 of file chan_zap.c.

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

Referenced by zt_exception(), and zt_read().

    04483 {
    04484    struct zt_pvt *p = ast->tech_pvt;
    04485    int res;
    04486    int usedindex=-1;
    04487    int index;
    04488    struct ast_frame *f;
    04489
    04490
    04491    index = zt_get_index(ast, p, 1);
    04492
    04493    p->subs[index].f.frametype = AST_FRAME_NULL;
    04494    p->subs[index].f.datalen = 0;
    04495    p->subs[index].f.samples = 0;
    04496    p->subs[index].f.mallocd = 0;
    04497    p->subs[index].f.offset = 0;
    04498    p->subs[index].f.subclass = 0;
    04499    p->subs[index].f.delivery = ast_tv(0,0);
    04500    p->subs[index].f.src = "zt_exception";
    04501    p->subs[index].f.data = NULL;
    04502
    04503
    04504    if ((!p->owner) && (!p->radio)) {
    04505       /* If nobody owns us, absorb the event appropriately, otherwise
    04506          we loop indefinitely.  This occurs when, during call waiting, the
    04507          other end hangs up our channel so that it no longer exists, but we
    04508          have neither FLASH'd nor ONHOOK'd to signify our desire to
    04509          change to the other channel. */
    04510       if (p->fake_event) {
    04511          res = p->fake_event;
    04512          p->fake_event = 0;
    04513       } else
    04514          res = zt_get_event(p->subs[SUB_REAL].zfd);
    04515       /* Switch to real if there is one and this isn't something really silly... */
    04516       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
    04517          (res != ZT_EVENT_HOOKCOMPLETE)) {
    04518          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
    04519          p->owner = p->subs[SUB_REAL].owner;
    04520          if (p->owner && ast_bridged_channel(p->owner))
    04521             ast_moh_stop(ast_bridged_channel(p->owner));
    04522       }
    04523       switch(res) {
    04524       case ZT_EVENT_ONHOOK:
    04525          zt_disable_ec(p);
    04526          if (p->owner) {
    04527             if (option_verbose > 2)
    04528                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
    04529             zt_ring_phone(p);
    04530             p->callwaitingrepeat = 0;
    04531             p->cidcwexpire = 0;
    04532          } else
    04533             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
    04534          update_conf(p);
    04535          break;
    04536       case ZT_EVENT_RINGOFFHOOK:
    04537          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
    04538          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
    04539             p->subs[SUB_REAL].needanswer = 1;
    04540             p->dialing = 0;
    04541          }
    04542          break;
    04543       case ZT_EVENT_HOOKCOMPLETE:
    04544       case ZT_EVENT_RINGERON:
    04545       case ZT_EVENT_RINGEROFF:
    04546          /* Do nothing */
    04547          break;
    04548       case ZT_EVENT_WINKFLASH:
    04549          gettimeofday(&p->flashtime, NULL);
    04550          if (p->owner) {
    04551             if (option_verbose > 2)
    04552                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
    04553             if (p->owner->_state != AST_STATE_UP) {
    04554                /* Answer if necessary */
    04555                usedindex = zt_get_index(p->owner, p, 0);
    04556                if (usedindex > -1) {
    04557                   p->subs[usedindex].needanswer = 1;
    04558                }
    04559                ast_setstate(p->owner, AST_STATE_UP);
    04560             }
    04561             p->callwaitingrepeat = 0;
    04562             p->cidcwexpire = 0;
    04563             if (ast_bridged_channel(p->owner))
    04564                ast_moh_stop(ast_bridged_channel(p->owner));
    04565          } else
    04566             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
    04567          update_conf(p);
    04568          break;
    04569       default:
    04570          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
    04571       }
    04572       f = &p->subs[index].f;
    04573       return f;
    04574    }
    04575    if (!p->radio) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
    04576    /* If it's not us, return NULL immediately */
    04577    if (ast != p->owner) {
    04578       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
    04579       f = &p->subs[index].f;
    04580       return f;
    04581    }
    04582    f = zt_handle_event(ast);
    04583    return f;
    04584 }

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

Definition at line 10106 of file chan_zap.c.

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

Referenced by load_module().

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

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

Definition at line 10124 of file chan_zap.c.

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

Referenced by load_module().

    10125 {
    10126    struct zt_pvt *p = NULL;
    10127    char *channel = astman_get_header(m, "ZapChannel");
    10128    if (ast_strlen_zero(channel)) {
    10129       astman_send_error(s, m, "No channel specified");
    10130       return 0;
    10131    }
    10132    p = find_channel(atoi(channel));
    10133    if (!p) {
    10134       astman_send_error(s, m, "No such channel");
    10135       return 0;
    10136    }
    10137    zap_fake_event(p,HANGUP);
    10138    astman_send_ack(s, m, "ZapHangup");
    10139    return 0;
    10140 }

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

Definition at line 10142 of file chan_zap.c.

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

Referenced by load_module().

    10143 {
    10144    struct zt_pvt *p = NULL;
    10145    char *channel = astman_get_header(m, "ZapChannel");
    10146    char *number = astman_get_header(m, "Number");
    10147    int i;
    10148    if (ast_strlen_zero(channel)) {
    10149       astman_send_error(s, m, "No channel specified");
    10150       return 0;
    10151    }
    10152    if (ast_strlen_zero(number)) {
    10153       astman_send_error(s, m, "No number specified");
    10154       return 0;
    10155    }
    10156    p = find_channel(atoi(channel));
    10157    if (!p) {
    10158       astman_send_error(s, m, "No such channel");
    10159       return 0;
    10160    }
    10161    if (!p->owner) {
    10162       astman_send_error(s, m, "Channel does not have it's owner");
    10163       return 0;
    10164    }
    10165    for (i=0; i<strlen(number); i++) {
    10166       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
    10167       zap_queue_frame(p, &f, NULL);
    10168    }
    10169    astman_send_ack(s, m, "ZapDialOffhook");
    10170    return 0;
    10171 }

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

Definition at line 10088 of file chan_zap.c.

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

Referenced by load_module().

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

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

Definition at line 10070 of file chan_zap.c.

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

Referenced by load_module().

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

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

Definition at line 10173 of file chan_zap.c.

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

Referenced by load_module().

    10174 {
    10175    struct zt_pvt *tmp = NULL;
    10176    char *id = astman_get_header(m, "ActionID");
    10177    char idText[256] = "";
    10178
    10179    astman_send_ack(s, m, "Zapata channel status will follow");
    10180    if (!ast_strlen_zero(id))
    10181       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
    10182
    10183    ast_mutex_lock(&iflock);
    10184
    10185    tmp = iflist;
    10186    while (tmp) {
    10187       if (tmp->channel > 0) {
    10188          int alarm = get_alarms(tmp);
    10189          ast_cli(s->fd,
    10190             "Event: ZapShowChannels\r\n"
    10191             "Channel: %d\r\n"
    10192             "Signalling: %s\r\n"
    10193             "Context: %s\r\n"
    10194             "DND: %s\r\n"
    10195             "Alarm: %s\r\n"
    10196             "%s"
    10197             "\r\n",
    10198             tmp->channel, sig2str(tmp->sig), tmp->context,
    10199             tmp->dnd ? "Enabled" : "Disabled",
    10200             alarm2str(alarm), idText);
    10201       }
    10202
    10203       tmp = tmp->next;
    10204    }
    10205
    10206    ast_mutex_unlock(&iflock);
    10207
    10208    ast_cli(s->fd,
    10209       "Event: ZapShowChannelsComplete\r\n"
    10210       "%s"
    10211       "\r\n",
    10212       idText);
    10213    return 0;
    10214 }

static char* alarm2str | ( | int | alarm | ) | `[static]`

Definition at line 1238 of file chan_zap.c.

References alarms.

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

    01239 {
    01240    int x;
    01241    for (x=0;x<sizeof(alarms) / sizeof(alarms[0]); x++) {
    01242       if (alarms[x].alarm & alarm)
    01243          return alarms[x].name;
    01244    }
    01245    return alarm ? "Unknown Alarm" : "No Alarm";
    01246 }

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

Definition at line 1106 of file chan_zap.c.

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

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

    01107 {
    01108    ZT_BUFFERINFO bi;
    01109    int res;
    01110    if (p->subs[x].zfd < 0) {
    01111       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
    01112       if (p->subs[x].zfd > -1) {
    01113          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
    01114          if (!res) {
    01115             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
    01116             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
    01117             bi.numbufs = numbufs;
    01118             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
    01119             if (res < 0) {
    01120                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
    01121             }
    01122          } else
    01123             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
    01124          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
    01125             ast_log(LOG_WARNING,"Unable to get channel number for pseudo channel on FD %d\n",p->subs[x].zfd);
    01126             zt_close(p->subs[x].zfd);
    01127             p->subs[x].zfd = -1;
    01128             return -1;
    01129          }
    01130          if (option_debug)
    01131             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
    01132          return 0;
    01133       } else
    01134          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
    01135       return -1;
    01136    }
    01137    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
    01138    return -1;
    01139 }

AST_MUTEX_DEFINE_STATIC | ( | monlock |  | ) |

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

AST_MUTEX_DEFINE_STATIC | ( | iflock |  | ) |

Protect the interface list (of zt_pvt's).

AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock |  | ) |

static int attempt_transfer | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 3486 of file chan_zap.c.

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

    03487 {
    03488    /* In order to transfer, we need at least one of the channels to
    03489       actually be in a call bridge.  We can't conference two applications
    03490       together (but then, why would we want to?) */
    03491    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
    03492       /* The three-way person we're about to transfer to could still be in MOH, so
    03493          stop if now if appropriate */
    03494       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
    03495          ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
    03496       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
    03497          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
    03498       }
    03499       if (p->subs[SUB_REAL].owner->cdr) {
    03500          /* Move CDR from second channel to current one */
    03501          p->subs[SUB_THREEWAY].owner->cdr =
    03502             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
    03503          p->subs[SUB_REAL].owner->cdr = NULL;
    03504       }
    03505       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
    03506          /* Move CDR from second channel's bridge to current one */
    03507          p->subs[SUB_THREEWAY].owner->cdr =
    03508             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
    03509          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
    03510       }
    03511        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
    03512          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
    03513                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
    03514          return -1;
    03515       }
    03516       /* Orphan the channel after releasing the lock */
    03517       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03518       unalloc_sub(p, SUB_THREEWAY);
    03519    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
    03520       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
    03521          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
    03522       }
    03523       ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
    03524       if (p->subs[SUB_THREEWAY].owner->cdr) {
    03525          /* Move CDR from second channel to current one */
    03526          p->subs[SUB_REAL].owner->cdr =
    03527             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
    03528          p->subs[SUB_THREEWAY].owner->cdr = NULL;
    03529       }
    03530       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
    03531          /* Move CDR from second channel's bridge to current one */
    03532          p->subs[SUB_REAL].owner->cdr =
    03533             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
    03534          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
    03535       }
    03536       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
    03537          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
    03538                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
    03539          return -1;
    03540       }
    03541       /* Three-way is now the REAL */
    03542       swap_subs(p, SUB_THREEWAY, SUB_REAL);
    03543       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
    03544       unalloc_sub(p, SUB_THREEWAY);
    03545       /* Tell the caller not to hangup */
    03546       return 1;
    03547    } else {
    03548       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
    03549                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
    03550       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
    03551       return -1;
    03552    }
    03553    return 0;
    03554 }

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

Definition at line 7445 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_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.

Referenced by zt_request().

    07446 {
    07447    int res;
    07448    ZT_PARAMS par;
    07449
    07450    /* First, check group matching */
    07451    if (groupmatch) {
    07452       if ((p->group & groupmatch) != groupmatch)
    07453          return 0;
    07454       *groupmatched = 1;
    07455    }
    07456    /* Check to see if we have a channel match */
    07457    if (channelmatch != -1) {
    07458       if (p->channel != channelmatch)
    07459          return 0;
    07460       *channelmatched = 1;
    07461    }
    07462    /* We're at least busy at this point */
    07463    if (busy) {
    07464       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
    07465          *busy = 1;
    07466    }
    07467    /* If do not disturb, definitely not */
    07468    if (p->dnd)
    07469       return 0;
    07470    /* If guard time, definitely not */
    07471    if (p->guardtime && (time(NULL) < p->guardtime))
    07472       return 0;
    07473
    07474    /* If no owner definitely available */
    07475    if (!p->owner) {
    07476 #ifdef ZAPATA_PRI
    07477       /* Trust PRI */
    07478       if (p->pri) {
    07479          if (p->resetting || p->call)
    07480             return 0;
    07481          else
    07482             return 1;
    07483       }
    07484 #endif
    07485 #ifdef ZAPATA_R2
    07486       /* Trust R2 as well */
    07487       if (p->r2) {
    07488          if (p->hasr2call || p->r2blocked)
    07489             return 0;
    07490          else
    07491             return 1;
    07492       }
    07493 #endif
    07494       if (!p->radio)
    07495       {
    07496          if (!p->sig || (p->sig == SIG_FXSLS))
    07497             return 1;
    07498          /* Check hook state */
    07499          if (p->subs[SUB_REAL].zfd > -1)
    07500             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
    07501          else {
    07502             /* Assume not off hook on CVRS */
    07503             res = 0;
    07504             par.rxisoffhook = 0;
    07505          }
    07506          if (res) {
    07507             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
    07508          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
    07509             /* When "onhook" that means no battery on the line, and thus
    07510               it is out of service..., if it's on a TDM card... If it's a channel
    07511               bank, there is no telling... */
    07512             if (par.rxbits > -1)
    07513                return 1;
    07514             if (par.rxisoffhook)
    07515                return 1;
    07516             else
    07517 #ifdef ZAP_CHECK_HOOKSTATE
    07518                return 0;
    07519 #else
    07520                return 1;
    07521 #endif
    07522          } else if (par.rxisoffhook) {
    07523             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
    07524             /* Not available when the other end is off hook */
    07525             return 0;
    07526          }
    07527       }
    07528       return 1;
    07529    }
    07530
    07531    /* If it's not an FXO, forget about call wait */
    07532    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS))
    07533       return 0;
    07534
    07535    if (!p->callwaiting) {
    07536       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
    07537       return 0;
    07538    }
    07539
    07540    if (p->subs[SUB_CALLWAIT].zfd > -1) {
    07541       /* If there is already a call waiting call, then we can't take a second one */
    07542       return 0;
    07543    }
    07544
    07545    if ((p->owner->_state != AST_STATE_UP) &&
    07546        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
    07547       /* If the current call is not up, then don't allow the call */
    07548       return 0;
    07549    }
    07550    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
    07551       /* Can't take a call wait when the three way calling hasn't been merged yet. */
    07552       return 0;
    07553    }
    07554    /* We're cool */
    07555    return 1;
    07556 }

static int bump_gains | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1700 of file chan_zap.c.

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

Referenced by ss_thread().

    01701 {
    01702    int res;
    01703
    01704    /* Bump receive gain by 5.0db */
    01705    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
    01706    if (res) {
    01707       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
    01708       return -1;
    01709    }
    01710
    01711    return 0;
    01712 }

static struct zt_pvt* chandup | ( | struct zt_pvt * | src | ) | `[static, read]`

Definition at line 7558 of file chan_zap.c.

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

Referenced by zt_request().

    07559 {
    07560    struct zt_pvt *p;
    07561    ZT_BUFFERINFO bi;
    07562    int res;
    07563    p = malloc(sizeof(struct zt_pvt));
    07564    if (p) {
    07565       memcpy(p, src, sizeof(struct zt_pvt));
    07566       ast_mutex_init(&p->lock);
    07567       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
    07568       /* Allocate a zapata structure */
    07569       if (p->subs[SUB_REAL].zfd < 0) {
    07570          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
    07571          destroy_zt_pvt(&p);
    07572          return NULL;
    07573       }
    07574       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
    07575       if (!res) {
    07576          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
    07577          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
    07578          bi.numbufs = numbufs;
    07579          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
    07580          if (res < 0) {
    07581             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
    07582          }
    07583       } else
    07584          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
    07585    }
    07586    p->destroy = 1;
    07587    p->next = iflist;
    07588    iflist = p;
    07589    return p;
    07590 }

static int check_for_conference | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 3628 of file chan_zap.c.

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

Referenced by zt_handle_event().

    03629 {
    03630    ZT_CONFINFO ci;
    03631    /* Fine if we already have a master, etc */
    03632    if (p->master || (p->confno > -1))
    03633       return 0;
    03634    memset(&ci, 0, sizeof(ci));
    03635    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
    03636       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
    03637       return 0;
    03638    }
    03639    /* If we have no master and don't have a confno, then
    03640       if we're in a conference, it's probably a MeetMe room or
    03641       some such, so don't let us 3-way out! */
    03642    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
    03643       if (option_verbose > 2)
    03644          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
    03645       return 1;
    03646    }
    03647    return 0;
    03648 }

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

Definition at line 1343 of file chan_zap.c.

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

Referenced by update_conf().

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

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

Definition at line 1392 of file chan_zap.c.

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

Referenced by update_conf(), and zt_unlink().

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

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 11266 of file chan_zap.c.

    11267 {
    11268    return (char *) desc;
    11269 }

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

Definition at line 2316 of file chan_zap.c.

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

Referenced by zap_destroy_channel(), and zt_hangup().

    02317 {
    02318    int owned = 0;
    02319    int i = 0;
    02320
    02321    if (!now) {
    02322       if (cur->owner) {
    02323          owned = 1;
    02324       }
    02325
    02326       for (i = 0; i < 3; i++) {
    02327          if (cur->subs[i].owner) {
    02328             owned = 1;
    02329          }
    02330       }
    02331       if (!owned) {
    02332          if (prev) {
    02333             prev->next = cur->next;
    02334             if (prev->next)
    02335                prev->next->prev = prev;
    02336             else
    02337                ifend = prev;
    02338          } else {
    02339             iflist = cur->next;
    02340             if (iflist)
    02341                iflist->prev = NULL;
    02342             else
    02343                ifend = NULL;
    02344          }
    02345          if (cur->subs[SUB_REAL].zfd > -1) {
    02346             zt_close(cur->subs[SUB_REAL].zfd);
    02347          }
    02348          destroy_zt_pvt(&cur);
    02349       }
    02350    } else {
    02351       if (prev) {
    02352          prev->next = cur->next;
    02353          if (prev->next)
    02354             prev->next->prev = prev;
    02355          else
    02356             ifend = prev;
    02357       } else {
    02358          iflist = cur->next;
    02359          if (iflist)
    02360             iflist->prev = NULL;
    02361          else
    02362             ifend = NULL;
    02363       }
    02364       if (cur->subs[SUB_REAL].zfd > -1) {
    02365          zt_close(cur->subs[SUB_REAL].zfd);
    02366       }
    02367       destroy_zt_pvt(&cur);
    02368    }
    02369    return 0;
    02370 }

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

Definition at line 2303 of file chan_zap.c.

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

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

    02304 {
    02305    struct zt_pvt *p = *pvt;
    02306    /* Remove channel from the list */
    02307    if(p->prev)
    02308       p->prev->next = p->next;
    02309    if(p->next)
    02310       p->next->prev = p->prev;
    02311    ast_mutex_destroy(&p->lock);
    02312    free(p);
    02313    *pvt = NULL;
    02314 }

static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | `[static]`

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

Referenced by zt_bridge().

    03109 {
    03110 #ifdef ZT_TONEDETECT
    03111    int val;
    03112 #endif
    03113
    03114    p->ignoredtmf = 1;
    03115
    03116 #ifdef ZT_TONEDETECT
    03117    val = 0;
    03118    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
    03119 #endif
    03120    if (!p->hardwaredtmf && p->dsp) {
    03121       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
    03122       ast_dsp_set_features(p->dsp, p->dsp_features);
    03123    }
    03124 }

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

Definition at line 6611 of file chan_zap.c.

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

    06612 {
    06613    int count, res, res2, spoint, pollres=0;
    06614    struct zt_pvt *i;
    06615    struct zt_pvt *last = NULL;
    06616    time_t thispass = 0, lastpass = 0;
    06617    int found;
    06618    char buf[1024];
    06619    struct pollfd *pfds=NULL;
    06620    int lastalloc = -1;
    06621    /* This thread monitors all the frame relay interfaces which are not yet in use
    06622       (and thus do not have a separate thread) indefinitely */
    06623    /* From here on out, we die whenever asked */
    06624 #if 0
    06625    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
    06626       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
    06627       return NULL;
    06628    }
    06629    ast_log(LOG_DEBUG, "Monitor starting...\n");
    06630 #endif
    06631    for(;;) {
    06632       /* Lock the interface list */
    06633       if (ast_mutex_lock(&iflock)) {
    06634          ast_log(LOG_ERROR, "Unable to grab interface lock\n");
    06635          return NULL;
    06636       }
    06637       if (!pfds || (lastalloc != ifcount)) {
    06638          if (pfds)
    06639             free(pfds);
    06640          if (ifcount) {
    06641             pfds = malloc(ifcount * sizeof(struct pollfd));
    06642             if (!pfds) {
    06643                ast_log(LOG_WARNING, "Critical memory error.  Zap dies.\n");
    06644                ast_mutex_unlock(&iflock);
    06645                return NULL;
    06646             }
    06647          }
    06648          lastalloc = ifcount;
    06649       }
    06650       /* Build the stuff we're going to poll on, that is the socket of every
    06651          zt_pvt that does not have an associated owner channel */
    06652       count = 0;
    06653       i = iflist;
    06654       while(i) {
    06655          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
    06656             if (!i->owner && !i->subs[SUB_REAL].owner) {
    06657                /* This needs to be watched, as it lacks an owner */
    06658                pfds[count].fd = i->subs[SUB_REAL].zfd;
    06659                pfds[count].events = POLLPRI;
    06660                pfds[count].revents = 0;
    06661                /* Message waiting or r2 channels also get watched for reading */
    06662 #ifdef ZAPATA_R2
    06663                if (i->cidspill || i->r2)
    06664 #else
    06665                if (i->cidspill)
    06666 #endif
    06667                   pfds[count].events |= POLLIN;
    06668                count++;
    06669             }
    06670          }
    06671          i = i->next;
    06672       }
    06673       /* Okay, now that we know what to do, release the interface lock */
    06674       ast_mutex_unlock(&iflock);
    06675
    06676       pthread_testcancel();
    06677       /* Wait at least a second for something to happen */
    06678       res = poll(pfds, count, 1000);
    06679       pthread_testcancel();
    06680       /* Okay, poll has finished.  Let's see what happened.  */
    06681       if (res < 0) {
    06682          if ((errno != EAGAIN) && (errno != EINTR))
    06683             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
    06684          continue;
    06685       }
    06686       /* Alright, lock the interface list again, and let's look and see what has
    06687          happened */
    06688       if (ast_mutex_lock(&iflock)) {
    06689          ast_log(LOG_WARNING, "Unable to lock the interface list\n");
    06690          continue;
    06691       }
    06692       found = 0;
    06693       spoint = 0;
    06694       lastpass = thispass;
    06695       thispass = time(NULL);
    06696       i = iflist;
    06697       while(i) {
    06698          if (thispass != lastpass) {
    06699             if (!found && ((i == last) || ((i == iflist) && !last))) {
    06700                last = i;
    06701                if (last) {
    06702                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
    06703                      (last->sig & __ZT_SIG_FXO)) {
    06704                      res = ast_app_has_voicemail(last->mailbox, NULL);
    06705                      if (last->msgstate != res) {
    06706                         int x;
    06707                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
    06708                         x = ZT_FLUSH_BOTH;
    06709                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
    06710                         if (res2)
    06711                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
    06712                         last->cidspill = malloc(MAX_CALLERID_SIZE);
    06713                         if (last->cidspill) {
    06714                            /* Turn on on hook transfer for 4 seconds */
    06715                            x = 4000;
    06716                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
    06717                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
    06718                            last->cidpos = 0;
    06719                            last->msgstate = res;
    06720                            last->onhooktime = thispass;
    06721                         }
    06722                         found ++;
    06723                      }
    06724                   }
    06725                   last = last->next;
    06726                }
    06727             }
    06728          }
    06729          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
    06730             if (i->radio && !i->owner)
    06731             {
    06732                res = zt_get_event(i->subs[SUB_REAL].zfd);
    06733                if (res)
    06734                {
    06735                   if (option_debug)
    06736                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
    06737                   /* Don't hold iflock while handling init events */
    06738                   ast_mutex_unlock(&iflock);
    06739                   handle_init_event(i, res);
    06740                   ast_mutex_lock(&iflock);
    06741                }
    06742                i = i->next;
    06743                continue;
    06744             }
    06745             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
    06746             if (pollres & POLLIN) {
    06747                if (i->owner || i->subs[SUB_REAL].owner) {
    06748 #ifdef ZAPATA_PRI
    06749                   if (!i->pri)
    06750 #endif
    06751                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
    06752                   i = i->next;
    06753                   continue;
    06754                }
    06755 #ifdef ZAPATA_R2
    06756                if (i->r2) {
    06757                   /* If it's R2 signalled, we always have to check for events */
    06758                   mfcr2_event_t *e;
    06759                   e = mfcr2_check_event(i->r2);
    06760                   if (e)
    06761                      handle_init_r2_event(i, e);
    06762                   else {
    06763                      e = mfcr2_schedule_run(i->r2);
    06764                      if (e)
    06765                         handle_init_r2_event(i, e);
    06766                   }
    06767                   i = i->next;
    06768                   continue;
    06769                }
    06770 #endif
    06771                if (!i->cidspill) {
    06772                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
    06773                   i = i->next;
    06774                   continue;
    06775                }
    06776                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
    06777                if (res > 0) {
    06778                   /* We read some number of bytes.  Write an equal amount of data */
    06779                   if (res > i->cidlen - i->cidpos)
    06780                      res = i->cidlen - i->cidpos;
    06781                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
    06782                   if (res2 > 0) {
    06783                      i->cidpos += res2;
    06784                      if (i->cidpos >= i->cidlen) {
    06785                         free(i->cidspill);
    06786                         i->cidspill = 0;
    06787                         i->cidpos = 0;
    06788                         i->cidlen = 0;
    06789                      }
    06790                   } else {
    06791                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
    06792                      i->msgstate = -1;
    06793                   }
    06794                } else {
    06795                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
    06796                }
    06797                if (option_debug)
    06798                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
    06799                /* Don't hold iflock while handling init events -- race with chlock */
    06800                ast_mutex_unlock(&iflock);
    06801                handle_init_event(i, res);
    06802                ast_mutex_lock(&iflock);
    06803             }
    06804 #ifdef ZAPATA_R2
    06805             if ((pollres & POLLPRI) || (i->r2 && !i->sigchecked))
    06806 #else
    06807             if (pollres & POLLPRI)
    06808 #endif
    06809             {
    06810                if (i->owner || i->subs[SUB_REAL].owner) {
    06811 #ifdef ZAPATA_PRI
    06812                   if (!i->pri)
    06813 #endif
    06814                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
    06815                   i = i->next;
    06816                   continue;
    06817                }
    06818                res = zt_get_event(i->subs[SUB_REAL].zfd);
    06819                if (option_debug)
    06820                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
    06821                /* Don't hold iflock while handling init events */
    06822                ast_mutex_unlock(&iflock);
    06823                handle_init_event(i, res);
    06824                ast_mutex_lock(&iflock);
    06825             }
    06826          }
    06827          i=i->next;
    06828       }
    06829       ast_mutex_unlock(&iflock);
    06830    }
    06831    /* Never reached */
    06832    return NULL;
    06833
    06834 }

static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | `[static]`

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

Referenced by zt_bridge().

    03127 {
    03128 #ifdef ZT_TONEDETECT
    03129    int val;
    03130 #endif
    03131
    03132    if (p->channel == CHAN_PSEUDO)
    03133       return;
    03134
    03135    p->ignoredtmf = 0;
    03136
    03137 #ifdef ZT_TONEDETECT
    03138    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
    03139    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
    03140 #endif
    03141    if (!p->hardwaredtmf && p->dsp) {
    03142       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
    03143       ast_dsp_set_features(p->dsp, p->dsp_features);
    03144    }
    03145 }

static char* event2str | ( | int | event | ) | `[static]`

Definition at line 1248 of file chan_zap.c.

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

    01249 {
    01250         static char buf[256];
    01251         if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
    01252                 return events[event];
    01253         sprintf(buf, "Event %d", event); /* safe */
    01254         return buf;
    01255 }

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

Definition at line 1625 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_rxgain().

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

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

Definition at line 1591 of file chan_zap.c.

References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.

Referenced by set_actual_txgain().

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

static struct zt_pvt* find_channel | ( | int | channel | ) | `[static, read]`

Definition at line 10058 of file chan_zap.c.

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

    10059 {
    10060    struct zt_pvt *p = iflist;
    10061    while(p) {
    10062       if (p->channel == channel) {
    10063          break;
    10064       }
    10065       p = p->next;
    10066    }
    10067    return p;
    10068 }

static int get_alarms | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 3650 of file chan_zap.c.

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

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

    03651 {
    03652    int res;
    03653    ZT_SPANINFO zi;
    03654    memset(&zi, 0, sizeof(zi));
    03655    zi.spanno = p->span;
    03656    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
    03657    if (res < 0) {
    03658       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
    03659       return 0;
    03660    }
    03661    return zi.alarms;
    03662 }

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

Definition at line 6414 of file chan_zap.c.

References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, EVENT_FLAG_SYSTEM, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().

Referenced by do_monitor().

    06415 {
    06416    int res;
    06417    pthread_t threadid;
    06418    pthread_attr_t attr;
    06419    struct ast_channel *chan;
    06420    pthread_attr_init(&attr);
    06421    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    06422    /* Handle an event on a given channel for the monitor thread. */
    06423    switch(event) {
    06424    case ZT_EVENT_NONE:
    06425    case ZT_EVENT_BITSCHANGED:
    06426       if (i->radio) break;
    06427 #ifdef ZAPATA_R2
    06428       if (i->r2) {
    06429          mfcr2_event_t *e;
    06430          e = r2_get_event_bits(i);
    06431          i->sigchecked = 1;
    06432          if (e)
    06433             handle_init_r2_event(i, e);
    06434       }
    06435 #endif
    06436       break;
    06437    case ZT_EVENT_WINKFLASH:
    06438    case ZT_EVENT_RINGOFFHOOK:
    06439       if (i->inalarm) break;
    06440       if (i->radio) break;
    06441       /* Got a ring/answer.  What kind of channel are we? */
    06442       switch(i->sig) {
    06443       case SIG_FXOLS:
    06444       case SIG_FXOGS:
    06445       case SIG_FXOKS:
    06446          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
    06447          if (res && (errno == EBUSY))
    06448             break;
    06449          if (i->cidspill) {
    06450             /* Cancel VMWI spill */
    06451             free(i->cidspill);
    06452             i->cidspill = NULL;
    06453          }
    06454          if (i->immediate) {
    06455             zt_enable_ec(i);
    06456             /* The channel is immediately up.  Start right away */
    06457             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
    06458             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
    06459             if (!chan) {
    06460                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
    06461                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
    06462                if (res < 0)
    06463                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
    06464             }
    06465          } else {
    06466             /* Check for callerid, digits, etc */
    06467             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
    06468             if (chan) {
    06469                if (has_voicemail(i))
    06470                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
    06471                else
    06472                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
    06473                if (res < 0)
    06474                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
    06475                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
    06476                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
    06477                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
    06478                   if (res < 0)
    06479                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
    06480                   ast_hangup(chan);
    06481                }
    06482             } else
    06483                ast_log(LOG_WARNING, "Unable to create channel\n");
    06484          }
    06485          break;
    06486       case SIG_FXSLS:
    06487       case SIG_FXSGS:
    06488       case SIG_FXSKS:
    06489             i->ringt = i->ringt_base;
    06490             /* Fall through */
    06491       case SIG_EMWINK:
    06492       case SIG_FEATD:
    06493       case SIG_FEATDMF:
    06494       case SIG_E911:
    06495       case SIG_FEATB:
    06496       case SIG_EM:
    06497       case SIG_EM_E1:
    06498       case SIG_SFWINK:
    06499       case SIG_SF_FEATD:
    06500       case SIG_SF_FEATDMF:
    06501       case SIG_SF_FEATB:
    06502       case SIG_SF:
    06503             /* Check for callerid, digits, etc */
    06504             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
    06505             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
    06506                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
    06507                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
    06508                if (res < 0)
    06509                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
    06510                ast_hangup(chan);
    06511             } else if (!chan) {
    06512                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
    06513             }
    06514             break;
    06515       default:
    06516          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
    06517          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
    06518          if (res < 0)
    06519                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
    06520          return -1;
    06521       }
    06522       break;
    06523    case ZT_EVENT_NOALARM:
    06524       i->inalarm = 0;
    06525       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
    06526       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
    06527                     "Channel: %d\r\n", i->channel);
    06528       break;
    06529    case ZT_EVENT_ALARM:
    06530       i->inalarm = 1;
    06531       res = get_alarms(i);
    06532       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
    06533       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
    06534                     "Alarm: %s\r\n"
    06535                     "Channel: %d\r\n",
    06536                     alarm2str(res), i->channel);
    06537       /* fall thru intentionally */
    06538    case ZT_EVENT_ONHOOK:
    06539       if (i->radio) break;
    06540       /* Back on hook.  Hang up. */
    06541       switch(i->sig) {
    06542       case SIG_FXOLS:
    06543       case SIG_FXOGS:
    06544       case SIG_FEATD:
    06545       case SIG_FEATDMF:
    06546       case SIG_E911:
    06547       case SIG_FEATB:
    06548       case SIG_EM:
    06549       case SIG_EM_E1:
    06550       case SIG_EMWINK:
    06551       case SIG_SF_FEATD:
    06552       case SIG_SF_FEATDMF:
    06553       case SIG_SF_FEATB:
    06554       case SIG_SF:
    06555       case SIG_SFWINK:
    06556       case SIG_FXSLS:
    06557       case SIG_FXSGS:
    06558       case SIG_FXSKS:
    06559       case SIG_GR303FXSKS:
    06560          zt_disable_ec(i);
    06561          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
    06562          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
    06563          break;
    06564       case SIG_GR303FXOKS:
    06565       case SIG_FXOKS:
    06566          zt_disable_ec(i);
    06567          /* Diddle the battery for the zhone */
    06568 #ifdef ZHONE_HACK
    06569          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
    06570          usleep(1);
    06571 #endif
    06572          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
    06573          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
    06574          break;
    06575       case SIG_PRI:
    06576          zt_disable_ec(i);
    06577          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
    06578          break;
    06579       default:
    06580          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
    06581          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
    06582          return -1;
    06583       }
    06584       break;
    06585    case ZT_EVENT_POLARITY:
    06586       switch(i->sig) {
    06587       case SIG_FXSLS:
    06588       case SIG_FXSKS:
    06589       case SIG_FXSGS:
    06590          if (i->cid_start == CID_START_POLARITY) {
    06591             i->polarity = POLARITY_REV;
    06592             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
    06593                    "CID detection on channel %d\n",
    06594                    i->channel);
    06595             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
    06596             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
    06597                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
    06598             }
    06599          }
    06600          break;
    06601       default:
    06602          ast_log(LOG_WARNING, "handle_init_event detected "
    06603             "polarity reversal on non-FXO (SIG_FXS) "
    06604             "interface %d\n", i->channel);
    06605       }
    06606    }
    06607    pthread_attr_destroy(&attr);
    06608    return 0;
    06609 }

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

Definition at line 9922 of file chan_zap.c.

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

    09923 {
    09924    int i, j;
    09925    for (i=0;i<num_cadence;i++) {
    09926       char output[1024];
    09927       char tmp[16], tmp2[64];
    09928       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
    09929       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
    09930
    09931       for (j=0;j<16;j++) {
    09932          if (cadences[i].ringcadence[j] == 0)
    09933             break;
    09934          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
    09935          if (cidrings[i] * 2 - 1 == j)
    09936             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
    09937          else
    09938             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
    09939          if (j != 0)
    09940             strncat(output, ",", sizeof(output) - strlen(output) - 1);
    09941          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
    09942       }
    09943       ast_cli(fd,"%s\n",output);
    09944    }
    09945    return 0;
    09946 }

static int has_voicemail | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1823 of file chan_zap.c.

References ast_app_has_voicemail(), and zt_pvt::mailbox.

    01824 {
    01825
    01826    return ast_app_has_voicemail(p->mailbox, NULL);
    01827 }

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

Definition at line 1381 of file chan_zap.c.

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

Referenced by conf_del().

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

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

Definition at line 1414 of file chan_zap.c.

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

Referenced by update_conf().

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

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 11271 of file chan_zap.c.

References ASTERISK_GPL_KEY.

    11272 {
    11273    return ASTERISK_GPL_KEY;
    11274 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 11102 of file chan_zap.c.

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

    11103 {
    11104    int res;
    11105
    11106 #ifdef ZAPATA_PRI
    11107    int y,i;
    11108    memset(pris, 0, sizeof(pris));
    11109    for (y=0;y<NUM_SPANS;y++) {
    11110       ast_mutex_init(&pris[y].lock);
    11111       pris[y].offset = -1;
    11112       pris[y].master = AST_PTHREADT_NULL;
    11113       for (i=0;i<NUM_DCHANS;i++)
    11114          pris[y].fds[i] = -1;
    11115    }
    11116    pri_set_error(zt_pri_error);
    11117    pri_set_message(zt_pri_message);
    11118 #endif
    11119    res = setup_zap(0);
    11120    /* Make sure we can register our Zap channel type */
    11121    if(res) {
    11122      return -1;
    11123    }
    11124    if (ast_channel_register(&zap_tech)) {
    11125       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
    11126       __unload_module();
    11127       return -1;
    11128    }
    11129 #ifdef ZAPATA_PRI
    11130    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
    11131 #endif
    11132 #ifdef ZAPATA_R2
    11133    ast_cli_register_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
    11134 #endif
    11135    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
    11136
    11137    memset(round_robin, 0, sizeof(round_robin));
    11138    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
    11139    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
    11140    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
    11141    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
    11142    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
    11143    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
    11144
    11145    return res;
    11146 }

static struct zt_pvt* mkintf | ( | int | channel,
|  | struct zt_chan_conf | chan_conf,
|  | struct zt_pri * | pri,
|  | int | reloading |
| ) |  |  | `[static, read]`

Definition at line 6984 of file chan_zap.c.

References zt_chan_conf::accountcode, zt_pvt::accountcode, zt_chan_conf::adsi, zt_pvt::adsi, zt_chan_conf::amaflags, zt_pvt::amaflags, zt_chan_conf::answeronpolarityswitch, zt_pvt::answeronpolarityswitch, ast_dsp_digitmode(), ast_log(), ast_mutex_init(), ast_strlen_zero(), zt_chan_conf::busy_quietlength, zt_pvt::busy_quietlength, zt_chan_conf::busy_tonelength, zt_pvt::busy_tonelength, zt_chan_conf::busycount, zt_pvt::busycount, zt_chan_conf::busydetect, zt_pvt::busydetect, zt_chan_conf::callergroup, zt_pvt::callgroup, zt_chan_conf::callprogress, zt_pvt::callprogress, zt_chan_conf::callreturn, zt_pvt::callreturn, zt_pvt::callwaiting, zt_chan_conf::callwaiting, zt_chan_conf::callwaitingcallerid, zt_pvt::callwaitingcallerid, zt_chan_conf::cancallforward, zt_pvt::cancallforward, zt_chan_conf::canpark, zt_pvt::canpark, CHAN_PSEUDO, zt_pvt::channel, zt_chan_conf::cid_name, zt_pvt::cid_name, zt_chan_conf::cid_num, zt_pvt::cid_num, zt_chan_conf::cid_signalling, zt_pvt::cid_signalling, zt_chan_conf::cid_start, zt_pvt::cid_start, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_chan_conf::context, zt_chan_conf::debounce, zt_pvt::defcontext, zt_pvt::destroy, destroy_zt_pvt(), drings, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_chan_conf::echocanbridged, zt_pvt::echocanbridged, zt_chan_conf::echocancel, zt_pvt::echocancel, zt_chan_conf::echotraining, zt_pvt::echotraining, zt_pvt::firstradio, zt_chan_conf::flash, zt_chan_conf::group, zt_pvt::group, zt_chan_conf::hanguponpolarityswitch, zt_pvt::hanguponpolarityswitch, zt_pvt::hidecallerid, zt_chan_conf::hidecallerid, iflist, zt_chan_conf::immediate, zt_pvt::immediate, zt_pvt::inalarm, zt_pvt::language, zt_pvt::law, zt_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, zt_chan_conf::mailbox, zt_pvt::mailbox, malloc, MAX_CHANNELS, zt_pvt::msgstate, zt_chan_conf::musicclass, zt_pvt::musicclass, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_chan_conf::pickupgroup, zt_pvt::pickupgroup, zt_chan_conf::polarityonanswerdelay, zt_pvt::polarityonanswerdelay, zt_chan_conf::preflash, zt_pvt::prev, zt_chan_conf::prewink, zt_chan_conf::pri, zt_chan_conf::priexclusive, zt_pvt::priexclusive, zt_chan_conf::priindication_oob, zt_pvt::priindication_oob, zt_pvt::propconfno, zt_chan_conf::pulse, zt_pvt::pulse, zt_pvt::radio, zt_chan_conf::radio, zt_chan_conf::relaxdtmf, zt_chan_conf::restrictcid, zt_pvt::restrictcid, zt_pvt::ringt_base, zt_chan_conf::rxflash, zt_chan_conf::rxgain, zt_pvt::rxgain, zt_chan_conf::rxwink, zt_chan_conf::sendcalleridafter, zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_chan_conf::signalling, zt_pvt::span, zt_chan_conf::start, zt_chan_conf::stripmsd, zt_pvt::stripmsd, SUB_REAL, zt_pvt::subs, zt_chan_conf::threewaycalling, zt_pvt::threewaycalling, zt_chan_conf::tonezone, zt_pvt::tonezone, zt_chan_conf::transfer, zt_pvt::transfer, zt_chan_conf::transfertobusy, zt_pvt::transfertobusy, zt_chan_conf::txgain, zt_pvt::txgain, update_conf(), zt_chan_conf::use_callerid, zt_pvt::use_callerid, zt_chan_conf::use_callingpres, zt_pvt::use_callingpres, zt_pvt::usedistinctiveringdetection, zt_chan_conf::wink, zt_chan_conf::zaptrcallerid, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_close(), zt_open(), and zt_set_hook().

Referenced by setup_zap().

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

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

Definition at line 5334 of file chan_zap.c.

References ast_waitfordigit().

Referenced by ss_thread().

    05335 {
    05336    char c;
    05337
    05338    *str = 0; /* start with empty output buffer */
    05339    for (;;)
    05340    {
    05341       /* Wait for the first digit (up to specified ms). */
    05342       c = ast_waitfordigit(chan, ms);
    05343       /* if timeout, hangup or error, return as such */
    05344       if (c < 1)
    05345          return c;
    05346       *str++ = c;
    05347       *str = 0;
    05348       if (strchr(term, c))
    05349          return 1;
    05350    }
    05351 }

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

Definition at line 4862 of file chan_zap.c.

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

Referenced by zt_write().

    04863 {
    04864    int sent=0;
    04865    int size;
    04866    int res;
    04867    int fd;
    04868    fd = p->subs[index].zfd;
    04869    while(len) {
    04870       size = len;
    04871       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
    04872          size = (linear ? READ_SIZE * 2 : READ_SIZE);
    04873       res = write(fd, buf, size);
    04874       if (res != size) {
    04875          if (option_debug)
    04876             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
    04877          return sent;
    04878       }
    04879       len -= size;
    04880       buf += size;
    04881    }
    04882    return sent;
    04883 }

int reload | ( | void |  | ) |

Reload stuff.

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

Returns:
  The return value is not used.

Definition at line 11249 of file chan_zap.c.

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

    11250 {
    11251    int res = 0;
    11252
    11253    res = setup_zap(1);
    11254    if (res) {
    11255       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
    11256       return -1;
    11257    }
    11258    return 0;
    11259 }

static int reset_conf | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1458 of file chan_zap.c.

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

Referenced by zt_hangup().

    01459 {
    01460    ZT_CONFINFO zi;
    01461    memset(&zi, 0, sizeof(zi));
    01462    p->confno = -1;
    01463    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
    01464    if (p->subs[SUB_REAL].zfd > -1) {
    01465       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
    01466          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
    01467    }
    01468    return 0;
    01469 }

static int restart_monitor | ( | void |  | ) | `[static]`

Definition at line 6836 of file chan_zap.c.

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

    06837 {
    06838    pthread_attr_t attr;
    06839    pthread_attr_init(&attr);
    06840    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    06841    /* If we're supposed to be stopped -- stay stopped */
    06842    if (monitor_thread == AST_PTHREADT_STOP)
    06843       return 0;
    06844    if (ast_mutex_lock(&monlock)) {
    06845       ast_log(LOG_WARNING, "Unable to lock monitor\n");
    06846       return -1;
    06847    }
    06848    if (monitor_thread == pthread_self()) {
    06849       ast_mutex_unlock(&monlock);
    06850       ast_log(LOG_WARNING, "Cannot kill myself\n");
    06851       return -1;
    06852    }
    06853    if (monitor_thread != AST_PTHREADT_NULL) {
    06854       /* Wake up the thread */
    06855       pthread_kill(monitor_thread, SIGURG);
    06856    } else {
    06857       /* Start a new monitor */
    06858       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
    06859          ast_mutex_unlock(&monlock);
    06860          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
    06861          pthread_attr_destroy(&attr);
    06862          return -1;
    06863       }
    06864    }
    06865    ast_mutex_unlock(&monlock);
    06866    pthread_attr_destroy(&attr);
    06867    return 0;
    06868 }

static int restore_conference | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1787 of file chan_zap.c.

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

Referenced by send_callerid(), and zt_read().

    01788 {
    01789    int res;
    01790    if (p->saveconf.confmode) {
    01791       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
    01792       p->saveconf.confmode = 0;
    01793       if (res) {
    01794          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
    01795          return -1;
    01796       }
    01797    }
    01798    if (option_debug)
    01799       ast_log(LOG_DEBUG, "Restored conferencing\n");
    01800    return 0;
    01801 }

static int restore_gains | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1714 of file chan_zap.c.

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

Referenced by ss_thread(), and zt_hangup().

    01715 {
    01716    int res;
    01717
    01718    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
    01719    if (res) {
    01720       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
    01721       return -1;
    01722    }
    01723
    01724    return 0;
    01725 }

static int save_conference | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1759 of file chan_zap.c.

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

Referenced by zt_callwait().

    01760 {
    01761    struct zt_confinfo c;
    01762    int res;
    01763    if (p->saveconf.confmode) {
    01764       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
    01765       return -1;
    01766    }
    01767    p->saveconf.chan = 0;
    01768    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
    01769    if (res) {
    01770       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
    01771       p->saveconf.confmode = 0;
    01772       return -1;
    01773    }
    01774    c.chan = 0;
    01775    c.confno = 0;
    01776    c.confmode = ZT_CONF_NORMAL;
    01777    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
    01778    if (res) {
    01779       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
    01780       return -1;
    01781    }
    01782    if (option_debug)
    01783       ast_log(LOG_DEBUG, "Disabled conferencing\n");
    01784    return 0;
    01785 }

static int send_callerid | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1829 of file chan_zap.c.

References ast_log(), zt_pvt::callwaitcas, CIDCW_EXPIRE_SAMPLES, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_setlinear().

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

    01830 {
    01831    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
    01832    int res;
    01833    /* Take out of linear mode if necessary */
    01834    if (p->subs[SUB_REAL].linear) {
    01835       p->subs[SUB_REAL].linear = 0;
    01836       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
    01837    }
    01838    while(p->cidpos < p->cidlen) {
    01839       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
    01840       if (res < 0) {
    01841          if (errno == EAGAIN)
    01842             return 0;
    01843          else {
    01844             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
    01845             return -1;
    01846          }
    01847       }
    01848       if (!res)
    01849          return 0;
    01850       p->cidpos += res;
    01851    }
    01852    free(p->cidspill);
    01853    p->cidspill = NULL;
    01854    if (p->callwaitcas) {
    01855       /* Wait for CID/CW to expire */
    01856       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
    01857    } else
    01858       restore_conference(p);
    01859    return 0;
    01860 }

int send_cwcidspill | ( | struct zt_pvt * | p | ) |

Definition at line 1805 of file chan_zap.c.

References ast_callerid_callwaiting_generate(), AST_LAW, ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, malloc, MAX_CALLERID_SIZE, option_verbose, READ_SIZE, send_callerid(), and VERBOSE_PREFIX_3.

Referenced by zt_handle_dtmfup().

    01806 {
    01807    p->callwaitcas = 0;
    01808    p->cidcwexpire = 0;
    01809    p->cidspill = malloc(MAX_CALLERID_SIZE);
    01810    if (p->cidspill) {
    01811       memset(p->cidspill, 0x7f, MAX_CALLERID_SIZE);
    01812       p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
    01813       /* Make sure we account for the end */
    01814       p->cidlen += READ_SIZE * 4;
    01815       p->cidpos = 0;
    01816       send_callerid(p);
    01817       if (option_verbose > 2)
    01818          ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
    01819    } else return -1;
    01820    return 0;
    01821 }

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

Definition at line 1695 of file chan_zap.c.

References set_actual_rxgain(), and set_actual_txgain().

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

    01696 {
    01697    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
    01698 }

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

Definition at line 1677 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

    01678 {
    01679    struct zt_gains g;
    01680    int res;
    01681
    01682    memset(&g, 0, sizeof(g));
    01683    g.chan = chan;
    01684    res = ioctl(fd, ZT_GETGAINS, &g);
    01685    if (res) {
    01686       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
    01687       return res;
    01688    }
    01689
    01690    fill_rxgain(&g, gain, law);
    01691
    01692    return ioctl(fd, ZT_SETGAINS, &g);
    01693 }

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

Definition at line 1659 of file chan_zap.c.

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

Referenced by set_actual_gain(), and zt_setoption().

    01660 {
    01661    struct zt_gains g;
    01662    int res;
    01663
    01664    memset(&g, 0, sizeof(g));
    01665    g.chan = chan;
    01666    res = ioctl(fd, ZT_GETGAINS, &g);
    01667    if (res) {
    01668       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
    01669       return res;
    01670    }
    01671
    01672    fill_txgain(&g, gain, law);
    01673
    01674    return ioctl(fd, ZT_SETGAINS, &g);
    01675 }

static int setup_zap | ( | int | reload | ) | `[static]`

Definition at line 10310 of file chan_zap.c.

References zt_chan_conf::accountcode, zt_chan_conf::adsi, zt_chan_conf::amaflags, zt_chan_conf::answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_get_group(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose(), zt_chan_conf::busy_quietlength, zt_chan_conf::busy_tonelength, zt_chan_conf::busycount, zt_chan_conf::busydetect, zt_chan_conf::callergroup, zt_chan_conf::callprogress, zt_chan_conf::callreturn, zt_chan_conf::callwaiting, zt_chan_conf::callwaitingcallerid, zt_chan_conf::cancallforward, zt_chan_conf::canpark, cfg, CHAN_PSEUDO, zt_chan_conf::cid_name, zt_chan_conf::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_V23, zt_chan_conf::cid_signalling, zt_chan_conf::cid_start, CID_START_POLARITY, CID_START_RING, zt_chan_conf::context, ringContextData::contextData, zt_chan_conf::debounce, drings, DSP_DIGITMODE_RELAXDTMF, zt_chan_conf::echocanbridged, zt_chan_conf::echocancel, zt_chan_conf::echotraining, zt_chan_conf::flash, zt_chan_conf::group, zt_chan_conf::hanguponpolarityswitch, zt_chan_conf::hidecallerid, zt_chan_conf::immediate, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, zt_chan_conf::mailbox, mkintf(), zt_chan_conf::musicclass, ast_variable::name, ast_variable::next, NUM_CADENCE_MAX, option_verbose, zt_chan_conf::pickupgroup, zt_chan_conf::polarityonanswerdelay, zt_chan_conf::preflash, zt_chan_conf::prewink, zt_chan_conf::pri, zt_chan_conf::priexclusive, zt_chan_conf::priindication_oob, zt_chan_conf::pulse, zt_chan_conf::radio, READ_SIZE, zt_chan_conf::relaxdtmf, restart_monitor(), zt_chan_conf::restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_chan_conf::rxflash, zt_chan_conf::rxgain, zt_chan_conf::rxwink, zt_chan_conf::sendcalleridafter, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, zt_chan_conf::signalling, zt_chan_conf::start, zt_chan_conf::stripmsd, strsep(), zt_chan_conf::threewaycalling, zt_chan_conf::tonezone, zt_chan_conf::transfer, zt_chan_conf::transfertobusy, zt_chan_conf::txgain, zt_chan_conf::use_callerid, zt_chan_conf::use_callingpres, ast_variable::value, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_chan_conf::wink, zt_chan_conf::zaptrcallerid, and zt_chan_conf_default().

Referenced by load_module(), and reload().

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

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

Definition at line 5371 of file chan_zap.c.

References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_moh_stop(), ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_read(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_shrink_phone_number(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_V23, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, callerid_state::flags, ast_frame::frametype, free, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, ast_channel::language, zt_pvt::lastcid_num, callerid_state::len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, callerid_state::number, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::transfer, ast_channel::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().

Referenced by handle_init_event(), and zt_handle_event().

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

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

Definition at line 1012 of file chan_zap.c.

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

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

    01013 {
    01014    int tchan;
    01015    int tinthreeway;
    01016    struct ast_channel *towner;
    01017
    01018    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
    01019
    01020    tchan = p->subs[a].chan;
    01021    towner = p->subs[a].owner;
    01022    tinthreeway = p->subs[a].inthreeway;
    01023
    01024    p->subs[a].chan = p->subs[b].chan;
    01025    p->subs[a].owner = p->subs[b].owner;
    01026    p->subs[a].inthreeway = p->subs[b].inthreeway;
    01027
    01028    p->subs[b].chan = tchan;
    01029    p->subs[b].owner = towner;
    01030    p->subs[b].inthreeway = tinthreeway;
    01031
    01032    if (p->subs[a].owner)
    01033       p->subs[a].owner->fds[0] = p->subs[a].zfd;
    01034    if (p->subs[b].owner)
    01035       p->subs[b].owner->fds[0] = p->subs[b].zfd;
    01036    wakeup_sub(p, a, NULL);
    01037    wakeup_sub(p, b, NULL);
    01038 }

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

Definition at line 1141 of file chan_zap.c.

References ast_log(), zt_subchannel::chan, zt_pvt::channel, zt_subchannel::curconf, zt_subchannel::inthreeway, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, zt_subchannel::owner, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::subs, zt_subchannel::zfd, and zt_close().

    01142 {
    01143    if (!x) {
    01144       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
    01145       return -1;
    01146    }
    01147    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
    01148    if (p->subs[x].zfd > -1) {
    01149       zt_close(p->subs[x].zfd);
    01150    }
    01151    p->subs[x].zfd = -1;
    01152    p->subs[x].linear = 0;
    01153    p->subs[x].chan = 0;
    01154    p->subs[x].owner = NULL;
    01155    p->subs[x].inthreeway = 0;
    01156    p->polarity = POLARITY_IDLE;
    01157    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
    01158    return 0;
    01159 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 10300 of file chan_zap.c.

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

    10301 {
    10302 #ifdef ZAPATA_PRI
    10303    int y;
    10304    for (y=0;y<NUM_SPANS;y++)
    10305       ast_mutex_destroy(&pris[y].lock);
    10306 #endif
    10307    return __unload_module();
    10308 }

static int update_conf | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1471 of file chan_zap.c.

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

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

    01472 {
    01473    int needconf = 0;
    01474    int x;
    01475    int useslavenative;
    01476    struct zt_pvt *slave = NULL;
    01477
    01478    useslavenative = isslavenative(p, &slave);
    01479    /* Start with the obvious, general stuff */
    01480    for (x=0;x<3;x++) {
    01481       /* Look for three way calls */
    01482       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
    01483          conf_add(p, &p->subs[x], x, 0);
    01484          needconf++;
    01485       } else {
    01486          conf_del(p, &p->subs[x], x);
    01487       }
    01488    }
    01489    /* If we have a slave, add him to our conference now. or DAX
    01490       if this is slave native */
    01491    for (x=0;x<MAX_SLAVES;x++) {
    01492       if (p->slaves[x]) {
    01493          if (useslavenative)
    01494             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
    01495          else {
    01496             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
    01497             needconf++;
    01498          }
    01499       }
    01500    }
    01501    /* If we're supposed to be in there, do so now */
    01502    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
    01503       if (useslavenative)
    01504          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
    01505       else {
    01506          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
    01507          needconf++;
    01508       }
    01509    }
    01510    /* If we have a master, add ourselves to his conference */
    01511    if (p->master) {
    01512       if (isslavenative(p->master, NULL)) {
    01513          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
    01514       } else {
    01515          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
    01516       }
    01517    }
    01518    if (!needconf) {
    01519       /* Nobody is left (or should be left) in our conference.
    01520          Kill it.  */
    01521       p->confno = -1;
    01522    }
    01523    ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
    01524    return 0;
    01525 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 11261 of file chan_zap.c.

    11262 {
    11263    return usecnt;
    11264 }

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

Definition at line 951 of file chan_zap.c.

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

Referenced by swap_subs().

    00953 {
    00954    struct ast_frame null = { AST_FRAME_NULL, };
    00955 #ifdef ZAPATA_PRI
    00956    if (pri)
    00957       ast_mutex_unlock(&pri->lock);
    00958 #endif
    00959    for (;;) {
    00960       if (p->subs[a].owner) {
    00961          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
    00962             ast_mutex_unlock(&p->lock);
    00963             usleep(1);
    00964             ast_mutex_lock(&p->lock);
    00965          } else {
    00966             ast_queue_frame(p->subs[a].owner, &null);
    00967             ast_mutex_unlock(&p->subs[a].owner->lock);
    00968             break;
    00969          }
    00970       } else
    00971          break;
    00972    }
    00973 #ifdef ZAPATA_PRI
    00974    if (pri)
    00975       ast_mutex_lock(&pri->lock);
    00976 #endif
    00977 }

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

Definition at line 9694 of file chan_zap.c.

References zt_pvt::channel, destroy_channel(), iflist, zt_pvt::next, zt_pvt::prev, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    09695 {
    09696    int channel = 0;
    09697    struct zt_pvt *tmp = NULL;
    09698    struct zt_pvt *prev = NULL;
    09699
    09700    if (argc != 4) {
    09701       return RESULT_SHOWUSAGE;
    09702    }
    09703    channel = atoi(argv[3]);
    09704
    09705    tmp = iflist;
    09706    while (tmp) {
    09707       if (tmp->channel == channel) {
    09708          destroy_channel(prev, tmp, 1);
    09709          return RESULT_SUCCESS;
    09710       }
    09711       prev = tmp;
    09712       tmp = tmp->next;
    09713    }
    09714    return RESULT_FAILURE;
    09715 }

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

Definition at line 10042 of file chan_zap.c.

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

Referenced by action_transfer(), and action_transferhangup().

    10043 {
    10044    if (p) {
    10045       switch(mode) {
    10046          case TRANSFER:
    10047             p->fake_event = ZT_EVENT_WINKFLASH;
    10048             break;
    10049          case HANGUP:
    10050             p->fake_event = ZT_EVENT_ONHOOK;
    10051             break;
    10052          default:
    10053             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);
    10054       }
    10055    }
    10056    return 0;
    10057 }

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

Definition at line 982 of file chan_zap.c.

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

Referenced by action_zapdialoffhook().

    00984 {
    00985    /* We must unlock the PRI to avoid the possibility of a deadlock */
    00986 #ifdef ZAPATA_PRI
    00987    if (pri)
    00988       ast_mutex_unlock(&pri->lock);
    00989 #endif
    00990    for (;;) {
    00991       if (p->owner) {
    00992          if (ast_mutex_trylock(&p->owner->lock)) {
    00993             ast_mutex_unlock(&p->lock);
    00994             usleep(1);
    00995             ast_mutex_lock(&p->lock);
    00996          } else {
    00997             ast_queue_frame(p->owner, f);
    00998             ast_mutex_unlock(&p->owner->lock);
    00999             break;
    01000          }
    01001       } else
    01002          break;
    01003    }
    01004 #ifdef ZAPATA_PRI
    01005    if (pri)
    01006       ast_mutex_lock(&pri->lock);
    01007 #endif
    01008 }

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

Definition at line 9778 of file chan_zap.c.

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

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

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

Definition at line 9717 of file chan_zap.c.

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

    09718 {
    09719 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
    09720 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
    09721    struct zt_pvt *tmp = NULL;
    09722    char tmps[20] = "";
    09723    ast_mutex_t *lock;
    09724    struct zt_pvt *start;
    09725 #ifdef ZAPATA_PRI
    09726    int trunkgroup;
    09727    struct zt_pri *pri=NULL;
    09728    int x;
    09729 #endif
    09730
    09731    lock = &iflock;
    09732    start = iflist;
    09733
    09734 #ifdef ZAPATA_PRI
    09735    if (argc == 4) {
    09736       if ((trunkgroup = atoi(argv[3])) < 1)
    09737          return RESULT_SHOWUSAGE;
    09738       for (x=0;x<NUM_SPANS;x++) {
    09739          if (pris[x].trunkgroup == trunkgroup) {
    09740             pri = pris + x;
    09741             break;
    09742          }
    09743       }
    09744       if (pri) {
    09745          start = pri->crvs;
    09746          lock = &pri->lock;
    09747       } else {
    09748          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
    09749          return RESULT_FAILURE;
    09750       }
    09751    } else
    09752 #endif
    09753    if (argc != 3)
    09754       return RESULT_SHOWUSAGE;
    09755
    09756    ast_mutex_lock(lock);
    09757 #ifdef ZAPATA_PRI
    09758    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MusicOnHold");
    09759 #else
    09760    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MusicOnHold");
    09761 #endif
    09762
    09763    tmp = start;
    09764    while (tmp) {
    09765       if (tmp->channel > 0) {
    09766          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
    09767       } else
    09768          ast_copy_string(tmps, "pseudo", sizeof(tmps));
    09769       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->musicclass);
    09770       tmp = tmp->next;
    09771    }
    09772    ast_mutex_unlock(lock);
    09773    return RESULT_SUCCESS;
    09774 #undef FORMAT
    09775 #undef FORMAT2
    09776 }

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

Definition at line 9949 of file chan_zap.c.

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

    09949                                                            {
    09950    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
    09951    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
    09952
    09953    int span;
    09954    int res;
    09955    char alarms[50];
    09956
    09957    int ctl;
    09958    ZT_SPANINFO s;
    09959
    09960    ctl = open("/dev/zap/ctl", O_RDWR);
    09961    if (ctl < 0) {
    09962       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
    09963       ast_cli(fd, "No Zaptel interface found.\n");
    09964       return RESULT_FAILURE;
    09965    }
    09966    ast_cli(fd,FORMAT2, "Description", "Alarms","IRQ","bpviol","CRC4");
    09967
    09968    for (span=1;span < ZT_MAX_SPANS;++span) {
    09969       s.spanno = span;
    09970       res = ioctl(ctl, ZT_SPANSTAT, &s);
    09971       if (res) {
    09972          continue;
    09973       }
    09974       alarms[0] = '\0';
    09975       if (s.alarms > 0) {
    09976          if (s.alarms & ZT_ALARM_BLUE)
    09977             strcat(alarms,"BLU/");
    09978          if (s.alarms & ZT_ALARM_YELLOW)
    09979             strcat(alarms, "YEL/");
    09980          if (s.alarms & ZT_ALARM_RED)
    09981             strcat(alarms, "RED/");
    09982          if (s.alarms & ZT_ALARM_LOOPBACK)
    09983             strcat(alarms,"LB/");
    09984          if (s.alarms & ZT_ALARM_RECOVER)
    09985             strcat(alarms,"REC/");
    09986          if (s.alarms & ZT_ALARM_NOTOPEN)
    09987             strcat(alarms, "NOP/");
    09988          if (!strlen(alarms))
    09989             strcat(alarms, "UUU/");
    09990          if (strlen(alarms)) {
    09991             /* Strip trailing / */
    09992             alarms[strlen(alarms)-1]='\0';
    09993          }
    09994       } else {
    09995          if (s.numchans)
    09996             strcpy(alarms, "OK");
    09997          else
    09998             strcpy(alarms, "UNCONFIGURED");
    09999       }
    10000
    10001       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
    10002    }
    10003    close(ctl);
    10004
    10005    return RESULT_SUCCESS;
    10006 #undef FORMAT
    10007 #undef FORMAT2
    10008 }

static char* zap_sig2str | ( | int | sig | ) | `[static]`

Definition at line 1283 of file chan_zap.c.

References SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.

    01284 {
    01285    static char buf[256];
    01286    switch(sig) {
    01287    case SIG_EM:
    01288       return "E & M Immediate";
    01289    case SIG_EMWINK:
    01290       return "E & M Wink";
    01291    case SIG_EM_E1:
    01292       return "E & M E1";
    01293    case SIG_FEATD:
    01294       return "Feature Group D (DTMF)";
    01295    case SIG_FEATDMF:
    01296       return "Feature Group D (MF)";
    01297    case SIG_FEATDMF_TA:
    01298       return "Feature Groud D (MF) Tandem Access";
    01299    case SIG_FEATB:
    01300       return "Feature Group B (MF)";
    01301    case SIG_E911:
    01302       return "E911 (MF)";
    01303    case SIG_FXSLS:
    01304       return "FXS Loopstart";
    01305    case SIG_FXSGS:
    01306       return "FXS Groundstart";
    01307    case SIG_FXSKS:
    01308       return "FXS Kewlstart";
    01309    case SIG_FXOLS:
    01310       return "FXO Loopstart";
    01311    case SIG_FXOGS:
    01312       return "FXO Groundstart";
    01313    case SIG_FXOKS:
    01314       return "FXO Kewlstart";
    01315    case SIG_PRI:
    01316       return "PRI Signalling";
    01317    case SIG_R2:
    01318       return "R2 Signalling";
    01319    case SIG_SF:
    01320       return "SF (Tone) Signalling Immediate";
    01321    case SIG_SFWINK:
    01322       return "SF (Tone) Signalling Wink";
    01323    case SIG_SF_FEATD:
    01324       return "SF (Tone) Signalling with Feature Group D (DTMF)";
    01325    case SIG_SF_FEATDMF:
    01326       return "SF (Tone) Signalling with Feature Group D (MF)";
    01327    case SIG_SF_FEATB:
    01328       return "SF (Tone) Signalling with Feature Group B (MF)";
    01329    case SIG_GR303FXOKS:
    01330       return "GR-303 Signalling with FXOKS";
    01331    case SIG_GR303FXSKS:
    01332       return "GR-303 Signalling with FXSKS";
    01333    case 0:
    01334       return "Pseudo Signalling";
    01335    default:
    01336       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
    01337       return buf;
    01338    }
    01339 }

static int zt_answer | ( | struct ast_channel * | ast | ) | `[static]`

Definition at line 2790 of file chan_zap.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_subchannel::inthreeway, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().

    02791 {
    02792    struct zt_pvt *p = ast->tech_pvt;
    02793    int res=0;
    02794    int index;
    02795    int oldstate = ast->_state;
    02796    ast_setstate(ast, AST_STATE_UP);
    02797    ast_mutex_lock(&p->lock);
    02798    index = zt_get_index(ast, p, 0);
    02799    if (index < 0)
    02800       index = SUB_REAL;
    02801    /* nothing to do if a radio channel */
    02802    if (p->radio) {
    02803       ast_mutex_unlock(&p->lock);
    02804       return 0;
    02805    }
    02806    switch(p->sig) {
    02807    case SIG_FXSLS:
    02808    case SIG_FXSGS:
    02809    case SIG_FXSKS:
    02810       p->ringt = 0;
    02811       /* Fall through */
    02812    case SIG_EM:
    02813    case SIG_EM_E1:
    02814    case SIG_EMWINK:
    02815    case SIG_FEATD:
    02816    case SIG_FEATDMF:
    02817    case SIG_E911:
    02818    case SIG_FEATB:
    02819    case SIG_SF:
    02820    case SIG_SFWINK:
    02821    case SIG_SF_FEATD:
    02822    case SIG_SF_FEATDMF:
    02823    case SIG_SF_FEATB:
    02824    case SIG_FXOLS:
    02825    case SIG_FXOGS:
    02826    case SIG_FXOKS:
    02827       /* Pick up the line */
    02828       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
    02829       if(p->hanguponpolarityswitch) {
    02830          gettimeofday(&p->polaritydelaytv, NULL);
    02831       }
    02832       res =  zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
    02833       tone_zone_play_tone(p->subs[index].zfd, -1);
    02834       p->dialing = 0;
    02835       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
    02836          if (oldstate == AST_STATE_RINGING) {
    02837             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
    02838             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
    02839             swap_subs(p, SUB_THREEWAY, SUB_REAL);
    02840             p->owner = p->subs[SUB_REAL].owner;
    02841          }
    02842       }
    02843       if (p->sig & __ZT_SIG_FXS) {
    02844          zt_enable_ec(p);
    02845          zt_train_ec(p);
    02846       }
    02847       break;
    02848 #ifdef ZAPATA_PRI
    02849    case SIG_PRI:
    02850       /* Send a pri acknowledge */
    02851       if (!pri_grab(p, p->pri)) {
    02852          p->proceeding = 1;
    02853          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
    02854          pri_rel(p->pri);
    02855       } else {
    02856          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    02857          res= -1;
    02858       }
    02859       break;
    02860 #endif
    02861 #ifdef ZAPATA_R2
    02862    case SIG_R2:
    02863       res = mfcr2_AnswerCall(p->r2, NULL);
    02864       if (res)
    02865          ast_log(LOG_WARNING, "R2 Answer call failed :( on %s\n", ast->name);
    02866       break;
    02867 #endif
    02868    case 0:
    02869       ast_mutex_unlock(&p->lock);
    02870       return 0;
    02871    default:
    02872       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
    02873       res = -1;
    02874    }
    02875    ast_mutex_unlock(&p->lock);
    02876    return res;
    02877 }

static enum ast_bridge_result zt_bridge | ( | struct ast_channel * | c0,
|  | struct ast_channel * | c1,
|  | int | flags,
|  | struct ast_frame ** | fo,
|  | struct ast_channel ** | rc,
|  | int | timeoutms |
| ) |  |  | `[static]`

Definition at line 3147 of file chan_zap.c.

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

    03148 {
    03149    struct ast_channel *who;
    03150    struct zt_pvt *p0, *p1, *op0, *op1;
    03151    struct zt_pvt *master = NULL, *slave = NULL;
    03152    struct ast_frame *f;
    03153    int inconf = 0;
    03154    int nothingok = 1;
    03155    int ofd0, ofd1;
    03156    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
    03157    int os0 = -1, os1 = -1;
    03158    int priority = 0;
    03159    struct ast_channel *oc0, *oc1;
    03160    enum ast_bridge_result res;
    03161
    03162 #ifdef PRI_2BCT
    03163    int triedtopribridge = 0;
    03164    q931_call *q931c0 = NULL, *q931c1 = NULL;
    03165 #endif
    03166
    03167    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
    03168       There is code below to handle it properly until DTMF is actually seen,
    03169       but due to currently unresolved issues it's ignored...
    03170    */
    03171
    03172    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
    03173       return AST_BRIDGE_FAILED_NOWARN;
    03174
    03175    ast_mutex_lock(&c0->lock);
    03176    ast_mutex_lock(&c1->lock);
    03177
    03178    p0 = c0->tech_pvt;
    03179    p1 = c1->tech_pvt;
    03180    /* cant do pseudo-channels here */
    03181    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
    03182       ast_mutex_unlock(&c0->lock);
    03183       ast_mutex_unlock(&c1->lock);
    03184       return AST_BRIDGE_FAILED_NOWARN;
    03185    }
    03186
    03187    oi0 = zt_get_index(c0, p0, 0);
    03188    oi1 = zt_get_index(c1, p1, 0);
    03189    if ((oi0 < 0) || (oi1 < 0)) {
    03190       ast_mutex_unlock(&c0->lock);
    03191       ast_mutex_unlock(&c1->lock);
    03192       return AST_BRIDGE_FAILED;
    03193    }
    03194
    03195    op0 = p0 = c0->tech_pvt;
    03196    op1 = p1 = c1->tech_pvt;
    03197    ofd0 = c0->fds[0];
    03198    ofd1 = c1->fds[0];
    03199    oc0 = p0->owner;
    03200    oc1 = p1->owner;
    03201
    03202    if (ast_mutex_trylock(&p0->lock)) {
    03203       /* Don't block, due to potential for deadlock */
    03204       ast_mutex_unlock(&c0->lock);
    03205       ast_mutex_unlock(&c1->lock);
    03206       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
    03207       return AST_BRIDGE_RETRY;
    03208    }
    03209    if (ast_mutex_trylock(&p1->lock)) {
    03210       /* Don't block, due to potential for deadlock */
    03211       ast_mutex_unlock(&p0->lock);
    03212       ast_mutex_unlock(&c0->lock);
    03213       ast_mutex_unlock(&c1->lock);
    03214       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
    03215       return AST_BRIDGE_RETRY;
    03216    }
    03217
    03218    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
    03219       if (p0->owner && p1->owner) {
    03220          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
    03221          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
    03222             master = p0;
    03223             slave = p1;
    03224             inconf = 1;
    03225          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
    03226             master = p1;
    03227             slave = p0;
    03228             inconf = 1;
    03229          } else {
    03230             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
    03231             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
    03232                p0->channel,
    03233                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
    03234                p0->subs[SUB_REAL].inthreeway, p0->channel,
    03235                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
    03236                p1->subs[SUB_REAL].inthreeway);
    03237          }
    03238          nothingok = 0;
    03239       }
    03240    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
    03241       if (p1->subs[SUB_THREEWAY].inthreeway) {
    03242          master = p1;
    03243          slave = p0;
    03244          nothingok = 0;
    03245       }
    03246    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
    03247       if (p0->subs[SUB_THREEWAY].inthreeway) {
    03248          master = p0;
    03249          slave = p1;
    03250          nothingok = 0;
    03251       }
    03252    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
    03253       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise,
    03254          don't put us in anything */
    03255       if (p1->subs[SUB_CALLWAIT].inthreeway) {
    03256          master = p1;
    03257          slave = p0;
    03258          nothingok = 0;
    03259       }
    03260    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
    03261       /* Same as previous */
    03262       if (p0->subs[SUB_CALLWAIT].inthreeway) {
    03263          master = p0;
    03264          slave = p1;
    03265          nothingok = 0;
    03266       }
    03267    }
    03268    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
    03269       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
    03270    if (master && slave) {
    03271       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
    03272          in an active threeway call with a channel that is ringing, we should
    03273          indicate ringing. */
    03274       if ((oi1 == SUB_THREEWAY) &&
    03275           p1->subs[SUB_THREEWAY].inthreeway &&
    03276           p1->subs[SUB_REAL].owner &&
    03277           p1->subs[SUB_REAL].inthreeway &&
    03278           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
    03279          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
    03280          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
    03281          os1 = p1->subs[SUB_REAL].owner->_state;
    03282       } else {
    03283          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
    03284          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
    03285       }
    03286       if ((oi0 == SUB_THREEWAY) &&
    03287           p0->subs[SUB_THREEWAY].inthreeway &&
    03288           p0->subs[SUB_REAL].owner &&
    03289           p0->subs[SUB_REAL].inthreeway &&
    03290           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
    03291          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
    03292          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
    03293          os0 = p0->subs[SUB_REAL].owner->_state;
    03294       } else {
    03295          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
    03296          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
    03297       }
    03298       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
    03299          if (!p0->echocanbridged || !p1->echocanbridged) {
    03300             /* Disable echo cancellation if appropriate */
    03301             zt_disable_ec(p0);
    03302             zt_disable_ec(p1);
    03303          }
    03304       }
    03305       zt_link(slave, master);
    03306       master->inconference = inconf;
    03307    } else if (!nothingok)
    03308       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
    03309
    03310    update_conf(p0);
    03311    update_conf(p1);
    03312    t0 = p0->subs[SUB_REAL].inthreeway;
    03313    t1 = p1->subs[SUB_REAL].inthreeway;
    03314
    03315    ast_mutex_unlock(&p0->lock);
    03316    ast_mutex_unlock(&p1->lock);
    03317
    03318    ast_mutex_unlock(&c0->lock);
    03319    ast_mutex_unlock(&c1->lock);
    03320
    03321    /* Native bridge failed */
    03322    if ((!master || !slave) && !nothingok) {
    03323       zt_enable_ec(p0);
    03324       zt_enable_ec(p1);
    03325       return AST_BRIDGE_FAILED;
    03326    }
    03327
    03328    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
    03329       disable_dtmf_detect(op0);
    03330
    03331    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
    03332       disable_dtmf_detect(op1);
    03333
    03334    for (;;) {
    03335       struct ast_channel *c0_priority[2] = {c0, c1};
    03336       struct ast_channel *c1_priority[2] = {c1, c0};
    03337
    03338       /* Here's our main loop...  Start by locking things, looking for private parts,
    03339          and then balking if anything is wrong */
    03340       ast_mutex_lock(&c0->lock);
    03341       ast_mutex_lock(&c1->lock);
    03342       p0 = c0->tech_pvt;
    03343       p1 = c1->tech_pvt;
    03344
    03345       if (op0 == p0)
    03346          i0 = zt_get_index(c0, p0, 1);
    03347       if (op1 == p1)
    03348          i1 = zt_get_index(c1, p1, 1);
    03349       ast_mutex_unlock(&c0->lock);
    03350       ast_mutex_unlock(&c1->lock);
    03351
    03352       if (!timeoutms ||
    03353           (op0 != p0) ||
    03354           (op1 != p1) ||
    03355           (ofd0 != c0->fds[0]) ||
    03356           (ofd1 != c1->fds[0]) ||
    03357           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) ||
    03358           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) ||
    03359           (oc0 != p0->owner) ||
    03360           (oc1 != p1->owner) ||
    03361           (t0 != p0->subs[SUB_REAL].inthreeway) ||
    03362           (t1 != p1->subs[SUB_REAL].inthreeway) ||
    03363           (oi0 != i0) ||
    03364           (oi1 != i1)) {
    03365          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
    03366             op0->channel, oi0, op1->channel, oi1);
    03367          res = AST_BRIDGE_RETRY;
    03368          goto return_from_bridge;
    03369       }
    03370
    03371 #ifdef PRI_2BCT
    03372       q931c0 = p0->call;
    03373       q931c1 = p1->call;
    03374       if (p0->transfer && p1->transfer
    03375           && q931c0 && q931c1
    03376           && !triedtopribridge) {
    03377          pri_channel_bridge(q931c0, q931c1);
    03378          triedtopribridge = 1;
    03379       }
    03380 #endif
    03381
    03382       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
    03383       if (!who) {
    03384          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
    03385          continue;
    03386       }
    03387       f = ast_read(who);
    03388       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
    03389          *fo = f;
    03390          *rc = who;
    03391          res = AST_BRIDGE_COMPLETE;
    03392          goto return_from_bridge;
    03393       }
    03394       if (f->frametype == AST_FRAME_DTMF) {
    03395          if ((who == c0) && p0->pulsedial) {
    03396             ast_write(c1, f);
    03397          } else if ((who == c1) && p1->pulsedial) {
    03398             ast_write(c0, f);
    03399          } else {
    03400             *fo = f;
    03401             *rc = who;
    03402             res = AST_BRIDGE_COMPLETE;
    03403             goto return_from_bridge;
    03404          }
    03405       }
    03406       ast_frfree(f);
    03407
    03408       /* Swap who gets priority */
    03409       priority = !priority;
    03410    }
    03411
    03412 return_from_bridge:
    03413    if (op0 == p0)
    03414       zt_enable_ec(p0);
    03415
    03416    if (op1 == p1)
    03417       zt_enable_ec(p1);
    03418
    03419    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
    03420       enable_dtmf_detect(op0);
    03421
    03422    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
    03423       enable_dtmf_detect(op1);
    03424
    03425    zt_unlink(slave, master, 1);
    03426
    03427    return res;
    03428 }

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

Definition at line 1893 of file chan_zap.c.

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

    01894 {
    01895    struct zt_pvt *p = ast->tech_pvt;
    01896    int x, res, index;
    01897    char *c, *n, *l;
    01898 #ifdef ZAPATA_PRI
    01899    char *s=NULL;
    01900 #endif
    01901    char dest[256]; /* must be same length as p->dialdest */
    01902    ast_mutex_lock(&p->lock);
    01903    ast_copy_string(dest, rdest, sizeof(dest));
    01904    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
    01905    if ((ast->_state == AST_STATE_BUSY)) {
    01906       p->subs[SUB_REAL].needbusy = 1;
    01907       ast_mutex_unlock(&p->lock);
    01908       return 0;
    01909    }
    01910    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
    01911       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
    01912       ast_mutex_unlock(&p->lock);
    01913       return -1;
    01914    }
    01915    p->dialednone = 0;
    01916    if (p->radio)  /* if a radio channel, up immediately */
    01917    {
    01918       /* Special pseudo -- automatically up */
    01919       ast_setstate(ast, AST_STATE_UP);
    01920       ast_mutex_unlock(&p->lock);
    01921       return 0;
    01922    }
    01923    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
    01924    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
    01925    if (res)
    01926       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
    01927    p->outgoing = 1;
    01928
    01929    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
    01930
    01931    switch(p->sig) {
    01932    case SIG_FXOLS:
    01933    case SIG_FXOGS:
    01934    case SIG_FXOKS:
    01935       if (p->owner == ast) {
    01936          /* Normal ring, on hook */
    01937
    01938          /* Don't send audio while on hook, until the call is answered */
    01939          p->dialing = 1;
    01940          if (p->use_callerid) {
    01941             /* Generate the Caller-ID spill if desired */
    01942             if (p->cidspill) {
    01943                ast_log(LOG_WARNING, "cidspill already exists??\n");
    01944                free(p->cidspill);
    01945             }
    01946             p->cidspill = malloc(MAX_CALLERID_SIZE);
    01947             p->callwaitcas = 0;
    01948             if (p->cidspill) {
    01949                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
    01950                p->cidpos = 0;
    01951                send_callerid(p);
    01952             } else
    01953                ast_log(LOG_WARNING, "Unable to generate CallerID spill\n");
    01954          }
    01955          /* Choose proper cadence */
    01956          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
    01957             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering-1]))
    01958                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
    01959             p->cidrings = cidrings[p->distinctivering - 1];
    01960          } else {
    01961             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
    01962                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
    01963             p->cidrings = p->sendcalleridafter;
    01964          }
    01965
    01966
    01967          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
    01968          c = strchr(dest, '/');
    01969          if (c)
    01970             c++;
    01971          if (c && (strlen(c) < p->stripmsd)) {
    01972             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
    01973             c = NULL;
    01974          }
    01975          if (c) {
    01976             p->dop.op = ZT_DIAL_OP_REPLACE;
    01977             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
    01978             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
    01979          } else {
    01980             p->dop.dialstr[0] = '\0';
    01981          }
    01982          x = ZT_RING;
    01983          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
    01984             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
    01985             ast_mutex_unlock(&p->lock);
    01986             return -1;
    01987          }
    01988          p->dialing = 1;
    01989       } else {
    01990          /* Call waiting call */
    01991          p->callwaitrings = 0;
    01992          if (ast->cid.cid_num)
    01993             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
    01994          else
    01995             p->callwait_num[0] = '\0';
    01996          if (ast->cid.cid_name)
    01997             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
    01998          else
    01999             p->callwait_name[0] = '\0';
    02000          /* Call waiting tone instead */
    02001          if (zt_callwait(ast)) {
    02002             ast_mutex_unlock(&p->lock);
    02003             return -1;
    02004          }
    02005          /* Make ring-back */
    02006          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
    02007             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
    02008
    02009       }
    02010       n = ast->cid.cid_name;
    02011       l = ast->cid.cid_num;
    02012       if (l)
    02013          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
    02014       else
    02015          p->lastcid_num[0] = '\0';
    02016       if (n)
    02017          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
    02018       else
    02019          p->lastcid_name[0] = '\0';
    02020       ast_setstate(ast, AST_STATE_RINGING);
    02021       index = zt_get_index(ast, p, 0);
    02022       if (index > -1) {
    02023          p->subs[index].needringing = 1;
    02024       }
    02025       break;
    02026    case SIG_FXSLS:
    02027    case SIG_FXSGS:
    02028    case SIG_FXSKS:
    02029    case SIG_EMWINK:
    02030    case SIG_EM:
    02031    case SIG_EM_E1:
    02032    case SIG_FEATD:
    02033    case SIG_FEATDMF:
    02034    case SIG_E911:
    02035    case SIG_FEATB:
    02036    case SIG_SFWINK:
    02037    case SIG_SF:
    02038    case SIG_SF_FEATD:
    02039    case SIG_SF_FEATDMF:
    02040    case SIG_FEATDMF_TA:
    02041    case SIG_SF_FEATB:
    02042       c = strchr(dest, '/');
    02043       if (c)
    02044          c++;
    02045       else
    02046          c = "";
    02047       if (strlen(c) < p->stripmsd) {
    02048          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
    02049          ast_mutex_unlock(&p->lock);
    02050          return -1;
    02051       }
    02052 #ifdef ZAPATA_PRI
    02053       /* Start the trunk, if not GR-303 */
    02054       if (!p->pri) {
    02055 #endif
    02056          x = ZT_START;
    02057          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
    02058          if (res < 0) {
    02059             if (errno != EINPROGRESS) {
    02060                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
    02061                ast_mutex_unlock(&p->lock);
    02062                return -1;
    02063             }
    02064          }
    02065 #ifdef ZAPATA_PRI
    02066       }
    02067 #endif
    02068       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
    02069       p->dop.op = ZT_DIAL_OP_REPLACE;
    02070
    02071       c += p->stripmsd;
    02072
    02073       switch (p->sig) {
    02074       case SIG_FEATD:
    02075          l = ast->cid.cid_num;
    02076          if (l)
    02077             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
    02078          else
    02079             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
    02080          break;
    02081       case SIG_FEATDMF:
    02082          l = ast->cid.cid_num;
    02083          if (l)
    02084             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
    02085          else
    02086             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
    02087          break;
    02088       case SIG_FEATDMF_TA:
    02089       {
    02090          char *cic = NULL, *ozz = NULL;
    02091
    02092          /* If you have to go through a Tandem Access point you need to use this */
    02093          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
    02094          if (!ozz)
    02095             ozz = defaultozz;
    02096          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
    02097          if (!cic)
    02098             cic = defaultcic;
    02099          if (!ozz || !cic) {
    02100             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
    02101             ast_mutex_unlock(&p->lock);
    02102             return -1;
    02103          }
    02104          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
    02105          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
    02106          p->whichwink = 0;
    02107       }
    02108          break;
    02109       case SIG_E911:
    02110          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
    02111          break;
    02112       case SIG_FEATB:
    02113          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
    02114          break;
    02115       default:
    02116          if (p->pulse)
    02117             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
    02118          else
    02119             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
    02120          break;
    02121       }
    02122
    02123       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
    02124          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
    02125          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
    02126          p->echorest[sizeof(p->echorest) - 1] = '\0';
    02127          p->echobreak = 1;
    02128          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
    02129       } else
    02130          p->echobreak = 0;
    02131       if (!res) {
    02132          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
    02133             x = ZT_ONHOOK;
    02134             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
    02135             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
    02136             ast_mutex_unlock(&p->lock);
    02137             return -1;
    02138          }
    02139       } else
    02140          ast_log(LOG_DEBUG, "Deferring dialing...\n");
    02141       p->dialing = 1;
    02142       if (ast_strlen_zero(c))
    02143          p->dialednone = 1;
    02144       ast_setstate(ast, AST_STATE_DIALING);
    02145       break;
    02146    case 0:
    02147       /* Special pseudo -- automatically up*/
    02148       ast_setstate(ast, AST_STATE_UP);
    02149       break;
    02150    case SIG_PRI:
    02151       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
    02152       p->dialdest[0] = '\0';
    02153       break;
    02154    default:
    02155       ast_log(LOG_DEBUG, "not yet implemented\n");
    02156       ast_mutex_unlock(&p->lock);
    02157       return -1;
    02158    }
    02159 #ifdef ZAPATA_PRI
    02160    if (p->pri) {
    02161       struct pri_sr *sr;
    02162 #ifdef SUPPORT_USERUSER
    02163       char *useruser;
    02164 #endif
    02165       int pridialplan;
    02166       int dp_strip;
    02167       int prilocaldialplan;
    02168       int ldp_strip;
    02169       int exclusive;
    02170
    02171       c = strchr(dest, '/');
    02172       if (c)
    02173          c++;
    02174       else
    02175          c = dest;
    02176       if (!p->hidecallerid) {
    02177          l = ast->cid.cid_num;
    02178          n = ast->cid.cid_name;
    02179       } else {
    02180          l = NULL;
    02181          n = NULL;
    02182       }
    02183       if (strlen(c) < p->stripmsd) {
    02184          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
    02185          ast_mutex_unlock(&p->lock);
    02186          return -1;
    02187       }
    02188       if (p->sig != SIG_FXSKS) {
    02189          p->dop.op = ZT_DIAL_OP_REPLACE;
    02190          s = strchr(c + p->stripmsd, 'w');
    02191          if (s) {
    02192             if (strlen(s) > 1)
    02193                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
    02194             else
    02195                p->dop.dialstr[0] = '\0';
    02196             *s = '\0';
    02197          } else {
    02198             p->dop.dialstr[0] = '\0';
    02199          }
    02200       }
    02201       if (pri_grab(p, p->pri)) {
    02202          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
    02203          ast_mutex_unlock(&p->lock);
    02204          return -1;
    02205       }
    02206       if (!(p->call = pri_new_call(p->pri->pri))) {
    02207          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
    02208          pri_rel(p->pri);
    02209          ast_mutex_unlock(&p->lock);
    02210          return -1;
    02211       }
    02212       if (!(sr = pri_sr_new())) {
    02213          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
    02214          pri_rel(p->pri);
    02215          ast_mutex_unlock(&p->lock);
    02216       }
    02217       if (p->bearer || (p->sig == SIG_FXSKS)) {
    02218          if (p->bearer) {
    02219             ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
    02220             p->bearer->call = p->call;
    02221          } else
    02222             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
    02223          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
    02224       }
    02225       p->digital = IS_DIGITAL(ast->transfercapability);
    02226       /* Add support for exclusive override */
    02227       if (p->priexclusive)
    02228          exclusive = 1;
    02229       else {
    02230       /* otherwise, traditional behavior */
    02231          if (p->pri->nodetype == PRI_NETWORK)
    02232             exclusive = 0;
    02233          else
    02234             exclusive = 1;
    02235       }
    02236
    02237       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
    02238       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
    02239                (p->digital ? -1 :
    02240                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
    02241       if (p->pri->facilityenable)
    02242          pri_facility_enable(p->pri->pri);
    02243
    02244       if (option_verbose > 2)
    02245          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
    02246       dp_strip = 0;
    02247       pridialplan = p->pri->dialplan - 1;
    02248       if (pridialplan == -2) { /* compute dynamically */
    02249          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
    02250             dp_strip = strlen(p->pri->internationalprefix);
    02251             pridialplan = PRI_INTERNATIONAL_ISDN;
    02252          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
    02253             dp_strip = strlen(p->pri->nationalprefix);
    02254             pridialplan = PRI_NATIONAL_ISDN;
    02255          } else {
    02256             pridialplan = PRI_LOCAL_ISDN;
    02257          }
    02258       }
    02259       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan,  s ? 1 : 0);
    02260
    02261       ldp_strip = 0;
    02262       prilocaldialplan = p->pri->localdialplan - 1;
    02263       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
    02264          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
    02265             ldp_strip = strlen(p->pri->internationalprefix);
    02266             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
    02267          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
    02268             ldp_strip = strlen(p->pri->nationalprefix);
    02269             prilocaldialplan = PRI_NATIONAL_ISDN;
    02270          } else {
    02271             prilocaldialplan = PRI_LOCAL_ISDN;
    02272          }
    02273       }
    02274       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
    02275               p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
    02276       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL);
    02277
    02278 #ifdef SUPPORT_USERUSER
    02279       /* User-user info */
    02280       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
    02281
    02282       if (useruser)
    02283          pri_sr_set_useruser(sr, useruser);
    02284 #endif
    02285
    02286       if (pri_setup(p->pri->pri, p->call,  sr)) {
    02287          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
    02288                   c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
    02289          pri_rel(p->pri);
    02290          ast_mutex_unlock(&p->lock);
    02291          pri_sr_free(sr);
    02292          return -1;
    02293       }
    02294       pri_sr_free(sr);
    02295       ast_setstate(ast, AST_STATE_DIALING);
    02296       pri_rel(p->pri);
    02297    }
    02298 #endif
    02299    ast_mutex_unlock(&p->lock);
    02300    return 0;
    02301 }

static int zt_callwait | ( | struct ast_channel * | ast | ) | `[static]`

Definition at line 1862 of file chan_zap.c.

References ast_gen_cas(), AST_LAW, ast_log(), zt_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, zt_pvt::callwaitingcallerid, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, LOG_WARNING, malloc, READ_SIZE, save_conference(), send_callerid(), and ast_channel::tech_pvt.

Referenced by zt_call(), and zt_read().

    01863 {
    01864    struct zt_pvt *p = ast->tech_pvt;
    01865    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
    01866    if (p->cidspill) {
    01867       ast_log(LOG_WARNING, "Spill already exists?!?\n");
    01868       free(p->cidspill);
    01869    }
    01870    p->cidspill = malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4);
    01871    if (p->cidspill) {
    01872       save_conference(p);
    01873       /* Silence */
    01874       memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
    01875       if (!p->callwaitrings && p->callwaitingcallerid) {
    01876          ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
    01877          p->callwaitcas = 1;
    01878          p->cidlen = 2400 + 680 + READ_SIZE * 4;
    01879       } else {
    01880          ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
    01881          p->callwaitcas = 0;
    01882          p->cidlen = 2400 + READ_SIZE * 4;
    01883       }
    01884       p->cidpos = 0;
    01885       send_callerid(p);
    01886    } else {
    01887       ast_log(LOG_WARNING, "Unable to create SAS/CAS spill\n");
    01888       return -1;
    01889    }
    01890    return 0;
    01891 }

struct zt_chan_conf zt_chan_conf_default | ( | void |  | ) | `[read]`

returns a new zt_chan_conf with default values (by-value)

Boolean: true to use echo cancelling. Default: True.

Integer: Echo training time. True implies 400.

Boolean: Use pulse dialing. Default: false. Right?

Boolean: true to use echo cancelling even between zaptel channels. Default: false.

Boolean: hangup calls by detecting a busy tone. Default: false.

String. Voicemail box in which to check mail for the channel (mailbox[]). Default: none.

Whether we answer on a Polarity Switch event

Whether we hang up on a Polarity Switch event

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

When to send the CallerID signals (rings)

Definition at line 542 of file chan_zap.c.

References CID_SIG_BELL, CID_START_RING, DEFAULT_CIDRINGS, and zt_chan_conf::pri.

Referenced by setup_zap().

    00542                                                {
    00543    struct zt_chan_conf chan_conf = {
    00544       .pri = {
    00545 #ifdef ZAPATA_PRI
    00546          .minunused = 2,
    00547          .minidle = 0,
    00548          .idleext = "",
    00549          .idledial = "",
    00550          .overlapdial = 0,
    00551          .facilityenable = 0,
    00552          .internationalprefix = "",
    00553          .nationalprefix = "",
    00554          .localprefix = "",
    00555          .privateprefix = "",
    00556          .unknownprefix = "",
    00557          /*!< How often (in seconds) to reset unused channels. Default 1 hour. */
    00558          .resetinterval = 3600,
    00559 #endif
    00560       },
    00561       .context = "default",
    00562       .cid_num = "",
    00563       .cid_name = "",
    00564       .musicclass = "",
    00565       .transfertobusy = 1,
    00566
    00567       .cid_signalling = CID_SIG_BELL,
    00568       .cid_start = CID_START_RING,
    00569       .zaptrcallerid = 0,
    00570       .use_callerid = 1,
    00571       .signalling = -1,
    00572       .group = 0,
    00573       .callergroup = 0,
    00574       .pickupgroup = 0,
    00575
    00576       .relaxdtmf = 0,
    00577       .immediate = 0,
    00578
    00579       .stripmsd = 0,
    00580
    00581       .callwaiting = 0,
    00582
    00583       .callwaitingcallerid = 0,
    00584
    00585       .hidecallerid = 0,
    00586
    00587       .restrictcid = 0,
    00588
    00589       .use_callingpres = 0,
    00590
    00591       .callreturn = 0,
    00592
    00593       .threewaycalling = 0,
    00594
    00595       .transfer = 0,
    00596
    00597       .canpark = 0,
    00598
    00599       .cancallforward = 0,
    00600
    00601       .rxgain = 0.0,
    00602
    00603       .txgain = 0.0,
    00604
    00605       .tonezone = -1,
    00606
    00607       /*! \brief Boolean: true to use echo cancelling. Default: True. */
    00608       .echocancel = 1,
    00609
    00610       /*! \brief Integer: Echo training time. True implies 400. */
    00611       .echotraining = 0,
    00612
    00613       /*! \brief Boolean: Use pulse dialing. Default: false. Right? */
    00614       .pulse = 0,
    00615
    00616       /*! \brief Boolean: true to use echo cancelling even between zaptel
    00617        * channels. Default: false. */
    00618       .echocanbridged = 0,
    00619
    00620       /*! \brief Boolean: hangup calls by detecting a busy tone.
    00621        * Default: false. */
    00622       .busydetect = 0,
    00623
    00624       .busycount = 3,
    00625       .busy_tonelength = 0,
    00626       .busy_quietlength = 0,
    00627
    00628       .callprogress = 0,
    00629
    00630       .accountcode = "",
    00631
    00632       /*! \brief String. Voicemail box in which to check mail for
    00633        * the channel (mailbox[@context]). Default: none. */
    00634       .mailbox = "",
    00635       .amaflags = 0,
    00636
    00637       .adsi = 0,
    00638       .numbufs = 4,
    00639
    00640       .prewink = -1,
    00641       .preflash = -1,
    00642       .wink = -1,
    00643       .flash = -1,
    00644       .start = -1,
    00645       .rxwink = -1,
    00646       .rxflash = -1,
    00647       .debounce = -1,
    00648       .priexclusive = 0,
    00649
    00650       /*! \brief Whether we answer on a Polarity Switch event */
    00651       .answeronpolarityswitch = 0,
    00652
    00653       /*! \brief Whether we hang up on a Polarity Switch event */
    00654       .hanguponpolarityswitch = 0,
    00655
    00656       /*! \brief How long (ms) to ignore Polarity Switch events after we answer a call */
    00657       .polarityonanswerdelay = 600,
    00658
    00659       /*! \brief When to send the CallerID signals (rings) */
    00660       .sendcalleridafter = DEFAULT_CIDRINGS,
    00661
    00662       .priindication_oob = 0,
    00663
    00664       /* Add fields above this comment. "radio" will be
    00665        * kept as the one without the comma. for the moment,
    00666        * until we add all fields.
    00667        */
    00668       .radio = 0
    00669    };
    00670
    00671    return chan_conf;
    00672 }

static void zt_close | ( | int | fd | ) | `[static]`

Definition at line 1081 of file chan_zap.c.

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

    01082 {
    01083    if(fd > 0)
    01084       close(fd);
    01085 }

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

Definition at line 1743 of file chan_zap.c.

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

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

    01744 {
    01745    int x, y, res;
    01746    x = muted;
    01747    if (p->sig == SIG_PRI) {
    01748       y = 1;
    01749       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
    01750       if (res)
    01751          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
    01752    }
    01753    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
    01754    if (res < 0)
    01755       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
    01756    return res;
    01757 }

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

Definition at line 1161 of file chan_zap.c.

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

    01162 {
    01163    ZT_DIAL_OPERATION zo;
    01164    struct zt_pvt *p;
    01165    int res = 0;
    01166    int index;
    01167    p = ast->tech_pvt;
    01168    ast_mutex_lock(&p->lock);
    01169    index = zt_get_index(ast, p, 0);
    01170    if ((index == SUB_REAL) && p->owner) {
    01171 #ifdef ZAPATA_PRI
    01172       if ((p->sig == SIG_PRI) && (ast->_state == AST_STATE_DIALING) && !p->proceeding) {
    01173          if (p->setup_ack) {
    01174             if (!pri_grab(p, p->pri)) {
    01175                pri_information(p->pri->pri,p->call,digit);
    01176                pri_rel(p->pri);
    01177             } else
    01178                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    01179          } else if (strlen(p->dialdest) < sizeof(p->dialdest) - 1) {
    01180             ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
    01181             res = strlen(p->dialdest);
    01182             p->dialdest[res++] = digit;
    01183             p->dialdest[res] = '\0';
    01184          }
    01185       } else {
    01186 #else
    01187       {
    01188 #endif
    01189          zo.op = ZT_DIAL_OP_APPEND;
    01190          zo.dialstr[0] = 'T';
    01191          zo.dialstr[1] = digit;
    01192          zo.dialstr[2] = 0;
    01193          if ((res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
    01194             ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
    01195          else
    01196             p->dialing = 1;
    01197       }
    01198    }
    01199    ast_mutex_unlock(&p->lock);
    01200    return res;
    01201 }

static void zt_disable_ec | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1576 of file chan_zap.c.

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

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

    01577 {
    01578    int x;
    01579    int res;
    01580    if (p->echocancel) {
    01581       x = 0;
    01582       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
    01583       if (res)
    01584          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
    01585       else
    01586          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
    01587    }
    01588    p->echocanon = 0;
    01589 }

static void zt_enable_ec | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1527 of file chan_zap.c.

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

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

    01528 {
    01529    int x;
    01530    int res;
    01531    if (!p)
    01532       return;
    01533    if (p->echocanon) {
    01534       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
    01535       return;
    01536    }
    01537    if (p->digital) {
    01538       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
    01539       return;
    01540    }
    01541    if (p->echocancel) {
    01542       if (p->sig == SIG_PRI) {
    01543          x = 1;
    01544          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
    01545          if (res)
    01546             ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
    01547       }
    01548       x = p->echocancel;
    01549       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
    01550       if (res)
    01551          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
    01552       else {
    01553          p->echocanon = 1;
    01554          ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
    01555       }
    01556    } else
    01557       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
    01558 }

struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | `[read]`

Definition at line 4586 of file chan_zap.c.

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

    04587 {
    04588    struct zt_pvt *p = ast->tech_pvt;
    04589    struct ast_frame *f;
    04590    ast_mutex_lock(&p->lock);
    04591    f = __zt_exception(ast);
    04592    ast_mutex_unlock(&p->lock);
    04593    return f;
    04594 }

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

Definition at line 3430 of file chan_zap.c.

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

    03431 {
    03432    struct zt_pvt *p = newchan->tech_pvt;
    03433    int x;
    03434    ast_mutex_lock(&p->lock);
    03435    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
    03436    if (p->owner == oldchan) {
    03437       p->owner = newchan;
    03438    }
    03439    for (x=0;x<3;x++)
    03440       if (p->subs[x].owner == oldchan) {
    03441          if (!x)
    03442             zt_unlink(NULL, p, 0);
    03443          p->subs[x].owner = newchan;
    03444       }
    03445    if (newchan->_state == AST_STATE_RINGING)
    03446       zt_indicate(newchan, AST_CONTROL_RINGING);
    03447    update_conf(p);
    03448    ast_mutex_unlock(&p->lock);
    03449    return 0;
    03450 }

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

Avoid the silly zt_getevent which ignores a bunch of events.

Definition at line 254 of file chan_zap.c.

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

    00255 {
    00256    int j;
    00257    if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
    00258    return j;
    00259 }

static int zt_get_index | ( | struct ast_channel * | ast,
|  | struct zt_pvt * | p,
|  | int | nullok |
| ) |  |  | `[static]`

Definition at line 931 of file chan_zap.c.

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

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

    00932 {
    00933    int res;
    00934    if (p->subs[0].owner == ast)
    00935       res = 0;
    00936    else if (p->subs[1].owner == ast)
    00937       res = 1;
    00938    else if (p->subs[2].owner == ast)
    00939       res = 2;
    00940    else {
    00941       res = -1;
    00942       if (!nullok)
    00943          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
    00944    }
    00945    return res;
    00946 }

static void zt_handle_dtmfup | ( | struct ast_channel * | ast,
|  | int | index,
|  | struct ast_frame ** | dest |
| ) |  |  | `[static]`

Definition at line 3664 of file chan_zap.c.

References ast_async_goto(), AST_CONTROL_ANSWER, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), ast_strlen_zero(), ast_verbose(), zt_pvt::callprogress, zt_pvt::callwaitcas, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_channel::exten, zt_subchannel::f, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), send_cwcidspill(), ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, VERBOSE_PREFIX_3, and zt_confmute().

Referenced by zt_handle_event(), and zt_read().

    03665 {
    03666    struct zt_pvt *p = ast->tech_pvt;
    03667    struct ast_frame *f = *dest;
    03668
    03669    ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
    03670    if (p->confirmanswer) {
    03671       ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
    03672       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
    03673          of a DTMF digit */
    03674       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    03675       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
    03676       *dest = &p->subs[index].f;
    03677       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
    03678       p->confirmanswer = 0;
    03679    } else if (p->callwaitcas) {
    03680       if ((f->subclass == 'A') || (f->subclass == 'D')) {
    03681          ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
    03682          if (p->cidspill)
    03683             free(p->cidspill);
    03684          send_cwcidspill(p);
    03685       }
    03686       if ((f->subclass != 'm') && (f->subclass != 'u'))
    03687          p->callwaitcas = 0;
    03688       p->subs[index].f.frametype = AST_FRAME_NULL;
    03689       p->subs[index].f.subclass = 0;
    03690       *dest = &p->subs[index].f;
    03691    } else if (f->subclass == 'f') {
    03692       /* Fax tone -- Handle and return NULL */
    03693       if ((p->callprogress & 0x6) && !p->faxhandled) {
    03694          p->faxhandled++;
    03695          if (strcmp(ast->exten, "fax")) {
    03696             const char *target_context = ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext;
    03697
    03698             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
    03699                if (option_verbose > 2)
    03700                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
    03701                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
    03702                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
    03703                if (ast_async_goto(ast, target_context, "fax", 1))
    03704                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
    03705             } else
    03706                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
    03707          } else
    03708             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
    03709       } else
    03710             ast_log(LOG_DEBUG, "Fax already handled\n");
    03711       zt_confmute(p, 0);
    03712       p->subs[index].f.frametype = AST_FRAME_NULL;
    03713       p->subs[index].f.subclass = 0;
    03714       *dest = &p->subs[index].f;
    03715    } else if (f->subclass == 'm') {
    03716       /* Confmute request */
    03717       zt_confmute(p, 1);
    03718       p->subs[index].f.frametype = AST_FRAME_NULL;
    03719       p->subs[index].f.subclass = 0;
    03720       *dest = &p->subs[index].f;
    03721    } else if (f->subclass == 'u') {
    03722       /* Unmute */
    03723       zt_confmute(p, 0);
    03724       p->subs[index].f.frametype = AST_FRAME_NULL;
    03725       p->subs[index].f.subclass = 0;
    03726       *dest = &p->subs[index].f;
    03727    } else
    03728       zt_confmute(p, 0);
    03729 }

static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | `[static, read]`

Definition at line 3731 of file chan_zap.c.

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

Referenced by __zt_exception().

    03732 {
    03733    int res,x;
    03734    int index;
    03735    char *c;
    03736    struct zt_pvt *p = ast->tech_pvt;
    03737    pthread_t threadid;
    03738    pthread_attr_t attr;
    03739    struct ast_channel *chan;
    03740    struct ast_frame *f;
    03741
    03742    index = zt_get_index(ast, p, 0);
    03743    p->subs[index].f.frametype = AST_FRAME_NULL;
    03744    p->subs[index].f.datalen = 0;
    03745    p->subs[index].f.samples = 0;
    03746    p->subs[index].f.mallocd = 0;
    03747    p->subs[index].f.offset = 0;
    03748    p->subs[index].f.src = "zt_handle_event";
    03749    p->subs[index].f.data = NULL;
    03750    f = &p->subs[index].f;
    03751
    03752    if (index < 0)
    03753       return &p->subs[index].f;
    03754    if (p->fake_event) {
    03755       res = p->fake_event;
    03756       p->fake_event = 0;
    03757    } else
    03758       res = zt_get_event(p->subs[index].zfd);
    03759
    03760    ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
    03761
    03762    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
    03763       if (res & ZT_EVENT_PULSEDIGIT)
    03764          p->pulsedial = 1;
    03765       else
    03766          p->pulsedial = 0;
    03767
    03768       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
    03769 #ifdef ZAPATA_PRI
    03770       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
    03771          p->subs[index].f.frametype = AST_FRAME_NULL;
    03772          p->subs[index].f.subclass = 0;
    03773       } else {
    03774 #endif
    03775          p->subs[index].f.frametype = AST_FRAME_DTMF;
    03776          p->subs[index].f.subclass = res & 0xff;
    03777 #ifdef ZAPATA_PRI
    03778       }
    03779 #endif
    03780       zt_handle_dtmfup(ast, index, &f);
    03781       return f;
    03782    }
    03783
    03784    if (res & ZT_EVENT_DTMFDOWN) {
    03785       ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
    03786       p->subs[index].f.frametype = AST_FRAME_NULL;
    03787       p->subs[index].f.subclass = 0;
    03788       zt_confmute(p, 1);
    03789       /* Mute conference, return null frame */
    03790       return &p->subs[index].f;
    03791    }
    03792
    03793    switch(res) {
    03794       case ZT_EVENT_BITSCHANGED:
    03795          if (p->sig == SIG_R2) {
    03796 #ifdef ZAPATA_R2
    03797             struct ast_frame  *f = &p->subs[index].f;
    03798             mfcr2_event_t *e;
    03799             e = r2_get_event_bits(p);
    03800             if (e)
    03801                f = handle_r2_event(p, e, index);
    03802             return f;
    03803 #else
    03804             break;
    03805 #endif
    03806          }
    03807          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
    03808       case ZT_EVENT_PULSE_START:
    03809          /* Stop tone if there's a pulse start and the PBX isn't started */
    03810          if (!ast->pbx)
    03811             tone_zone_play_tone(p->subs[index].zfd, -1);
    03812          break;
    03813       case ZT_EVENT_DIALCOMPLETE:
    03814          if (p->inalarm) break;
    03815          if (p->radio) break;
    03816          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
    03817             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
    03818             return NULL;
    03819          }
    03820          if (!x) { /* if not still dialing in driver */
    03821             zt_enable_ec(p);
    03822             if (p->echobreak) {
    03823                zt_train_ec(p);
    03824                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
    03825                p->dop.op = ZT_DIAL_OP_REPLACE;
    03826                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
    03827                p->echobreak = 0;
    03828             } else {
    03829                p->dialing = 0;
    03830                if (p->sig == SIG_E911) {
    03831                   /* if thru with dialing after offhook */
    03832                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
    03833                      ast_setstate(ast, AST_STATE_UP);
    03834                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
    03835                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
    03836                      break;
    03837                   } else { /* if to state wait for offhook to dial rest */
    03838                      /* we now wait for off hook */
    03839                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
    03840                   }
    03841                }
    03842                if (ast->_state == AST_STATE_DIALING) {
    03843                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
    03844                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
    03845                   } else if (p->confirmanswer || (!p->dialednone && ((p->sig == SIG_EM) || (p->sig == SIG_EM_E1) ||  (p->sig == SIG_EMWINK) || (p->sig == SIG_FEATD) || (p->sig == SIG_FEATDMF) || (p->sig == SIG_E911) || (p->sig == SIG_FEATB) || (p->sig == SIG_SF) || (p->sig == SIG_SFWINK) || (p->sig == SIG_SF_FEATD) || (p->sig == SIG_SF_FEATDMF) || (p->sig == SIG_SF_FEATB)))) {
    03846                      ast_setstate(ast, AST_STATE_RINGING);
    03847                   } else if (!p->answeronpolarityswitch) {
    03848                      ast_setstate(ast, AST_STATE_UP);
    03849                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
    03850                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
    03851                   }
    03852                }
    03853             }
    03854          }
    03855          break;
    03856       case ZT_EVENT_ALARM:
    03857 #ifdef ZAPATA_PRI
    03858          if (p->call) {
    03859             if (p->pri && p->pri->pri) {
    03860                if (!pri_grab(p, p->pri)) {
    03861                   pri_hangup(p->pri->pri, p->call, -1);
    03862                   pri_destroycall(p->pri->pri, p->call);
    03863                   p->call = NULL;
    03864                   pri_rel(p->pri);
    03865                } else
    03866                   ast_log(LOG_WARNING, "Failed to grab PRI!\n");
    03867             } else
    03868                ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
    03869          }
    03870          if (p->owner)
    03871             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
    03872          if (p->bearer)
    03873             p->bearer->inalarm = 1;
    03874          else
    03875 #endif
    03876          p->inalarm = 1;
    03877          res = get_alarms(p);
    03878          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res));
    03879          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
    03880                         "Alarm: %s\r\n"
    03881                         "Channel: %d\r\n",
    03882                         alarm2str(res), p->channel);
    03883          /* fall through intentionally */
    03884       case ZT_EVENT_ONHOOK:
    03885          if (p->radio)
    03886          {
    03887             p->subs[index].f.frametype = AST_FRAME_CONTROL;
    03888             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
    03889             break;
    03890          }
    03891          switch(p->sig) {
    03892          case SIG_FXOLS:
    03893          case SIG_FXOGS:
    03894          case SIG_FXOKS:
    03895             p->onhooktime = time(NULL);
    03896             p->msgstate = -1;
    03897             /* Check for some special conditions regarding call waiting */
    03898             if (index == SUB_REAL) {
    03899                /* The normal line was hung up */
    03900                if (p->subs[SUB_CALLWAIT].owner) {
    03901                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
    03902                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
    03903                   if (option_verbose > 2)
    03904                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
    03905                   unalloc_sub(p, SUB_CALLWAIT);
    03906 #if 0
    03907                   p->subs[index].needanswer = 0;
    03908                   p->subs[index].needringing = 0;
    03909 #endif
    03910                   p->callwaitingrepeat = 0;
    03911                   p->cidcwexpire = 0;
    03912                   p->owner = NULL;
    03913                   /* Don't start streaming audio yet if the incoming call isn't up yet */
    03914                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
    03915                      p->dialing = 1;
    03916                   zt_ring_phone(p);
    03917                } else if (p->subs[SUB_THREEWAY].owner) {
    03918                   unsigned int mssinceflash;
    03919                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
    03920                      the private structure -- not especially easy or clean */
    03921                   while(p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
    03922                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
    03923                      ast_mutex_unlock(&p->lock);
    03924                      ast_mutex_unlock(&ast->lock);
    03925                      usleep(1);
    03926                      /* We can grab ast and p in that order, without worry.  We should make sure
    03927                         nothing seriously bad has happened though like some sort of bizarre double
    03928                         masquerade! */
    03929                      ast_mutex_lock(&ast->lock);
    03930                      ast_mutex_lock(&p->lock);
    03931                      if (p->owner != ast) {
    03932                         ast_log(LOG_WARNING, "This isn't good...\n");
    03933                         return NULL;
    03934                      }
    03935                   }
    03936                   if (!p->subs[SUB_THREEWAY].owner) {
    03937                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
    03938                      return NULL;
    03939                   }
    03940                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
    03941                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
    03942                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
    03943                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on
    03944                         hanging up.  Hangup both channels now */
    03945                      if (p->subs[SUB_THREEWAY].owner)
    03946                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
    03947                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
    03948                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
    03949                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03950                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
    03951                      if (p->transfer) {
    03952                         /* In any case this isn't a threeway call anymore */
    03953                         p->subs[SUB_REAL].inthreeway = 0;
    03954                         p->subs[SUB_THREEWAY].inthreeway = 0;
    03955                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
    03956                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
    03957                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03958                            /* Swap subs and dis-own channel */
    03959                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
    03960                            p->owner = NULL;
    03961                            /* Ring the phone */
    03962                            zt_ring_phone(p);
    03963                         } else {
    03964                            if ((res = attempt_transfer(p)) < 0) {
    03965                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
    03966                               if (p->subs[SUB_THREEWAY].owner)
    03967                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03968                            } else if (res) {
    03969                               /* Don't actually hang up at this point */
    03970                               if (p->subs[SUB_THREEWAY].owner)
    03971                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03972                               break;
    03973                            }
    03974                         }
    03975                      } else {
    03976                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
    03977                         if (p->subs[SUB_THREEWAY].owner)
    03978                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03979                      }
    03980                   } else {
    03981                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
    03982                      /* Swap subs and dis-own channel */
    03983                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
    03984                      p->owner = NULL;
    03985                      /* Ring the phone */
    03986                      zt_ring_phone(p);
    03987                   }
    03988                }
    03989             } else {
    03990                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
    03991             }
    03992             /* Fall through */
    03993          default:
    03994             zt_disable_ec(p);
    03995             return NULL;
    03996          }
    03997          break;
    03998       case ZT_EVENT_RINGOFFHOOK:
    03999          if (p->inalarm) break;
    04000          if (p->radio)
    04001          {
    04002             p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04003             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
    04004             break;
    04005          }
    04006          /* for E911, its supposed to wait for offhook then dial
    04007             the second half of the dial string */
    04008          if ((p->sig == SIG_E911) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
    04009             c = strchr(p->dialdest, '/');
    04010             if (c)
    04011                c++;
    04012             else
    04013                c = p->dialdest;
    04014             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
    04015             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
    04016             if (strlen(p->dop.dialstr) > 4) {
    04017                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
    04018                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
    04019                p->echorest[sizeof(p->echorest) - 1] = '\0';
    04020                p->echobreak = 1;
    04021                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
    04022             } else
    04023                p->echobreak = 0;
    04024             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
    04025                x = ZT_ONHOOK;
    04026                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
    04027                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
    04028                return NULL;
    04029                }
    04030             p->dialing = 1;
    04031             return &p->subs[index].f;
    04032          }
    04033          switch(p->sig) {
    04034          case SIG_FXOLS:
    04035          case SIG_FXOGS:
    04036          case SIG_FXOKS:
    04037             switch(ast->_state) {
    04038             case AST_STATE_RINGING:
    04039                zt_enable_ec(p);
    04040                zt_train_ec(p);
    04041                p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04042                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
    04043                /* Make sure it stops ringing */
    04044                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
    04045                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
    04046                if (p->cidspill) {
    04047                   /* Cancel any running CallerID spill */
    04048                   free(p->cidspill);
    04049                   p->cidspill = NULL;
    04050                }
    04051                p->dialing = 0;
    04052                p->callwaitcas = 0;
    04053                if (p->confirmanswer) {
    04054                   /* Ignore answer if "confirm answer" is enabled */
    04055                   p->subs[index].f.frametype = AST_FRAME_NULL;
    04056                   p->subs[index].f.subclass = 0;
    04057                } else if (!ast_strlen_zero(p->dop.dialstr)) {
    04058                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
    04059                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
    04060                   if (res < 0) {
    04061                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
    04062                      p->dop.dialstr[0] = '\0';
    04063                      return NULL;
    04064                   } else {
    04065                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
    04066                      p->subs[index].f.frametype = AST_FRAME_NULL;
    04067                      p->subs[index].f.subclass = 0;
    04068                      p->dialing = 1;
    04069                   }
    04070                   p->dop.dialstr[0] = '\0';
    04071                   ast_setstate(ast, AST_STATE_DIALING);
    04072                } else
    04073                   ast_setstate(ast, AST_STATE_UP);
    04074                return &p->subs[index].f;
    04075             case AST_STATE_DOWN:
    04076                ast_setstate(ast, AST_STATE_RING);
    04077                ast->rings = 1;
    04078                p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04079                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
    04080                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
    04081                return &p->subs[index].f;
    04082             case AST_STATE_UP:
    04083                /* Make sure it stops ringing */
    04084                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
    04085                /* Okay -- probably call waiting*/
    04086                if (ast_bridged_channel(p->owner))
    04087                      ast_moh_stop(ast_bridged_channel(p->owner));
    04088                break;
    04089             case AST_STATE_RESERVED:
    04090                /* Start up dialtone */
    04091                if (has_voicemail(p))
    04092                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
    04093                else
    04094                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
    04095                break;
    04096             default:
    04097                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
    04098             }
    04099             break;
    04100          case SIG_FXSLS:
    04101          case SIG_FXSGS:
    04102          case SIG_FXSKS:
    04103             if (ast->_state == AST_STATE_RING) {
    04104                p->ringt = p->ringt_base;
    04105             }
    04106
    04107             /* If we get a ring then we cannot be in
    04108              * reversed polarity. So we reset to idle */
    04109             ast_log(LOG_DEBUG, "Setting IDLE polarity due "
    04110                "to ring. Old polarity was %d\n",
    04111                p->polarity);
    04112             p->polarity = POLARITY_IDLE;
    04113
    04114             /* Fall through */
    04115          case SIG_EM:
    04116          case SIG_EM_E1:
    04117          case SIG_EMWINK:
    04118          case SIG_FEATD:
    04119          case SIG_FEATDMF:
    04120          case SIG_FEATDMF_TA:
    04121          case SIG_E911:
    04122          case SIG_FEATB:
    04123          case SIG_SF:
    04124          case SIG_SFWINK:
    04125          case SIG_SF_FEATD:
    04126          case SIG_SF_FEATDMF:
    04127          case SIG_SF_FEATB:
    04128             if (ast->_state == AST_STATE_PRERING)
    04129                ast_setstate(ast, AST_STATE_RING);
    04130             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
    04131                if (option_debug)
    04132                   ast_log(LOG_DEBUG, "Ring detected\n");
    04133                p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04134                p->subs[index].f.subclass = AST_CONTROL_RING;
    04135             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
    04136                if (option_debug)
    04137                   ast_log(LOG_DEBUG, "Line answered\n");
    04138                if (p->confirmanswer) {
    04139                   p->subs[index].f.frametype = AST_FRAME_NULL;
    04140                   p->subs[index].f.subclass = 0;
    04141                } else {
    04142                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04143                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
    04144                   ast_setstate(ast, AST_STATE_UP);
    04145                }
    04146             } else if (ast->_state != AST_STATE_RING)
    04147                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
    04148             break;
    04149          default:
    04150             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
    04151          }
    04152          break;
    04153 #ifdef ZT_EVENT_RINGBEGIN
    04154       case ZT_EVENT_RINGBEGIN:
    04155          switch(p->sig) {
    04156          case SIG_FXSLS:
    04157          case SIG_FXSGS:
    04158          case SIG_FXSKS:
    04159             if (ast->_state == AST_STATE_RING) {
    04160                p->ringt = p->ringt_base;
    04161             }
    04162             break;
    04163          }
    04164          break;
    04165 #endif
    04166       case ZT_EVENT_RINGEROFF:
    04167          if (p->inalarm) break;
    04168          if (p->radio) break;
    04169          ast->rings++;
    04170          if ((ast->rings > p->cidrings) && (p->cidspill)) {
    04171             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
    04172             free(p->cidspill);
    04173             p->cidspill = NULL;
    04174             p->callwaitcas = 0;
    04175          }
    04176          p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04177          p->subs[index].f.subclass = AST_CONTROL_RINGING;
    04178          break;
    04179       case ZT_EVENT_RINGERON:
    04180          break;
    04181       case ZT_EVENT_NOALARM:
    04182          p->inalarm = 0;
    04183 #ifdef ZAPATA_PRI
    04184          /* Extremely unlikely but just in case */
    04185          if (p->bearer)
    04186             p->bearer->inalarm = 0;
    04187 #endif
    04188          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
    04189          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
    04190                         "Channel: %d\r\n", p->channel);
    04191          break;
    04192       case ZT_EVENT_WINKFLASH:
    04193          if (p->inalarm) break;
    04194          if (p->radio) break;
    04195          /* Remember last time we got a flash-hook */
    04196          gettimeofday(&p->flashtime, NULL);
    04197          switch(p->sig) {
    04198          case SIG_FXOLS:
    04199          case SIG_FXOGS:
    04200          case SIG_FXOKS:
    04201             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
    04202                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
    04203             p->callwaitcas = 0;
    04204
    04205             if (index != SUB_REAL) {
    04206                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
    04207                goto winkflashdone;
    04208             }
    04209
    04210             if (p->subs[SUB_CALLWAIT].owner) {
    04211                /* Swap to call-wait */
    04212                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
    04213                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
    04214                p->owner = p->subs[SUB_REAL].owner;
    04215                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
    04216                if (p->owner->_state == AST_STATE_RINGING) {
    04217                   ast_setstate(p->owner, AST_STATE_UP);
    04218                   p->subs[SUB_REAL].needanswer = 1;
    04219                }
    04220                p->callwaitingrepeat = 0;
    04221                p->cidcwexpire = 0;
    04222                /* Start music on hold if appropriate */
    04223                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
    04224                   ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
    04225                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
    04226                   ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
    04227             } else if (!p->subs[SUB_THREEWAY].owner) {
    04228                char cid_num[256];
    04229                char cid_name[256];
    04230
    04231                if (!p->threewaycalling) {
    04232                   /* Just send a flash if no 3-way calling */
    04233                   p->subs[SUB_REAL].needflash = 1;
    04234                   goto winkflashdone;
    04235                } else if (!check_for_conference(p)) {
    04236                   if (p->zaptrcallerid && p->owner) {
    04237                      if (p->owner->cid.cid_num)
    04238                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
    04239                      if (p->owner->cid.cid_name)
    04240                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
    04241                   }
    04242                   /* XXX This section needs much more error checking!!! XXX */
    04243                   /* Start a 3-way call if feasible */
    04244                   if (!((ast->pbx) ||
    04245                         (ast->_state == AST_STATE_UP) ||
    04246                         (ast->_state == AST_STATE_RING))) {
    04247                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
    04248                         goto winkflashdone;
    04249                   }
    04250                   if (alloc_sub(p, SUB_THREEWAY)) {
    04251                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
    04252                      goto winkflashdone;
    04253                   }
    04254                   /* Make new channel */
    04255                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
    04256                   if (p->zaptrcallerid) {
    04257                      if (!p->origcid_num)
    04258                         p->origcid_num = strdup(p->cid_num);
    04259                      if (!p->origcid_name)
    04260                         p->origcid_name = strdup(p->cid_name);
    04261                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
    04262                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
    04263                   }
    04264                   /* Swap things around between the three-way and real call */
    04265                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
    04266                   /* Disable echo canceller for better dialing */
    04267                   zt_disable_ec(p);
    04268                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
    04269                   if (res)
    04270                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
    04271                   p->owner = chan;
    04272                   pthread_attr_init(&attr);
    04273                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    04274                   if (!chan) {
    04275                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
    04276                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
    04277                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
    04278                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
    04279                      zt_enable_ec(p);
    04280                      ast_hangup(chan);
    04281                   } else {
    04282                      if (option_verbose > 2)
    04283                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
    04284                      /* Start music on hold if appropriate */
    04285                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
    04286                         ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
    04287                   }
    04288                   pthread_attr_destroy(&attr);
    04289                }
    04290             } else {
    04291                /* Already have a 3 way call */
    04292                if (p->subs[SUB_THREEWAY].inthreeway) {
    04293                   /* Call is already up, drop the last person */
    04294                   if (option_debug)
    04295                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
    04296                   /* If the primary call isn't answered yet, use it */
    04297                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
    04298                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
    04299                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
    04300                      p->owner = p->subs[SUB_REAL].owner;
    04301                   }
    04302                   /* Drop the last call and stop the conference */
    04303                   if (option_verbose > 2)
    04304                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
    04305                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
    04306                   p->subs[SUB_REAL].inthreeway = 0;
    04307                   p->subs[SUB_THREEWAY].inthreeway = 0;
    04308                } else {
    04309                   /* Lets see what we're up to */
    04310                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) &&
    04311                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
    04312                      int otherindex = SUB_THREEWAY;
    04313
    04314                      if (option_verbose > 2)
    04315                         ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
    04316                      /* Put them in the threeway, and flip */
    04317                      p->subs[SUB_THREEWAY].inthreeway = 1;
    04318                      p->subs[SUB_REAL].inthreeway = 1;
    04319                      if (ast->_state == AST_STATE_UP) {
    04320                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
    04321                         otherindex = SUB_REAL;
    04322                      }
    04323                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
    04324                         ast_moh_stop(ast_bridged_channel(p->subs[otherindex].owner));
    04325                      p->owner = p->subs[SUB_REAL].owner;
    04326                      if (ast->_state == AST_STATE_RINGING) {
    04327                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
    04328                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
    04329                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
    04330                      }
    04331                   } else {
    04332                      if (option_verbose > 2)
    04333                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
    04334                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
    04335                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
    04336                      p->owner = p->subs[SUB_REAL].owner;
    04337                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
    04338                         ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
    04339                      zt_enable_ec(p);
    04340                   }
    04341
    04342                }
    04343             }
    04344          winkflashdone:
    04345             update_conf(p);
    04346             break;
    04347          case SIG_EM:
    04348          case SIG_EM_E1:
    04349          case SIG_EMWINK:
    04350          case SIG_FEATD:
    04351          case SIG_SF:
    04352          case SIG_SFWINK:
    04353          case SIG_SF_FEATD:
    04354          case SIG_FXSLS:
    04355          case SIG_FXSGS:
    04356             if (p->dialing)
    04357                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
    04358             else
    04359                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
    04360             break;
    04361          case SIG_FEATDMF_TA:
    04362             switch (p->whichwink) {
    04363             case 0:
    04364                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
    04365                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
    04366                break;
    04367             case 1:
    04368                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
    04369                break;
    04370             case 2:
    04371                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
    04372                return NULL;
    04373             }
    04374             p->whichwink++;
    04375             /* Fall through */
    04376          case SIG_FEATDMF:
    04377          case SIG_E911:
    04378          case SIG_FEATB:
    04379          case SIG_SF_FEATDMF:
    04380          case SIG_SF_FEATB:
    04381             /* FGD MF *Must* wait for wink */
    04382             if (!ast_strlen_zero(p->dop.dialstr))
    04383                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
    04384             else if (res < 0) {
    04385                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
    04386                p->dop.dialstr[0] = '\0';
    04387                return NULL;
    04388             } else
    04389                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
    04390             p->dop.dialstr[0] = '\0';
    04391             break;
    04392          default:
    04393             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
    04394          }
    04395          break;
    04396       case ZT_EVENT_HOOKCOMPLETE:
    04397          if (p->inalarm) break;
    04398          if (p->radio) break;
    04399          switch(p->sig) {
    04400          case SIG_FXSLS:  /* only interesting for FXS */
    04401          case SIG_FXSGS:
    04402          case SIG_FXSKS:
    04403          case SIG_EM:
    04404          case SIG_EM_E1:
    04405          case SIG_EMWINK:
    04406          case SIG_FEATD:
    04407          case SIG_SF:
    04408          case SIG_SFWINK:
    04409          case SIG_SF_FEATD:
    04410             if (!ast_strlen_zero(p->dop.dialstr))
    04411                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
    04412             else if (res < 0) {
    04413                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
    04414                p->dop.dialstr[0] = '\0';
    04415                return NULL;
    04416             } else
    04417                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
    04418             p->dop.dialstr[0] = '\0';
    04419             p->dop.op = ZT_DIAL_OP_REPLACE;
    04420             break;
    04421          case SIG_FEATDMF:
    04422          case SIG_E911:
    04423          case SIG_FEATB:
    04424          case SIG_SF_FEATDMF:
    04425          case SIG_SF_FEATB:
    04426             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
    04427             break;
    04428          default:
    04429             break;
    04430          }
    04431          break;
    04432       case ZT_EVENT_POLARITY:
    04433                         /*
    04434                          * If we get a Polarity Switch event, check to see
    04435                          * if we should change the polarity state and
    04436                          * mark the channel as UP or if this is an indication
    04437                          * of remote end disconnect.
    04438                          */
    04439                         if (p->polarity == POLARITY_IDLE) {
    04440                                 p->polarity = POLARITY_REV;
    04441                                 if (p->answeronpolarityswitch &&
    04442                                     ((ast->_state == AST_STATE_DIALING) ||
    04443                                      (ast->_state == AST_STATE_RINGING))) {
    04444                                         ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
    04445                                         ast_setstate(p->owner, AST_STATE_UP);
    04446                if(p->hanguponpolarityswitch) {
    04447                   gettimeofday(&p->polaritydelaytv, NULL);
    04448                }
    04449                break;
    04450                                 } else
    04451                                         ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
    04452          }
    04453          /* Removed else statement from here as it was preventing hangups from ever happening*/
    04454          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
    04455          if(p->hanguponpolarityswitch &&
    04456             (p->polarityonanswerdelay > 0) &&
    04457                 (p->polarity == POLARITY_REV) &&
    04458             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
    04459                                 /* Added log_debug information below to provide a better indication of what is going on */
    04460             ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
    04461
    04462             if(ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
    04463                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
    04464                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
    04465                p->polarity = POLARITY_IDLE;
    04466             } else {
    04467                ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
    04468             }
    04469          } else {
    04470             p->polarity = POLARITY_IDLE;
    04471             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
    04472          }
    04473                         /* Added more log_debug information below to provide a better indication of what is going on */
    04474          ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
    04475          break;
    04476       default:
    04477          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
    04478    }
    04479    return &p->subs[index].f;
    04480 }

static int zt_hangup | ( | struct ast_channel * | ast | ) | `[static]`

Definition at line 2452 of file chan_zap.c.

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

    02453 {
    02454    int res;
    02455    int index,x, law;
    02456    /*static int restore_gains(struct zt_pvt *p);*/
    02457    struct zt_pvt *p = ast->tech_pvt;
    02458    struct zt_pvt *tmp = NULL;
    02459    struct zt_pvt *prev = NULL;
    02460    ZT_PARAMS par;
    02461
    02462    if (option_debug)
    02463       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
    02464    if (!ast->tech_pvt) {
    02465       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
    02466       return 0;
    02467    }
    02468
    02469    ast_mutex_lock(&p->lock);
    02470
    02471    index = zt_get_index(ast, p, 1);
    02472
    02473    if (p->sig == SIG_PRI) {
    02474       x = 1;
    02475       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
    02476    }
    02477
    02478    x = 0;
    02479    zt_confmute(p, 0);
    02480    restore_gains(p);
    02481    if (p->origcid_num) {
    02482       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
    02483       free(p->origcid_num);
    02484       p->origcid_num = NULL;
    02485    }
    02486    if (p->origcid_name) {
    02487       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
    02488       free(p->origcid_name);
    02489       p->origcid_name = NULL;
    02490    }
    02491    if (p->dsp)
    02492       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
    02493    if (p->exten)
    02494       p->exten[0] = '\0';
    02495
    02496    ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
    02497       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
    02498    p->ignoredtmf = 0;
    02499
    02500    if (index > -1) {
    02501       /* Real channel, do some fixup */
    02502       p->subs[index].owner = NULL;
    02503       p->subs[index].needanswer = 0;
    02504       p->subs[index].needflash = 0;
    02505       p->subs[index].needringing = 0;
    02506       p->subs[index].needbusy = 0;
    02507       p->subs[index].needcongestion = 0;
    02508       p->subs[index].linear = 0;
    02509       p->subs[index].needcallerid = 0;
    02510       p->polarity = POLARITY_IDLE;
    02511       zt_setlinear(p->subs[index].zfd, 0);
    02512       if (index == SUB_REAL) {
    02513          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
    02514             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
    02515             if (p->subs[SUB_CALLWAIT].inthreeway) {
    02516                /* We had flipped over to answer a callwait and now it's gone */
    02517                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
    02518                /* Move to the call-wait, but un-own us until they flip back. */
    02519                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
    02520                unalloc_sub(p, SUB_CALLWAIT);
    02521                p->owner = NULL;
    02522             } else {
    02523                /* The three way hung up, but we still have a call wait */
    02524                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
    02525                swap_subs(p, SUB_THREEWAY, SUB_REAL);
    02526                unalloc_sub(p, SUB_THREEWAY);
    02527                if (p->subs[SUB_REAL].inthreeway) {
    02528                   /* This was part of a three way call.  Immediately make way for
    02529                      another call */
    02530                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
    02531                   p->owner = p->subs[SUB_REAL].owner;
    02532                } else {
    02533                   /* This call hasn't been completed yet...  Set owner to NULL */
    02534                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
    02535                   p->owner = NULL;
    02536                }
    02537                p->subs[SUB_REAL].inthreeway = 0;
    02538             }
    02539          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
    02540             /* Move to the call-wait and switch back to them. */
    02541             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
    02542             unalloc_sub(p, SUB_CALLWAIT);
    02543             p->owner = p->subs[SUB_REAL].owner;
    02544             if (p->owner->_state != AST_STATE_UP)
    02545                p->subs[SUB_REAL].needanswer = 1;
    02546             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
    02547                ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
    02548          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
    02549             swap_subs(p, SUB_THREEWAY, SUB_REAL);
    02550             unalloc_sub(p, SUB_THREEWAY);
    02551             if (p->subs[SUB_REAL].inthreeway) {
    02552                /* This was part of a three way call.  Immediately make way for
    02553                   another call */
    02554                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
    02555                p->owner = p->subs[SUB_REAL].owner;
    02556             } else {
    02557                /* This call hasn't been completed yet...  Set owner to NULL */
    02558                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
    02559                p->owner = NULL;
    02560             }
    02561             p->subs[SUB_REAL].inthreeway = 0;
    02562          }
    02563       } else if (index == SUB_CALLWAIT) {
    02564          /* Ditch the holding callwait call, and immediately make it availabe */
    02565          if (p->subs[SUB_CALLWAIT].inthreeway) {
    02566             /* This is actually part of a three way, placed on hold.  Place the third part
    02567                on music on hold now */
    02568             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
    02569                ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
    02570             p->subs[SUB_THREEWAY].inthreeway = 0;
    02571             /* Make it the call wait now */
    02572             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
    02573             unalloc_sub(p, SUB_THREEWAY);
    02574          } else
    02575             unalloc_sub(p, SUB_CALLWAIT);
    02576       } else if (index == SUB_THREEWAY) {
    02577          if (p->subs[SUB_CALLWAIT].inthreeway) {
    02578             /* The other party of the three way call is currently in a call-wait state.
    02579                Start music on hold for them, and take the main guy out of the third call */
    02580             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
    02581                ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
    02582             p->subs[SUB_CALLWAIT].inthreeway = 0;
    02583          }
    02584          p->subs[SUB_REAL].inthreeway = 0;
    02585          /* If this was part of a three way call index, let us make
    02586             another three way call */
    02587          unalloc_sub(p, SUB_THREEWAY);
    02588       } else {
    02589          /* This wasn't any sort of call, but how are we an index? */
    02590          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
    02591       }
    02592    }
    02593
    02594
    02595    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
    02596       p->owner = NULL;
    02597       p->ringt = 0;
    02598       p->distinctivering = 0;
    02599       p->confirmanswer = 0;
    02600       p->cidrings = 1;
    02601       p->outgoing = 0;
    02602       p->digital = 0;
    02603       p->faxhandled = 0;
    02604       p->pulsedial = 0;
    02605       p->onhooktime = time(NULL);
    02606 #ifdef ZAPATA_PRI
    02607       p->proceeding = 0;
    02608       p->progress = 0;
    02609       p->alerting = 0;
    02610       p->setup_ack = 0;
    02611 #endif
    02612       if (p->dsp) {
    02613          ast_dsp_free(p->dsp);
    02614          p->dsp = NULL;
    02615       }
    02616
    02617       law = ZT_LAW_DEFAULT;
    02618       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
    02619       if (res < 0)
    02620          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
    02621       /* Perform low level hangup if no owner left */
    02622 #ifdef ZAPATA_PRI
    02623       if (p->pri) {
    02624 #ifdef SUPPORT_USERUSER
    02625          char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
    02626 #endif
    02627
    02628          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
    02629          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
    02630             if (!pri_grab(p, p->pri)) {
    02631                if (p->alreadyhungup) {
    02632                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
    02633
    02634 #ifdef SUPPORT_USERUSER
    02635                   pri_call_set_useruser(p->call, useruser);
    02636 #endif
    02637
    02638                   pri_hangup(p->pri->pri, p->call, -1);
    02639                   p->call = NULL;
    02640                   if (p->bearer)
    02641                      p->bearer->call = NULL;
    02642                } else {
    02643                   char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
    02644                   int icause = ast->hangupcause ? ast->hangupcause : -1;
    02645                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
    02646
    02647 #ifdef SUPPORT_USERUSER
    02648                   pri_call_set_useruser(p->call, useruser);
    02649 #endif
    02650
    02651                   p->alreadyhungup = 1;
    02652                   if (p->bearer)
    02653                      p->bearer->alreadyhungup = 1;
    02654                   if (cause) {
    02655                      if (atoi(cause))
    02656                         icause = atoi(cause);
    02657                   }
    02658                   pri_hangup(p->pri->pri, p->call, icause);
    02659                }
    02660                if (res < 0)
    02661                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
    02662                pri_rel(p->pri);
    02663             } else {
    02664                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    02665                res = -1;
    02666             }
    02667          } else {
    02668             if (p->bearer)
    02669                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
    02670             p->call = NULL;
    02671             res = 0;
    02672          }
    02673       }
    02674 #endif
    02675 #ifdef ZAPATA_R2
    02676       if (p->sig == SIG_R2) {
    02677          if (p->hasr2call) {
    02678             mfcr2_DropCall(p->r2, NULL, UC_NORMAL_CLEARING);
    02679             p->hasr2call = 0;
    02680             res = 0;
    02681          } else
    02682             res = 0;
    02683
    02684       }
    02685 #endif
    02686       if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2))
    02687          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
    02688       if (res < 0) {
    02689          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
    02690       }
    02691       switch(p->sig) {
    02692       case SIG_FXOGS:
    02693       case SIG_FXOLS:
    02694       case SIG_FXOKS:
    02695          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
    02696          if (!res) {
    02697 #if 0
    02698             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
    02699 #endif
    02700             /* If they're off hook, try playing congestion */
    02701             if ((par.rxisoffhook) && (!p->radio))
    02702                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
    02703             else
    02704                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
    02705          }
    02706          break;
    02707       case SIG_FXSGS:
    02708       case SIG_FXSLS:
    02709       case SIG_FXSKS:
    02710          /* Make sure we're not made available for at least two seconds assuming
    02711             we were actually used for an inbound or outbound call. */
    02712          if (ast->_state != AST_STATE_RESERVED) {
    02713             time(&p->guardtime);
    02714             p->guardtime += 2;
    02715          }
    02716          break;
    02717       default:
    02718          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
    02719       }
    02720       if (p->cidspill)
    02721          free(p->cidspill);
    02722       if (p->sig)
    02723          zt_disable_ec(p);
    02724       x = 0;
    02725       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
    02726       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
    02727       p->didtdd = 0;
    02728       p->cidspill = NULL;
    02729       p->callwaitcas = 0;
    02730       p->callwaiting = p->permcallwaiting;
    02731       p->hidecallerid = p->permhidecallerid;
    02732       p->dialing = 0;
    02733       p->rdnis[0] = '\0';
    02734       update_conf(p);
    02735       reset_conf(p);
    02736       /* Restore data mode */
    02737       if (p->sig == SIG_PRI) {
    02738          x = 0;
    02739          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
    02740       }
    02741 #ifdef ZAPATA_PRI
    02742       if (p->bearer) {
    02743          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
    02744          /* Free up the bearer channel as well, and
    02745             don't use its file descriptor anymore */
    02746          update_conf(p->bearer);
    02747          reset_conf(p->bearer);
    02748          p->bearer->owner = NULL;
    02749          p->bearer->realcall = NULL;
    02750          p->bearer = NULL;
    02751          p->subs[SUB_REAL].zfd = -1;
    02752          p->pri = NULL;
    02753       }
    02754 #endif
    02755       restart_monitor();
    02756    }
    02757
    02758
    02759    p->callwaitingrepeat = 0;
    02760    p->cidcwexpire = 0;
    02761    ast->tech_pvt = NULL;
    02762    ast_mutex_unlock(&p->lock);
    02763    ast_mutex_lock(&usecnt_lock);
    02764    usecnt--;
    02765    if (usecnt < 0)
    02766       ast_log(LOG_WARNING, "Usecnt < 0???\n");
    02767    ast_mutex_unlock(&usecnt_lock);
    02768    ast_update_use_count();
    02769    if (option_verbose > 2)
    02770       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
    02771
    02772    ast_mutex_lock(&iflock);
    02773    tmp = iflist;
    02774    prev = NULL;
    02775    if (p->destroy) {
    02776       while (tmp) {
    02777          if (tmp == p) {
    02778             destroy_channel(prev, tmp, 0);
    02779             break;
    02780          } else {
    02781             prev = tmp;
    02782             tmp = tmp->next;
    02783          }
    02784       }
    02785    }
    02786    ast_mutex_unlock(&iflock);
    02787    return 0;
    02788 }

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

Definition at line 4973 of file chan_zap.c.

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

Referenced by zt_fixup().

    04974 {
    04975    struct zt_pvt *p = chan->tech_pvt;
    04976    int res=-1;
    04977    int index;
    04978    int func = ZT_FLASH;
    04979    ast_mutex_lock(&p->lock);
    04980    index = zt_get_index(chan, p, 0);
    04981    ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
    04982    if (index == SUB_REAL) {
    04983       switch(condition) {
    04984       case AST_CONTROL_BUSY:
    04985 #ifdef ZAPATA_PRI
    04986          if (p->priindication_oob && p->sig == SIG_PRI) {
    04987             chan->hangupcause = AST_CAUSE_USER_BUSY;
    04988             chan->_softhangup |= AST_SOFTHANGUP_DEV;
    04989             res = 0;
    04990          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
    04991             if (p->pri->pri) {
    04992                if (!pri_grab(p, p->pri)) {
    04993                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
    04994                   pri_rel(p->pri);
    04995                }
    04996                else
    04997                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    04998             }
    04999             p->progress = 1;
    05000             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
    05001          } else
    05002 #endif
    05003             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
    05004          break;
    05005       case AST_CONTROL_RINGING:
    05006 #ifdef ZAPATA_PRI
    05007          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
    05008             if (p->pri->pri) {
    05009                if (!pri_grab(p, p->pri)) {
    05010                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
    05011                   pri_rel(p->pri);
    05012                }
    05013                else
    05014                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    05015             }
    05016             p->alerting = 1;
    05017          }
    05018 #endif
    05019          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
    05020          if (chan->_state != AST_STATE_UP && chan->_state != AST_STATE_RING) {
    05021             if ((p->sig != SIG_FXSKS) &&
    05022                 (p->sig != SIG_FXSLS) &&
    05023                 (p->sig != SIG_FXSGS))
    05024                ast_setstate(chan, AST_STATE_RINGING);
    05025          }
    05026          break;
    05027       case AST_CONTROL_PROCEEDING:
    05028          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
    05029 #ifdef ZAPATA_PRI
    05030          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
    05031             if (p->pri->pri) {
    05032                if (!pri_grab(p, p->pri)) {
    05033                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
    05034                   pri_rel(p->pri);
    05035                }
    05036                else
    05037                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    05038             }
    05039             p->proceeding = 1;
    05040          }
    05041 #endif
    05042          /* don't continue in ast_indicate */
    05043          res = 0;
    05044          break;
    05045       case AST_CONTROL_PROGRESS:
    05046          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
    05047 #ifdef ZAPATA_PRI
    05048          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
    05049          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
    05050             if (p->pri->pri) {
    05051                if (!pri_grab(p, p->pri)) {
    05052                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
    05053                   pri_rel(p->pri);
    05054                }
    05055                else
    05056                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    05057             }
    05058             p->progress = 1;
    05059          }
    05060 #endif
    05061          /* don't continue in ast_indicate */
    05062          res = 0;
    05063          break;
    05064       case AST_CONTROL_CONGESTION:
    05065          chan->hangupcause = AST_CAUSE_CONGESTION;
    05066 #ifdef ZAPATA_PRI
    05067          if (p->priindication_oob && p->sig == SIG_PRI) {
    05068             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
    05069             chan->_softhangup |= AST_SOFTHANGUP_DEV;
    05070             res = 0;
    05071          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
    05072             if (p->pri) {
    05073                if (!pri_grab(p, p->pri)) {
    05074                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
    05075                   pri_rel(p->pri);
    05076                } else
    05077                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    05078             }
    05079             p->progress = 1;
    05080             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
    05081          } else
    05082 #endif
    05083             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
    05084          break;
    05085 #ifdef ZAPATA_PRI
    05086       case AST_CONTROL_HOLD:
    05087          if (p->pri) {
    05088             if (!pri_grab(p, p->pri)) {
    05089                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
    05090                pri_rel(p->pri);
    05091             } else
    05092                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    05093          }
    05094          break;
    05095       case AST_CONTROL_UNHOLD:
    05096          if (p->pri) {
    05097             if (!pri_grab(p, p->pri)) {
    05098                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
    05099                pri_rel(p->pri);
    05100             } else
    05101                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    05102          }
    05103          break;
    05104 #endif
    05105       case AST_CONTROL_RADIO_KEY:
    05106          if (p->radio)
    05107              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
    05108          res = 0;
    05109          break;
    05110       case AST_CONTROL_RADIO_UNKEY:
    05111          if (p->radio)
    05112              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
    05113          res = 0;
    05114          break;
    05115       case AST_CONTROL_FLASH:
    05116          /* flash hookswitch */
    05117          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
    05118             /* Clear out the dial buffer */
    05119             p->dop.dialstr[0] = '\0';
    05120             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
    05121                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
    05122                   chan->name, strerror(errno));
    05123             } else
    05124                res = 0;
    05125          } else
    05126             res = 0;
    05127          break;
    05128       case -1:
    05129          res = tone_zone_play_tone(p->subs[index].zfd, -1);
    05130          break;
    05131       }
    05132    } else
    05133       res = 0;
    05134    ast_mutex_unlock(&p->lock);
    05135    return res;
    05136 }

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

Definition at line 3085 of file chan_zap.c.

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

Referenced by zt_bridge().

    03085                                                                  {
    03086    int x;
    03087    if (!slave || !master) {
    03088       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
    03089       return;
    03090    }
    03091    for (x=0;x<MAX_SLAVES;x++) {
    03092       if (!master->slaves[x]) {
    03093          master->slaves[x] = slave;
    03094          break;
    03095       }
    03096    }
    03097    if (x >= MAX_SLAVES) {
    03098       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
    03099       master->slaves[MAX_SLAVES - 1] = slave;
    03100    }
    03101    if (slave->master)
    03102       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
    03103    slave->master = master;
    03104
    03105    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
    03106 }

static struct ast_channel * zt_new | ( | struct zt_pvt * | i,
|  | int | state,
|  | int | startpbx,
|  | int | index,
|  | int | law,
|  | int | transfercapability |
| ) |  |  | `[static, read]`

Definition at line 5138 of file chan_zap.c.

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

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

    05139 {
    05140    struct ast_channel *tmp;
    05141    int deflaw;
    05142    int res;
    05143    int x,y;
    05144    int features;
    05145    ZT_PARAMS ps;
    05146    if (i->subs[index].owner) {
    05147       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
    05148       return NULL;
    05149    }
    05150    tmp = ast_channel_alloc(0);
    05151    if (tmp) {
    05152       tmp->tech = &zap_tech;
    05153       ps.channo = i->channel;
    05154       res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
    05155       if (res) {
    05156          ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
    05157          ps.curlaw = ZT_LAW_MULAW;
    05158       }
    05159       if (ps.curlaw == ZT_LAW_ALAW)
    05160          deflaw = AST_FORMAT_ALAW;
    05161       else
    05162          deflaw = AST_FORMAT_ULAW;
    05163       if (law) {
    05164          if (law == ZT_LAW_ALAW)
    05165             deflaw = AST_FORMAT_ALAW;
    05166          else
    05167             deflaw = AST_FORMAT_ULAW;
    05168       }
    05169       y = 1;
    05170       do {
    05171 #ifdef ZAPATA_PRI
    05172          if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
    05173             snprintf(tmp->name, sizeof(tmp->name), "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y);
    05174          else
    05175 #endif
    05176          if (i->channel == CHAN_PSEUDO)
    05177             snprintf(tmp->name, sizeof(tmp->name), "Zap/pseudo-%d", rand());
    05178          else
    05179             snprintf(tmp->name, sizeof(tmp->name), "Zap/%d-%d", i->channel, y);
    05180          for (x=0;x<3;x++) {
    05181             if ((index != x) && i->subs[x].owner && !strcasecmp(tmp->name, i->subs[x].owner->name))
    05182                break;
    05183          }
    05184          y++;
    05185       } while (x < 3);
    05186       tmp->type = type;
    05187       tmp->fds[0] = i->subs[index].zfd;
    05188       tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
    05189       /* Start out assuming ulaw since it's smaller :) */
    05190       tmp->rawreadformat = deflaw;
    05191       tmp->readformat = deflaw;
    05192       tmp->rawwriteformat = deflaw;
    05193       tmp->writeformat = deflaw;
    05194       i->subs[index].linear = 0;
    05195       zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
    05196       features = 0;
    05197       if (index == SUB_REAL) {
    05198          if (i->busydetect && CANBUSYDETECT(i)) {
    05199             features |= DSP_FEATURE_BUSY_DETECT;
    05200          }
    05201          if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) {
    05202             features |= DSP_FEATURE_CALL_PROGRESS;
    05203          }
    05204          if ((!i->outgoing && (i->callprogress & 4)) ||
    05205              (i->outgoing && (i->callprogress & 2))) {
    05206             features |= DSP_FEATURE_FAX_DETECT;
    05207          }
    05208 #ifdef ZT_TONEDETECT
    05209          x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
    05210          if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
    05211 #endif
    05212             i->hardwaredtmf = 0;
    05213             features |= DSP_FEATURE_DTMF_DETECT;
    05214 #ifdef ZT_TONEDETECT
    05215          } else if (NEED_MFDETECT(i)) {
    05216             i->hardwaredtmf = 1;
    05217             features |= DSP_FEATURE_DTMF_DETECT;
    05218          }
    05219 #endif
    05220       }
    05221       if (features) {
    05222          if (i->dsp) {
    05223             ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
    05224          } else {
    05225             if (i->channel != CHAN_PSEUDO)
    05226                i->dsp = ast_dsp_new();
    05227             else
    05228                i->dsp = NULL;
    05229             if (i->dsp) {
    05230                i->dsp_features = features & ~DSP_PROGRESS_TALK;
    05231 #ifdef ZAPATA_PRI
    05232                /* We cannot do progress detection until receives PROGRESS message */
    05233                if (i->outgoing && (i->sig == SIG_PRI)) {
    05234                   /* Remember requested DSP features, don't treat
    05235                      talking as ANSWER */
    05236                   features = 0;
    05237                }
    05238 #endif
    05239                ast_dsp_set_features(i->dsp, features);
    05240                ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
    05241                if (!ast_strlen_zero(progzone))
    05242                   ast_dsp_set_call_progress_zone(i->dsp, progzone);
    05243                if (i->busydetect && CANBUSYDETECT(i)) {
    05244                   ast_dsp_set_busy_count(i->dsp, i->busycount);
    05245                   ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
    05246                }
    05247             }
    05248          }
    05249       }
    05250
    05251       if (state == AST_STATE_RING)
    05252          tmp->rings = 1;
    05253       tmp->tech_pvt = i;
    05254       if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
    05255          /* Only FXO signalled stuff can be picked up */
    05256          tmp->callgroup = i->callgroup;
    05257          tmp->pickupgroup = i->pickupgroup;
    05258       }
    05259       if (!ast_strlen_zero(i->language))
    05260          ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
    05261       if (!ast_strlen_zero(i->musicclass))
    05262          ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass));
    05263       if (!i->owner)
    05264          i->owner = tmp;
    05265       if (!ast_strlen_zero(i->accountcode))
    05266          ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
    05267       if (i->amaflags)
    05268          tmp->amaflags = i->amaflags;
    05269       i->subs[index].owner = tmp;
    05270       ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
    05271       /* Copy call forward info */
    05272       ast_copy_string(tmp->call_forward, i->call_forward, sizeof(tmp->call_forward));
    05273       /* If we've been told "no ADSI" then enforce it */
    05274       if (!i->adsi)
    05275          tmp->adsicpe = AST_ADSI_UNAVAILABLE;
    05276       if (!ast_strlen_zero(i->exten))
    05277          ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
    05278       if (!ast_strlen_zero(i->rdnis))
    05279          tmp->cid.cid_rdnis = strdup(i->rdnis);
    05280       if (!ast_strlen_zero(i->dnid))
    05281          tmp->cid.cid_dnid = strdup(i->dnid);
    05282
    05283 #ifdef PRI_ANI
    05284       if (!ast_strlen_zero(i->cid_num))
    05285          tmp->cid.cid_num = strdup(i->cid_num);
    05286       if (!ast_strlen_zero(i->cid_name))
    05287          tmp->cid.cid_name = strdup(i->cid_name);
    05288       if (!ast_strlen_zero(i->cid_ani))
    05289          tmp->cid.cid_ani = strdup(i->cid_ani);
    05290       else if (!ast_strlen_zero(i->cid_num))
    05291          tmp->cid.cid_ani = strdup(i->cid_num);
    05292 #else
    05293       if (!ast_strlen_zero(i->cid_num)) {
    05294          tmp->cid.cid_num = strdup(i->cid_num);
    05295          tmp->cid.cid_ani = strdup(i->cid_num);
    05296       }
    05297       if (!ast_strlen_zero(i->cid_name))
    05298          tmp->cid.cid_name = strdup(i->cid_name);
    05299 #endif
    05300       tmp->cid.cid_pres = i->callingpres;
    05301       tmp->cid.cid_ton = i->cid_ton;
    05302 #ifdef ZAPATA_PRI
    05303       tmp->transfercapability = transfercapability;
    05304       pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
    05305       if (transfercapability & PRI_TRANS_CAP_DIGITAL) {
    05306          i->digital = 1;
    05307       }
    05308       /* Assume calls are not idle calls unless we're told differently */
    05309       i->isidlecall = 0;
    05310       i->alreadyhungup = 0;
    05311 #endif
    05312       /* clear the fake event in case we posted one before we had ast_channel */
    05313       i->fake_event = 0;
    05314       /* Assure there is no confmute on this channel */
    05315       zt_confmute(i, 0);
    05316       ast_setstate(tmp, state);
    05317       ast_mutex_lock(&usecnt_lock);
    05318       usecnt++;
    05319       ast_mutex_unlock(&usecnt_lock);
    05320       ast_update_use_count();
    05321       if (startpbx) {
    05322          if (ast_pbx_start(tmp)) {
    05323             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
    05324             ast_hangup(tmp);
    05325             tmp = NULL;
    05326          }
    05327       }
    05328    } else
    05329       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
    05330    return tmp;
    05331 }

static int zt_open | ( | char * | fn | ) | `[static]`

Definition at line 1040 of file chan_zap.c.

References ast_log(), LOG_WARNING, and READ_SIZE.

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

    01041 {
    01042    int fd;
    01043    int isnum;
    01044    int chan = 0;
    01045    int bs;
    01046    int x;
    01047    isnum = 1;
    01048    for (x=0;x<strlen(fn);x++) {
    01049       if (!isdigit(fn[x])) {
    01050          isnum = 0;
    01051          break;
    01052       }
    01053    }
    01054    if (isnum) {
    01055       chan = atoi(fn);
    01056       if (chan < 1) {
    01057          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
    01058          return -1;
    01059       }
    01060       fn = "/dev/zap/channel";
    01061    }
    01062    fd = open(fn, O_RDWR | O_NONBLOCK);
    01063    if (fd < 0) {
    01064       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
    01065       return -1;
    01066    }
    01067    if (chan) {
    01068       if (ioctl(fd, ZT_SPECIFY, &chan)) {
    01069          x = errno;
    01070          close(fd);
    01071          errno = x;
    01072          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
    01073          return -1;
    01074       }
    01075    }
    01076    bs = READ_SIZE;
    01077    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1;
    01078    return fd;
    01079 }

struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | `[read]`

Definition at line 4596 of file chan_zap.c.

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

    04597 {
    04598    struct zt_pvt *p = ast->tech_pvt;
    04599    int res;
    04600    int index;
    04601    void *readbuf;
    04602    struct ast_frame *f;
    04603
    04604
    04605    ast_mutex_lock(&p->lock);
    04606
    04607    index = zt_get_index(ast, p, 0);
    04608
    04609    /* Hang up if we don't really exist */
    04610    if (index < 0) {
    04611       ast_log(LOG_WARNING, "We dont exist?\n");
    04612       ast_mutex_unlock(&p->lock);
    04613       return NULL;
    04614    }
    04615
    04616    if (p->radio && p->inalarm) return NULL;
    04617
    04618    p->subs[index].f.frametype = AST_FRAME_NULL;
    04619    p->subs[index].f.datalen = 0;
    04620    p->subs[index].f.samples = 0;
    04621    p->subs[index].f.mallocd = 0;
    04622    p->subs[index].f.offset = 0;
    04623    p->subs[index].f.subclass = 0;
    04624    p->subs[index].f.delivery = ast_tv(0,0);
    04625    p->subs[index].f.src = "zt_read";
    04626    p->subs[index].f.data = NULL;
    04627
    04628    /* make sure it sends initial key state as first frame */
    04629    if (p->radio && (!p->firstradio))
    04630    {
    04631       ZT_PARAMS ps;
    04632
    04633       ps.channo = p->channel;
    04634       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
    04635          ast_mutex_unlock(&p->lock);
    04636          return NULL;
    04637       }
    04638       p->firstradio = 1;
    04639       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04640       if (ps.rxisoffhook)
    04641       {
    04642          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
    04643       }
    04644       else
    04645       {
    04646          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
    04647       }
    04648       ast_mutex_unlock(&p->lock);
    04649       return &p->subs[index].f;
    04650    }
    04651    if (p->ringt == 1) {
    04652       ast_mutex_unlock(&p->lock);
    04653       return NULL;
    04654    }
    04655    else if (p->ringt > 0)
    04656       p->ringt--;
    04657
    04658    if (p->subs[index].needringing) {
    04659       /* Send ringing frame if requested */
    04660       p->subs[index].needringing = 0;
    04661       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04662       p->subs[index].f.subclass = AST_CONTROL_RINGING;
    04663       ast_setstate(ast, AST_STATE_RINGING);
    04664       ast_mutex_unlock(&p->lock);
    04665       return &p->subs[index].f;
    04666    }
    04667
    04668    if (p->subs[index].needbusy) {
    04669       /* Send busy frame if requested */
    04670       p->subs[index].needbusy = 0;
    04671       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04672       p->subs[index].f.subclass = AST_CONTROL_BUSY;
    04673       ast_mutex_unlock(&p->lock);
    04674       return &p->subs[index].f;
    04675    }
    04676
    04677    if (p->subs[index].needcongestion) {
    04678       /* Send congestion frame if requested */
    04679       p->subs[index].needcongestion = 0;
    04680       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04681       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
    04682       ast_mutex_unlock(&p->lock);
    04683       return &p->subs[index].f;
    04684    }
    04685
    04686    if (p->subs[index].needcallerid) {
    04687       ast_set_callerid(ast, !ast_strlen_zero(p->lastcid_num) ? p->lastcid_num : NULL,
    04688                      !ast_strlen_zero(p->lastcid_name) ? p->lastcid_name : NULL,
    04689                      !ast_strlen_zero(p->lastcid_num) ? p->lastcid_num : NULL
    04690                      );
    04691       p->subs[index].needcallerid = 0;
    04692    }
    04693
    04694    if (p->subs[index].needanswer) {
    04695       /* Send answer frame if requested */
    04696       p->subs[index].needanswer = 0;
    04697       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04698       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
    04699       ast_mutex_unlock(&p->lock);
    04700       return &p->subs[index].f;
    04701    }
    04702
    04703    if (p->subs[index].needflash) {
    04704       /* Send answer frame if requested */
    04705       p->subs[index].needflash = 0;
    04706       p->subs[index].f.frametype = AST_FRAME_CONTROL;
    04707       p->subs[index].f.subclass = AST_CONTROL_FLASH;
    04708       ast_mutex_unlock(&p->lock);
    04709       return &p->subs[index].f;
    04710    }
    04711
    04712    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
    04713       if (!p->subs[index].linear) {
    04714          p->subs[index].linear = 1;
    04715          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
    04716          if (res)
    04717             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
    04718       }
    04719    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
    04720          (ast->rawreadformat == AST_FORMAT_ALAW)) {
    04721       if (p->subs[index].linear) {
    04722          p->subs[index].linear = 0;
    04723          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
    04724          if (res)
    04725             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
    04726       }
    04727    } else {
    04728       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
    04729       ast_mutex_unlock(&p->lock);
    04730       return NULL;
    04731    }
    04732    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
    04733    CHECK_BLOCKING(ast);
    04734    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
    04735    ast_clear_flag(ast, AST_FLAG_BLOCKING);
    04736    /* Check for hangup */
    04737    if (res < 0) {
    04738       f = NULL;
    04739       if (res == -1)  {
    04740          if (errno == EAGAIN) {
    04741             /* Return "NULL" frame if there is nobody there */
    04742             ast_mutex_unlock(&p->lock);
    04743             return &p->subs[index].f;
    04744          } else if (errno == ELAST) {
    04745             f = __zt_exception(ast);
    04746          } else
    04747             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
    04748       }
    04749       ast_mutex_unlock(&p->lock);
    04750       return f;
    04751    }
    04752    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
    04753       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
    04754       f = __zt_exception(ast);
    04755       ast_mutex_unlock(&p->lock);
    04756       return f;
    04757    }
    04758    if (p->tdd) { /* if in TDD mode, see if we receive that */
    04759       int c;
    04760
    04761       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
    04762       if (c < 0) {
    04763          ast_log(LOG_DEBUG,"tdd_feed failed\n");
    04764          ast_mutex_unlock(&p->lock);
    04765          return NULL;
    04766       }
    04767       if (c) { /* if a char to return */
    04768          p->subs[index].f.subclass = 0;
    04769          p->subs[index].f.frametype = AST_FRAME_TEXT;
    04770          p->subs[index].f.mallocd = 0;
    04771          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
    04772          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
    04773          p->subs[index].f.datalen = 1;
    04774          *((char *) p->subs[index].f.data) = c;
    04775          ast_mutex_unlock(&p->lock);
    04776          return &p->subs[index].f;
    04777       }
    04778    }
    04779    if (p->callwaitingrepeat)
    04780       p->callwaitingrepeat--;
    04781    if (p->cidcwexpire)
    04782       p->cidcwexpire--;
    04783    /* Repeat callwaiting */
    04784    if (p->callwaitingrepeat == 1) {
    04785       p->callwaitrings++;
    04786       zt_callwait(ast);
    04787    }
    04788    /* Expire CID/CW */
    04789    if (p->cidcwexpire == 1) {
    04790       if (option_verbose > 2)
    04791          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
    04792       restore_conference(p);
    04793    }
    04794    if (p->subs[index].linear) {
    04795       p->subs[index].f.datalen = READ_SIZE * 2;
    04796    } else
    04797       p->subs[index].f.datalen = READ_SIZE;
    04798
    04799    /* Handle CallerID Transmission */
    04800    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
    04801       send_callerid(p);
    04802    }
    04803
    04804    p->subs[index].f.frametype = AST_FRAME_VOICE;
    04805    p->subs[index].f.subclass = ast->rawreadformat;
    04806    p->subs[index].f.samples = READ_SIZE;
    04807    p->subs[index].f.mallocd = 0;
    04808    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
    04809    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET/2;
    04810 #if 0
    04811    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
    04812 #endif
    04813    if (p->dialing || /* Transmitting something */
    04814       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
    04815       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
    04816       ) {
    04817       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
    04818          don't send anything */
    04819       p->subs[index].f.frametype = AST_FRAME_NULL;
    04820       p->subs[index].f.subclass = 0;
    04821       p->subs[index].f.samples = 0;
    04822       p->subs[index].f.mallocd = 0;
    04823       p->subs[index].f.offset = 0;
    04824       p->subs[index].f.data = NULL;
    04825       p->subs[index].f.datalen= 0;
    04826    }
    04827    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
    04828       /* Perform busy detection. etc on the zap line */
    04829       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
    04830       if (f) {
    04831          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
    04832             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
    04833                /* Treat this as a "hangup" instead of a "busy" on the assumption that
    04834                   a busy  */
    04835                f = NULL;
    04836             }
    04837          } else if (f->frametype == AST_FRAME_DTMF) {
    04838 #ifdef ZAPATA_PRI
    04839             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
    04840                /* Don't accept in-band DTMF when in overlap dial mode */
    04841                f->frametype = AST_FRAME_NULL;
    04842                f->subclass = 0;
    04843             }
    04844 #endif
    04845             /* DSP clears us of being pulse */
    04846             p->pulsedial = 0;
    04847          }
    04848       }
    04849    } else
    04850       f = &p->subs[index].f;
    04851    if (f && (f->frametype == AST_FRAME_DTMF))
    04852       zt_handle_dtmfup(ast, index, &f);
    04853
    04854    /* If we have a fake_event, trigger exception to handle it */
    04855    if (p->fake_event)
    04856       ast_set_flag(ast, AST_FLAG_EXCEPTION);
    04857
    04858    ast_mutex_unlock(&p->lock);
    04859    return f;
    04860 }

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

Definition at line 7620 of file chan_zap.c.

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

    07621 {
    07622    int oldformat;
    07623    int groupmatch = 0;
    07624    int channelmatch = -1;
    07625    int roundrobin = 0;
    07626    int callwait = 0;
    07627    int busy = 0;
    07628    struct zt_pvt *p;
    07629    struct ast_channel *tmp = NULL;
    07630    char *dest=NULL;
    07631    int x;
    07632    char *s;
    07633    char opt=0;
    07634    int res=0, y=0;
    07635    int backwards = 0;
    07636 #ifdef ZAPATA_PRI
    07637    int crv;
    07638    int bearer = -1;
    07639    int trunkgroup;
    07640    struct zt_pri *pri=NULL;
    07641 #endif
    07642    struct zt_pvt *exit, *start, *end;
    07643    ast_mutex_t *lock;
    07644    int channelmatched = 0;
    07645    int groupmatched = 0;
    07646
    07647    /* Assume we're locking the iflock */
    07648    lock = &iflock;
    07649    start = iflist;
    07650    end = ifend;
    07651    /* We do signed linear */
    07652    oldformat = format;
    07653    format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
    07654    if (!format) {
    07655       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
    07656       return NULL;
    07657    }
    07658    if (data) {
    07659       dest = ast_strdupa((char *)data);
    07660    } else {
    07661       ast_log(LOG_WARNING, "Channel requested with no data\n");
    07662       return NULL;
    07663    }
    07664    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
    07665       /* Retrieve the group number */
    07666       char *stringp=NULL;
    07667       stringp=dest + 1;
    07668       s = strsep(&stringp, "/");
    07669       if ((res = sscanf(s, "%30d%c%30d", &x, &opt, &y)) < 1) {
    07670          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
    07671          return NULL;
    07672       }
    07673       groupmatch = 1 << x;
    07674       if (toupper(dest[0]) == 'G') {
    07675          if (dest[0] == 'G') {
    07676             backwards = 1;
    07677             p = ifend;
    07678          } else
    07679             p = iflist;
    07680       } else {
    07681          if (dest[0] == 'R') {
    07682             backwards = 1;
    07683             p = round_robin[x]?round_robin[x]->prev:ifend;
    07684             if (!p)
    07685                p = ifend;
    07686          } else {
    07687             p = round_robin[x]?round_robin[x]->next:iflist;
    07688             if (!p)
    07689                p = iflist;
    07690          }
    07691          roundrobin = 1;
    07692       }
    07693    } else {
    07694       char *stringp=NULL;
    07695       stringp=dest;
    07696       s = strsep(&stringp, "/");
    07697       p = iflist;
    07698       if (!strcasecmp(s, "pseudo")) {
    07699          /* Special case for pseudo */
    07700          x = CHAN_PSEUDO;
    07701          channelmatch = x;
    07702       }
    07703 #ifdef ZAPATA_PRI
    07704       else if ((res = sscanf(s, "%30d:%30d%c%30d", &trunkgroup, &crv, &opt, &y)) > 1) {
    07705          if ((trunkgroup < 1) || (crv < 1)) {
    07706             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
    07707             return NULL;
    07708          }
    07709          res--;
    07710          for (x=0;x<NUM_SPANS;x++) {
    07711             if (pris[x].trunkgroup == trunkgroup) {
    07712                pri = pris + x;
    07713                lock = &pri->lock;
    07714                start = pri->crvs;
    07715                end = pri->crvend;
    07716                break;
    07717             }
    07718          }
    07719          if (!pri) {
    07720             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
    07721             return NULL;
    07722          }
    07723          channelmatch = crv;
    07724          p = pris[x].crvs;
    07725       }
    07726 #endif
    07727       else if ((res = sscanf(s, "%30d%c%30d", &x, &opt, &y)) < 1) {
    07728          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
    07729          return NULL;
    07730       } else {
    07731          channelmatch = x;
    07732       }
    07733    }
    07734    /* Search for an unowned channel */
    07735    if (ast_mutex_lock(lock)) {
    07736       ast_log(LOG_ERROR, "Unable to lock interface list???\n");
    07737       return NULL;
    07738    }
    07739    exit = p;
    07740    while(p && !tmp) {
    07741       if (roundrobin)
    07742          round_robin[x] = p;
    07743 #if 0
    07744       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
    07745 #endif
    07746
    07747       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
    07748          if (option_debug)
    07749             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
    07750             if (p->inalarm)
    07751                goto next;
    07752
    07753          callwait = (p->owner != NULL);
    07754 #ifdef ZAPATA_PRI
    07755          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
    07756             if (p->sig != SIG_FXSKS) {
    07757                /* Gotta find an actual channel to use for this
    07758                   CRV if this isn't a callwait */
    07759                bearer = pri_find_empty_chan(pri, 0);
    07760                if (bearer < 0) {
    07761                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
    07762                   p = NULL;
    07763                   break;
    07764                }
    07765                pri_assign_bearer(p, pri, pri->pvts[bearer]);
    07766             } else {
    07767                if (alloc_sub(p, 0)) {
    07768                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
    07769                   p = NULL;
    07770                   break;
    07771                } else
    07772                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
    07773                p->pri = pri;
    07774             }
    07775          }
    07776 #endif
    07777          if (p->channel == CHAN_PSEUDO) {
    07778             p = chandup(p);
    07779             if (!p) {
    07780                break;
    07781             }
    07782          }
    07783          if (p->owner) {
    07784             if (alloc_sub(p, SUB_CALLWAIT)) {
    07785                p = NULL;
    07786                break;
    07787             }
    07788          }
    07789          p->outgoing = 1;
    07790          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
    07791 #ifdef ZAPATA_PRI
    07792          if (p->bearer) {
    07793             /* Log owner to bearer channel, too */
    07794             p->bearer->owner = tmp;
    07795          }
    07796 #endif
    07797          /* Make special notes */
    07798          if (res > 1) {
    07799             if (opt == 'c') {
    07800                /* Confirm answer */
    07801                p->confirmanswer = 1;
    07802             } else if (opt == 'r') {
    07803                /* Distinctive ring */
    07804                if (res < 3)
    07805                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
    07806                else
    07807                   p->distinctivering = y;
    07808             } else if (opt == 'd') {
    07809                /* If this is an ISDN call, make it digital */
    07810                p->digital = 1;
    07811                if (tmp)
    07812                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
    07813             } else {
    07814                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
    07815             }
    07816          }
    07817          /* Note if the call is a call waiting call */
    07818          if (tmp && callwait)
    07819             tmp->cdrflags |= AST_CDR_CALLWAIT;
    07820          break;
    07821       }
    07822 next:
    07823       if (backwards) {
    07824          p = p->prev;
    07825          if (!p)
    07826             p = end;
    07827       } else {
    07828          p = p->next;
    07829          if (!p)
    07830             p = start;
    07831       }
    07832       /* stop when you roll to the one that we started from */
    07833       if (p == exit)
    07834          break;
    07835    }
    07836    ast_mutex_unlock(lock);
    07837    restart_monitor();
    07838    if (callwait)
    07839       *cause = AST_CAUSE_BUSY;
    07840    else if (!tmp) {
    07841       if (channelmatched) {
    07842          if (busy)
    07843             *cause = AST_CAUSE_BUSY;
    07844       } else if (groupmatched) {
    07845          *cause = AST_CAUSE_CONGESTION;
    07846       }
    07847    }
    07848
    07849    return tmp;
    07850 }

static int zt_ring_phone | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 3452 of file chan_zap.c.

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

Referenced by __zt_exception(), and zt_handle_event().

    03453 {
    03454    int x;
    03455    int res;
    03456    /* Make sure our transmit state is on hook */
    03457    x = 0;
    03458    x = ZT_ONHOOK;
    03459    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
    03460    do {
    03461       x = ZT_RING;
    03462       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
    03463       if (res) {
    03464          switch(errno) {
    03465          case EBUSY:
    03466          case EINTR:
    03467             /* Wait just in case */
    03468             usleep(10000);
    03469             continue;
    03470          case EINPROGRESS:
    03471             res = 0;
    03472             break;
    03473          default:
    03474             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
    03475             res = 0;
    03476          }
    03477       }
    03478    } while (res);
    03479    return res;
    03480 }

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

Definition at line 11148 of file chan_zap.c.

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

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

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

Definition at line 1727 of file chan_zap.c.

References ast_log(), and LOG_WARNING.

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

    01728 {
    01729    int x, res;
    01730
    01731    x = hs;
    01732    res = ioctl(fd, ZT_HOOK, &x);
    01733
    01734    if (res < 0) {
    01735       if (errno == EINPROGRESS)
    01736          return 0;
    01737       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
    01738    }
    01739
    01740    return res;
    01741 }

int zt_setlaw | ( | int | zfd,
|  | int | law |
| ) |  |  |

Definition at line 1097 of file chan_zap.c.

    01098 {
    01099    int res;
    01100    res = ioctl(zfd, ZT_SETLAW, &law);
    01101    if (res)
    01102       return res;
    01103    return 0;
    01104 }

int zt_setlinear | ( | int | zfd,
|  | int | linear |
| ) |  |  |

Definition at line 1087 of file chan_zap.c.

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

    01088 {
    01089    int res;
    01090    res = ioctl(zfd, ZT_SETLINEAR, &linear);
    01091    if (res)
    01092       return res;
    01093    return 0;
    01094 }

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

Definition at line 2879 of file chan_zap.c.

References ast_check_hangup(), ast_dsp_digitmode(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), zt_pvt::channel, zt_pvt::didtdd, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, pollfd::events, pollfd::fd, zt_pvt::law, LOG_DEBUG, LOG_WARNING, zt_pvt::mate, ast_channel::name, poll(), POLLOUT, POLLPRI, READ_SIZE, pollfd::revents, zt_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, zt_pvt::subs, zt_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech_pvt, zt_pvt::txgain, zt_subchannel::zfd, zt_disable_ec(), and zt_get_index().

    02880 {
    02881    char *cp;
    02882    signed char *scp;
    02883    int x;
    02884    int index;
    02885    struct zt_pvt *p = chan->tech_pvt;
    02886
    02887    /* all supported options require data */
    02888    if (!data || (datalen < 1)) {
    02889       errno = EINVAL;
    02890       return -1;
    02891    }
    02892
    02893    switch(option) {
    02894    case AST_OPTION_TXGAIN:
    02895       scp = (signed char *) data;
    02896       index = zt_get_index(chan, p, 0);
    02897       if (index < 0) {
    02898          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
    02899          return -1;
    02900       }
    02901       ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
    02902       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
    02903    case AST_OPTION_RXGAIN:
    02904       scp = (signed char *) data;
    02905       index = zt_get_index(chan, p, 0);
    02906       if (index < 0) {
    02907          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
    02908          return -1;
    02909       }
    02910       ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
    02911       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
    02912    case AST_OPTION_TONE_VERIFY:
    02913       if (!p->dsp)
    02914          break;
    02915       cp = (char *) data;
    02916       switch (*cp) {
    02917       case 1:
    02918          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
    02919          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
    02920          break;
    02921       case 2:
    02922          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
    02923          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
    02924          break;
    02925       default:
    02926          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
    02927          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
    02928          break;
    02929       }
    02930       break;
    02931    case AST_OPTION_TDD:
    02932       /* turn on or off TDD */
    02933       cp = (char *) data;
    02934       p->mate = 0;
    02935       if (!*cp) { /* turn it off */
    02936          ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
    02937          if (p->tdd) tdd_free(p->tdd);
    02938          p->tdd = 0;
    02939          break;
    02940       }
    02941       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
    02942          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
    02943       zt_disable_ec(p);
    02944       /* otherwise, turn it on */
    02945       if (!p->didtdd) { /* if havent done it yet */
    02946          unsigned char mybuf[41000],*buf;
    02947          int size,res,fd,len;
    02948          struct pollfd fds[1];
    02949
    02950          buf = mybuf;
    02951          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
    02952          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
    02953          len = 40000;
    02954          index = zt_get_index(chan, p, 0);
    02955          if (index < 0) {
    02956             ast_log(LOG_WARNING, "No index in TDD?\n");
    02957             return -1;
    02958          }
    02959          fd = p->subs[index].zfd;
    02960          while(len) {
    02961             if (ast_check_hangup(chan)) return -1;
    02962             size = len;
    02963             if (size > READ_SIZE)
    02964                size = READ_SIZE;
    02965             fds[0].fd = fd;
    02966             fds[0].events = POLLPRI | POLLOUT;
    02967             fds[0].revents = 0;
    02968             res = poll(fds, 1, -1);
    02969             if (!res) {
    02970                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
    02971                continue;
    02972             }
    02973             /* if got exception */
    02974             if (fds[0].revents & POLLPRI) return -1;
    02975             if (!(fds[0].revents & POLLOUT)) {
    02976                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
    02977                continue;
    02978             }
    02979             res = write(fd, buf, size);
    02980             if (res != size) {
    02981                if (res == -1) return -1;
    02982                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
    02983                break;
    02984             }
    02985             len -= size;
    02986             buf += size;
    02987          }
    02988          p->didtdd = 1; /* set to have done it now */
    02989       }
    02990       if (*cp == 2) { /* Mate mode */
    02991          if (p->tdd) tdd_free(p->tdd);
    02992          p->tdd = 0;
    02993          p->mate = 1;
    02994          break;
    02995       }
    02996       if (!p->tdd) { /* if we dont have one yet */
    02997          p->tdd = tdd_new(); /* allocate one */
    02998       }
    02999       break;
    03000    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
    03001       if (!p->dsp)
    03002          break;
    03003       cp = (char *) data;
    03004       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
    03005          *cp ? "ON" : "OFF", (int) *cp, chan->name);
    03006       ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
    03007       break;
    03008    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
    03009       cp = (char *) data;
    03010       if (!*cp) {
    03011          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
    03012          x = 0;
    03013          zt_disable_ec(p);
    03014       } else {
    03015          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
    03016          x = 1;
    03017       }
    03018       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
    03019          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
    03020       break;
    03021    }
    03022    errno = 0;
    03023
    03024    return 0;
    03025 }

static void zt_train_ec | ( | struct zt_pvt * | p | ) | `[static]`

Definition at line 1560 of file chan_zap.c.

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

Referenced by zt_answer(), and zt_handle_event().

    01561 {
    01562    int x;
    01563    int res;
    01564    if (p && p->echocancel && p->echotraining) {
    01565       x = p->echotraining;
    01566       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
    01567       if (res)
    01568          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
    01569       else {
    01570          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
    01571       }
    01572    } else
    01573       ast_log(LOG_DEBUG, "No echo training requested\n");
    01574 }

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

Definition at line 3027 of file chan_zap.c.

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

Referenced by zt_bridge(), and zt_fixup().

    03028 {
    03029    /* Unlink a specific slave or all slaves/masters from a given master */
    03030    int x;
    03031    int hasslaves;
    03032    if (!master)
    03033       return;
    03034    if (needlock) {
    03035       ast_mutex_lock(&master->lock);
    03036       if (slave) {
    03037          while(ast_mutex_trylock(&slave->lock)) {
    03038             ast_mutex_unlock(&master->lock);
    03039             usleep(1);
    03040             ast_mutex_lock(&master->lock);
    03041          }
    03042       }
    03043    }
    03044    hasslaves = 0;
    03045    for (x=0;x<MAX_SLAVES;x++) {
    03046       if (master->slaves[x]) {
    03047          if (!slave || (master->slaves[x] == slave)) {
    03048             /* Take slave out of the conference */
    03049             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
    03050             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
    03051             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
    03052             master->slaves[x]->master = NULL;
    03053             master->slaves[x] = NULL;
    03054          } else
    03055             hasslaves = 1;
    03056       }
    03057       if (!hasslaves)
    03058          master->inconference = 0;
    03059    }
    03060    if (!slave) {
    03061       if (master->master) {
    03062          /* Take master out of the conference */
    03063          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
    03064          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
    03065          hasslaves = 0;
    03066          for (x=0;x<MAX_SLAVES;x++) {
    03067             if (master->master->slaves[x] == master)
    03068                master->master->slaves[x] = NULL;
    03069             else if (master->master->slaves[x])
    03070                hasslaves = 1;
    03071          }
    03072          if (!hasslaves)
    03073             master->master->inconference = 0;
    03074       }
    03075       master->master = NULL;
    03076    }
    03077    update_conf(master);
    03078    if (needlock) {
    03079       if (slave)
    03080          ast_mutex_unlock(&slave->lock);
    03081       ast_mutex_unlock(&master->lock);
    03082    }
    03083 }

static int zt_wait_event | ( | int | fd | ) | `[inline, static]`

Avoid the silly zt_waitevent which ignores a bunch of events.

Definition at line 262 of file chan_zap.c.

Referenced by flash_exec(), and ss_thread().

    00263 {
    00264    int i,j=0;
    00265    i = ZT_IOMUX_SIGEVENT;
    00266    if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1;
    00267    if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
    00268    return j;
    00269 }

static int zt_wink | ( | struct zt_pvt * | p,
|  | int | index |
| ) |  |  | `[static]`

Definition at line 5353 of file chan_zap.c.

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

Referenced by ss_thread().

    05354 {
    05355    int j;
    05356    zt_set_hook(p->subs[index].zfd, ZT_WINK);
    05357    for(;;)
    05358    {
    05359          /* set bits of interest */
    05360       j = ZT_IOMUX_SIGEVENT;
    05361           /* wait for some happening */
    05362       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
    05363          /* exit loop if we have it */
    05364       if (j & ZT_IOMUX_SIGEVENT) break;
    05365    }
    05366      /* get the event info */
    05367    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
    05368    return 0;
    05369 }

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

Definition at line 4885 of file chan_zap.c.

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

    04886 {
    04887    struct zt_pvt *p = ast->tech_pvt;
    04888    int res;
    04889    unsigned char outbuf[4096];
    04890    int index;
    04891    index = zt_get_index(ast, p, 0);
    04892    if (index < 0) {
    04893       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
    04894       return -1;
    04895    }
    04896
    04897 #if 0
    04898 #ifdef ZAPATA_PRI
    04899    ast_mutex_lock(&p->lock);
    04900    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
    04901       if (p->pri->pri) {
    04902          if (!pri_grab(p, p->pri)) {
    04903                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
    04904                pri_rel(p->pri);
    04905          } else
    04906                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
    04907       }
    04908       p->proceeding=1;
    04909    }
    04910    ast_mutex_unlock(&p->lock);
    04911 #endif
    04912 #endif
    04913    /* Write a frame of (presumably voice) data */
    04914    if (frame->frametype != AST_FRAME_VOICE) {
    04915       if (frame->frametype != AST_FRAME_IMAGE)
    04916          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
    04917       return 0;
    04918    }
    04919    if ((frame->subclass != AST_FORMAT_SLINEAR) &&
    04920        (frame->subclass != AST_FORMAT_ULAW) &&
    04921        (frame->subclass != AST_FORMAT_ALAW)) {
    04922       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
    04923       return -1;
    04924    }
    04925    if (p->dialing) {
    04926       if (option_debug)
    04927          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
    04928       return 0;
    04929    }
    04930    if (!p->owner) {
    04931       if (option_debug)
    04932          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
    04933       return 0;
    04934    }
    04935    if (p->cidspill) {
    04936       if (option_debug)
    04937          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
    04938       return 0;
    04939    }
    04940    /* Return if it's not valid data */
    04941    if (!frame->data || !frame->datalen)
    04942       return 0;
    04943    if (frame->datalen > sizeof(outbuf) * 2) {
    04944       ast_log(LOG_WARNING, "Frame too large\n");
    04945       return 0;
    04946    }
    04947
    04948    if (frame->subclass == AST_FORMAT_SLINEAR) {
    04949       if (!p->subs[index].linear) {
    04950          p->subs[index].linear = 1;
    04951          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
    04952          if (res)
    04953             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
    04954       }
    04955       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
    04956    } else {
    04957       /* x-law already */
    04958       if (p->subs[index].linear) {
    04959          p->subs[index].linear = 0;
    04960          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
    04961          if (res)
    04962             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
    04963       }
    04964       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
    04965    }
    04966    if (res < 0) {
    04967       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
    04968       return -1;
    04969    }
    04970    return 0;
    04971 }

## Variable Documentation

int alarm

Definition at line 1226 of file chan_zap.c.

Referenced by action_zapshowchannels().

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

Referenced by alarm2str(), and zap_show_status().

struct zt_ring_cadence cadences[NUM_CADENCE_MAX]`[static]`

Definition at line 907 of file chan_zap.c.

int cidrings[NUM_CADENCE_MAX]`[static]`

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

Definition at line 918 of file chan_zap.c.

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

Definition at line 160 of file chan_zap.c.

char defaultcic[64] = ""`[static]`

Definition at line 198 of file chan_zap.c.

char defaultozz[64] = ""`[static]`

Definition at line 199 of file chan_zap.c.

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

Definition at line 141 of file chan_zap.c.

char destroy_channel_usage[]`[static]`

Initial value:

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

Definition at line 10022 of file chan_zap.c.

struct zt_distRings drings`[static]`

Definition at line 375 of file chan_zap.c.

Referenced by mkintf(), and setup_zap().

char* events[]`[static]`

Definition at line 1203 of file chan_zap.c.

Referenced by authenticate().

int firstdigittimeout = 16000`[static]`

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

Definition at line 218 of file chan_zap.c.

int gendigittimeout = 8000`[static]`

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

Definition at line 221 of file chan_zap.c.

int ifcount = 0`[static]`

Definition at line 233 of file chan_zap.c.

struct zt_pvt * ifend`[static]`

Referenced by __build_step().

struct zt_pvt * iflist`[static]`

char language[MAX_LANGUAGE] = ""`[static]`

Definition at line 201 of file chan_zap.c.

int matchdigittimeout = 3000`[static]`

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

Definition at line 224 of file chan_zap.c.

pthread_t monitor_thread = AST_PTHREADT_NULL`[static]`

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

Definition at line 245 of file chan_zap.c.

char* name

Definition at line 1227 of file chan_zap.c.

int num_cadence = 4`[static]`

Definition at line 904 of file chan_zap.c.

int numbufs = 4`[static]`

Definition at line 206 of file chan_zap.c.

char progzone[10] = ""`[static]`

Definition at line 202 of file chan_zap.c.

int ringt_base = DEFAULT_RINGT`[static]`

Definition at line 290 of file chan_zap.c.

struct zt_pvt* round_robin[32]

Definition at line 881 of file chan_zap.c.

char show_channel_usage[]`[static]`

Initial value:

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

Definition at line 10014 of file chan_zap.c.

char show_channels_usage[]`[static]`

Initial value:

       "Usage: zap show channels\n"
       "  Shows a list of available channels\n"

Definition at line 10010 of file chan_zap.c.

char* subnames[]`[static]`

Initial value:

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

Definition at line 388 of file chan_zap.c.

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

Definition at line 150 of file chan_zap.c.

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

Definition at line 159 of file chan_zap.c.

int usecnt = 0`[static]`

Definition at line 226 of file chan_zap.c.

int usedistinctiveringdetection = 0`[static]`

Definition at line 204 of file chan_zap.c.

int user_has_defined_cadences = 0`[static]`

Definition at line 905 of file chan_zap.c.

struct ast_cli_entry zap_cli[]`[static]`

Definition at line 10026 of file chan_zap.c.

char zap_show_cadences_help[]`[static]`

Initial value:

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

Definition at line 9918 of file chan_zap.c.

char zap_show_status_usage[]`[static]`

Initial value:

       "Usage: zap show status\n"
       "       Shows a list of Zaptel cards with status\n"

Definition at line 10018 of file chan_zap.c.

struct ast_channel_tech zap_tech`[static]`

Definition at line 856 of file chan_zap.c.