#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <zaptel.h>
#include <math.h>
#include <tonezone.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
Include dependency graph for chan_zap.c:
Go to the source code of this file.
Data Structures | |
struct | distRingData |
struct | ringContextData |
struct | zt_distRings |
struct | zt_pvt |
struct | zt_subchannel |
Defines | |
#define | ASCII_BYTES_PER_CHAR 80 |
#define | AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
#define | CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define | CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
#define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CHAN_PSEUDO -2 |
#define | CHANNEL_PSEUDO -12 |
#define | CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define | CONF_USER_REAL (1 << 0) |
#define | CONF_USER_THIRDCALL (1 << 1) |
#define | DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 1) |
#define | DCHAN_PROVISIONED (1 << 0) |
#define | DCHAN_UP (1 << 2) |
#define | DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID. | |
#define | DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
#define | END_SILENCE_LEN 400 |
#define | FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | GET_CHANNEL(p) ((p)->channel) |
#define | HANGUP 1 |
#define | HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
#define | HEADER_MS 50 |
#define | ISTRUNK(p) |
#define | MASK_AVAIL (1 << 0) |
#define | MASK_INUSE (1 << 1) |
#define | MAX_CHANNELS 672 |
#define | MAX_SLAVES 4 |
#define | MIN_MS_SINCE_FLASH ( (2000) ) |
#define | NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro. | |
#define | NUM_CADENCE_MAX 25 |
#define | NUM_DCHANS 4 |
#define | NUM_SPANS 32 |
#define | POLARITY_IDLE 0 |
#define | POLARITY_REV 1 |
#define | READ_SIZE 160 |
#define | sig2str zap_sig2str |
#define | SIG_E911 (0x1000000 | ZT_SIG_EM) |
#define | SIG_EM ZT_SIG_EM |
#define | SIG_EM_E1 ZT_SIG_EM_E1 |
#define | SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
#define | SIG_FEATB (0x0800000 | ZT_SIG_EM) |
#define | SIG_FEATD (0x0200000 | ZT_SIG_EM) |
#define | SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
#define | SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
#define | SIG_FXOGS ZT_SIG_FXOGS |
#define | SIG_FXOKS ZT_SIG_FXOKS |
#define | SIG_FXOLS ZT_SIG_FXOLS |
#define | SIG_FXSGS ZT_SIG_FXSGS |
#define | SIG_FXSKS ZT_SIG_FXSKS |
#define | SIG_FXSLS ZT_SIG_FXSLS |
#define | SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
#define | SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
#define | SIG_PRI ZT_SIG_CLEAR |
#define | SIG_R2 ZT_SIG_CAS |
#define | SIG_SF ZT_SIG_SF |
#define | SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
#define | SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
#define | SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
#define | SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
#define | SUB_CALLWAIT 1 |
#define | SUB_REAL 0 |
#define | SUB_THREEWAY 2 |
#define | TRAILER_MS 5 |
#define | TRANSFER 0 |
#define | ZT_EVENT_DTMFDOWN 0 |
#define | ZT_EVENT_DTMFUP 0 |
Functions | |
static int | __unload_module (void) |
static struct ast_frame * | __zt_exception (struct ast_channel *ast) |
static int | action_transfer (struct mansession *s, struct message *m) |
static int | action_transferhangup (struct mansession *s, struct message *m) |
static int | action_zapdialoffhook (struct mansession *s, struct message *m) |
static int | action_zapdndoff (struct mansession *s, struct message *m) |
static int | action_zapdndon (struct mansession *s, struct message *m) |
static int | action_zaprestart (struct mansession *s, struct message *m) |
static int | action_zapshowchannels (struct mansession *s, struct message *m) |
static char * | alarm2str (int alarm) |
static int | alloc_sub (struct zt_pvt *p, int x) |
AST_MUTEX_DEFINE_STATIC (monlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the interface list (of zt_pvt's). | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static int | attempt_transfer (struct zt_pvt *p) |
static int | available (struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched) |
static int | bump_gains (struct zt_pvt *p) |
static struct zt_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, int signalling, int radio, struct zt_pri *pri, int reloading) |
static int | my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
static int | my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear) |
int | reload (void) |
Reload stuff. | |
static int | reset_conf (struct zt_pvt *p) |
static int | restart_monitor (void) |
static int | restore_conference (struct zt_pvt *p) |
static int | restore_gains (struct zt_pvt *p) |
static int | save_conference (struct zt_pvt *p) |
static int | send_callerid (struct zt_pvt *p) |
int | send_cwcidspill (struct zt_pvt *p) |
int | set_actual_gain (int fd, int chan, float rxgain, float txgain, int law) |
int | set_actual_rxgain (int fd, int chan, float gain, int law) |
int | set_actual_txgain (int fd, int chan, float gain, int law) |
static int | setup_zap (int reload) |
static void * | ss_thread (void *data) |
static void | swap_subs (struct zt_pvt *p, int a, int b) |
static int | unalloc_sub (struct zt_pvt *p, int x) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
static int | update_conf (struct zt_pvt *p) |
int | usecount () |
Provides a usecount. | |
static void | wakeup_sub (struct zt_pvt *p, int a, void *pri) |
static int | zap_destroy_channel (int fd, int argc, char **argv) |
static int | zap_fake_event (struct zt_pvt *p, int mode) |
static void | zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *pri) |
static int | zap_restart (void) |
static int | zap_restart_cmd (int fd, int argc, char **argv) |
static int | zap_show_channel (int fd, int argc, char **argv) |
static int | zap_show_channels (int fd, int argc, char **argv) |
static int | zap_show_status (int fd, int argc, char *argv[]) |
static char * | zap_sig2str (int sig) |
static int | zt_answer (struct ast_channel *ast) |
static enum ast_bridge_result | zt_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | zt_call (struct ast_channel *ast, char *rdest, int timeout) |
static int | zt_callwait (struct ast_channel *ast) |
static void | zt_close (int fd) |
static int | zt_confmute (struct zt_pvt *p, int muted) |
static int | zt_digit (struct ast_channel *ast, char digit) |
static void | zt_disable_ec (struct zt_pvt *p) |
static void | zt_enable_ec (struct zt_pvt *p) |
ast_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_history (int fd, void *buf, int buf_size) |
static int | zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok) |
static struct ast_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) |
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 | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] = "" |
static int | adsi = 0 |
struct { | |
int alarm | |
char * name | |
} | alarms [] |
static int | amaflags = 0 |
static int | answeronpolarityswitch = 0 |
Whether we answer on a Polarity Switch event. | |
static int | busy_quietlength = 0 |
static int | busy_tonelength = 0 |
static int | busycount = 3 |
static int | busydetect = 0 |
static struct zt_ring_cadence | cadences [NUM_CADENCE_MAX] |
static int | callprogress = 0 |
static int | callreturn = 0 |
static int | callwaiting = 0 |
static int | callwaitingcallerid = 0 |
static int | cancallforward = 0 |
static int | canpark = 0 |
static char | cid_name [256] = "" |
static char | cid_num [256] = "" |
static int | cid_signalling = CID_SIG_BELL |
static int | cid_start = CID_START_RING |
static int | cidrings [NUM_CADENCE_MAX] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
static const char | config [] = "zapata.conf" |
static char | context [AST_MAX_CONTEXT] = "default" |
static ast_group_t | cur_callergroup = 0 |
static int | cur_debounce = -1 |
static int | cur_flash = -1 |
static ast_group_t | cur_group = 0 |
static ast_group_t | cur_pickupgroup = 0 |
static int | cur_preflash = -1 |
static int | cur_prewink = -1 |
static int | cur_priexclusive = 0 |
static int | cur_rxflash = -1 |
static int | cur_rxwink = -1 |
static int | cur_signalling = -1 |
static int | cur_start = -1 |
static int | cur_wink = -1 |
static char | defaultcic [64] = "" |
static char | defaultozz [64] = "" |
static const char | desc [] = "Zapata Telephony" |
static char | destroy_channel_usage [] |
static struct zt_distRings | drings |
static int | echocanbridged = 0 |
static int | echocancel |
static int | echotraining |
static char * | events [] |
static int | firstdigittimeout = 16000 |
Wait up to 16 seconds for first digit (FXO logic). | |
static int | gendigittimeout = 8000 |
How long to wait for following digits (FXO logic). | |
static int | hanguponpolarityswitch = 0 |
Whether we hang up on a Polarity Switch event. | |
static int | hidecallerid = 0 |
static int | ifcount = 0 |
static struct zt_pvt * | ifend |
static struct zt_pvt * | iflist |
static int | immediate = 0 |
static char | language [MAX_LANGUAGE] = "" |
static char | mailbox [AST_MAX_EXTENSION] |
static int | matchdigittimeout = 3000 |
How long to wait for an extra digit, if there is an ambiguous match. | |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static char | musicclass [MAX_MUSICCLASS] = "" |
static int | num_cadence = 4 |
static int | numbufs = 4 |
static int | polarityonanswerdelay = 600 |
How long (ms) to ignore Polarity Switch events after we answer a call. | |
static int | priindication_oob = 0 |
static char | progzone [10] = "" |
static int | pulse |
static int | relaxdtmf = 0 |
static int | restrictcid = 0 |
static int | ringt_base = DEFAULT_RINGT |
zt_pvt * | round_robin [32] |
static float | rxgain = 0.0 |
static int | sendcalleridafter = DEFAULT_CIDRINGS |
When to send the CallerID signals (rings). | |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static int | stripmsd = 0 |
static char * | subnames [] |
static const char | tdesc [] = "Zapata Telephony Driver" |
static int | threewaycalling = 0 |
static int | tonezone = -1 |
static int | transfer = 0 |
static int | transfertobusy = 1 |
static float | txgain = 0.0 |
static const char | type [] = "Zap" |
static int | use_callerid = 1 |
static int | use_callingpres = 0 |
static int | usecnt = 0 |
static int | usedistinctiveringdetection = 0 |
static int | user_has_defined_cadences = 0 |
static struct ast_cli_entry | zap_cli [] |
static char | zap_restart_usage [] |
static char | zap_show_cadences_help [] |
static char | zap_show_status_usage [] |
static struct ast_channel_tech | zap_tech |
static int | zaptrcallerid = 0 |
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.
Definition in file chan_zap.c.
#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) |
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 384 of file chan_zap.c.
#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 |
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) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 518 of file chan_zap.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 519 of file chan_zap.c.
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
Definition at line 196 of file chan_zap.c.
#define DCHAN_NOTINALARM (1 << 1) |
Definition at line 193 of file chan_zap.c.
#define DCHAN_PROVISIONED (1 << 0) |
Definition at line 192 of file chan_zap.c.
#define DCHAN_UP (1 << 2) |
Definition at line 194 of file chan_zap.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 132 of file chan_zap.c.
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
Definition at line 388 of file chan_zap.c.
#define END_SILENCE_LEN 400 |
Referenced by zt_sendtext().
#define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define GET_CHANNEL | ( | p | ) | ((p)->channel) |
Definition at line 727 of file chan_zap.c.
#define HANGUP 1 |
Definition at line 10021 of file chan_zap.c.
Referenced by action_transferhangup(), and zap_fake_event().
#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by zt_sendtext().
#define HEADER_MS 50 |
Referenced by zt_sendtext().
#define ISTRUNK | ( | p | ) |
#define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 381 of file chan_zap.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 382 of file chan_zap.c.
#define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 188 of file chan_zap.c.
Referenced by mkintf().
#define MAX_SLAVES 4 |
#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.
Definition at line 139 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
#define NUM_CADENCE_MAX 25 |
Definition at line 752 of file chan_zap.c.
#define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 187 of file chan_zap.c.
#define NUM_SPANS 32 |
Definition at line 186 of file chan_zap.c.
#define POLARITY_IDLE 0 |
Definition at line 478 of file chan_zap.c.
Referenced by unalloc_sub(), zt_handle_event(), and zt_hangup().
#define POLARITY_REV 1 |
Definition at line 479 of file chan_zap.c.
Referenced by handle_init_event(), and zt_handle_event().
#define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 379 of file chan_zap.c.
Referenced by my_zt_write(), send_cwcidspill(), setup_zap(), zt_callwait(), zt_open(), zt_read(), zt_sendtext(), and zt_setoption().
#define sig2str zap_sig2str |
Definition at line 1198 of file chan_zap.c.
Referenced by action_zapshowchannels(), handle_init_event(), mkintf(), setup_zap(), zap_show_channel(), and zt_handle_event().
#define SIG_E911 (0x1000000 | ZT_SIG_EM) |
Definition at line 167 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM ZT_SIG_EM |
Definition at line 162 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM_E1 ZT_SIG_EM_E1 |
Definition at line 182 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
Definition at line 163 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 166 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 164 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 165 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
Definition at line 168 of file chan_zap.c.
Referenced by setup_zap(), zap_sig2str(), zt_call(), and zt_handle_event().
#define SIG_FXOGS ZT_SIG_FXOGS |
Definition at line 173 of file chan_zap.c.
Referenced by available(), handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXOKS ZT_SIG_FXOKS |
Definition at line 174 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXOLS ZT_SIG_FXOLS |
Definition at line 172 of file chan_zap.c.
Referenced by available(), handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXSGS ZT_SIG_FXSGS |
Definition at line 170 of file chan_zap.c.
Referenced by available(), handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_FXSKS ZT_SIG_FXSKS |
Definition at line 171 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), and zt_request().
#define SIG_FXSLS ZT_SIG_FXSLS |
Definition at line 169 of file chan_zap.c.
Referenced by available(), handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
Definition at line 183 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), setup_zap(), and zap_sig2str().
#define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
Definition at line 184 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), setup_zap(), and zap_sig2str().
#define SIG_PRI ZT_SIG_CLEAR |
Definition at line 175 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().
#define SIG_R2 ZT_SIG_CAS |
Definition at line 176 of file chan_zap.c.
Referenced by mkintf(), setup_zap(), zap_sig2str(), zt_answer(), zt_handle_event(), and zt_hangup().
#define SIG_SF ZT_SIG_SF |
Definition at line 177 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
Definition at line 181 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
Definition at line 179 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
Definition at line 180 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
Definition at line 178 of file chan_zap.c.
Referenced by handle_init_event(), setup_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 474 of file chan_zap.c.
#define SUB_REAL 0 |
Active call
Definition at line 473 of file chan_zap.c.
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 475 of file chan_zap.c.
#define TRAILER_MS 5 |
Referenced by zt_sendtext().
#define TRANSFER 0 |
#define ZT_EVENT_DTMFDOWN 0 |
#define ZT_EVENT_DTMFUP 0 |
static int __unload_module | ( | void | ) | [static] |
Definition at line 10197 of file chan_zap.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_verbose(), zt_pvt::cidspill, destroy_zt_pvt(), free, iflist, master, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, zap_cli, zap_tech, and zt_close().
10198 { 10199 int x = 0; 10200 struct zt_pvt *p, *pl; 10201 #ifdef ZAPATA_PRI 10202 int i; 10203 for(i=0;i<NUM_SPANS;i++) { 10204 if (pris[i].master != AST_PTHREADT_NULL) 10205 pthread_cancel(pris[i].master); 10206 } 10207 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0])); 10208 #endif 10209 #ifdef ZAPATA_R2 10210 ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0])); 10211 #endif 10212 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0])); 10213 ast_manager_unregister( "ZapDialOffhook" ); 10214 ast_manager_unregister( "ZapHangup" ); 10215 ast_manager_unregister( "ZapTransfer" ); 10216 ast_manager_unregister( "ZapDNDoff" ); 10217 ast_manager_unregister( "ZapDNDon" ); 10218 ast_manager_unregister("ZapShowChannels"); 10219 ast_channel_unregister(&zap_tech); 10220 if (!ast_mutex_lock(&iflock)) { 10221 /* Hangup all interfaces if they have an owner */ 10222 p = iflist; 10223 while(p) { 10224 if (p->owner) 10225 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 10226 p = p->next; 10227 } 10228 ast_mutex_unlock(&iflock); 10229 } else { 10230 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 10231 return -1; 10232 } 10233 if (!ast_mutex_lock(&monlock)) { 10234 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 10235 pthread_cancel(monitor_thread); 10236 pthread_kill(monitor_thread, SIGURG); 10237 pthread_join(monitor_thread, NULL); 10238 } 10239 monitor_thread = AST_PTHREADT_STOP; 10240 ast_mutex_unlock(&monlock); 10241 } else { 10242 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 10243 return -1; 10244 } 10245 10246 if (!ast_mutex_lock(&iflock)) { 10247 /* Destroy all the interfaces and free their memory */ 10248 p = iflist; 10249 while(p) { 10250 /* Free any callerid */ 10251 if (p->cidspill) 10252 free(p->cidspill); 10253 /* Close the zapata thingy */ 10254 if (p->subs[SUB_REAL].zfd > -1) 10255 zt_close(p->subs[SUB_REAL].zfd); 10256 pl = p; 10257 p = p->next; 10258 x++; 10259 /* Free associated memory */ 10260 if(pl) 10261 destroy_zt_pvt(&pl); 10262 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 10263 } 10264 iflist = NULL; 10265 ifcount = 0; 10266 ast_mutex_unlock(&iflock); 10267 } else { 10268 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 10269 return -1; 10270 } 10271 #ifdef ZAPATA_PRI 10272 for(i=0;i<NUM_SPANS;i++) { 10273 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 10274 pthread_join(pris[i].master, NULL); 10275 zt_close(pris[i].fds[i]); 10276 } 10277 #endif 10278 return 0; 10279 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4266 of file chan_zap.c.
References ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_moh_stop(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, event2str(), zt_subchannel::f, zt_pvt::fake_event, ast_channel::fds, ast_frame::frametype, LOG_DEBUG, ast_frame::mallocd, ast_channel::name, ast_frame::offset, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_disable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().
Referenced by zt_exception(), and zt_read().
04267 { 04268 struct zt_pvt *p = ast->tech_pvt; 04269 int res; 04270 int usedindex=-1; 04271 int index; 04272 struct ast_frame *f; 04273 04274 04275 index = zt_get_index(ast, p, 1); 04276 04277 p->subs[index].f.frametype = AST_FRAME_NULL; 04278 p->subs[index].f.datalen = 0; 04279 p->subs[index].f.samples = 0; 04280 p->subs[index].f.mallocd = 0; 04281 p->subs[index].f.offset = 0; 04282 p->subs[index].f.subclass = 0; 04283 p->subs[index].f.delivery = ast_tv(0,0); 04284 p->subs[index].f.src = "zt_exception"; 04285 p->subs[index].f.data = NULL; 04286 04287 04288 if ((!p->owner) && (!p->radio)) { 04289 /* If nobody owns us, absorb the event appropriately, otherwise 04290 we loop indefinitely. This occurs when, during call waiting, the 04291 other end hangs up our channel so that it no longer exists, but we 04292 have neither FLASH'd nor ONHOOK'd to signify our desire to 04293 change to the other channel. */ 04294 if (p->fake_event) { 04295 res = p->fake_event; 04296 p->fake_event = 0; 04297 } else 04298 res = zt_get_event(p->subs[SUB_REAL].zfd); 04299 /* Switch to real if there is one and this isn't something really silly... */ 04300 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04301 (res != ZT_EVENT_HOOKCOMPLETE)) { 04302 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04303 p->owner = p->subs[SUB_REAL].owner; 04304 if (p->owner && ast_bridged_channel(p->owner)) 04305 ast_moh_stop(ast_bridged_channel(p->owner)); 04306 } 04307 switch(res) { 04308 case ZT_EVENT_ONHOOK: 04309 zt_disable_ec(p); 04310 if (p->owner) { 04311 if (option_verbose > 2) 04312 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04313 zt_ring_phone(p); 04314 p->callwaitingrepeat = 0; 04315 p->cidcwexpire = 0; 04316 } else 04317 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04318 update_conf(p); 04319 break; 04320 case ZT_EVENT_RINGOFFHOOK: 04321 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04322 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04323 p->subs[SUB_REAL].needanswer = 1; 04324 p->dialing = 0; 04325 } 04326 break; 04327 case ZT_EVENT_HOOKCOMPLETE: 04328 case ZT_EVENT_RINGERON: 04329 case ZT_EVENT_RINGEROFF: 04330 /* Do nothing */ 04331 break; 04332 case ZT_EVENT_WINKFLASH: 04333 gettimeofday(&p->flashtime, NULL); 04334 if (p->owner) { 04335 if (option_verbose > 2) 04336 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04337 if (p->owner->_state != AST_STATE_UP) { 04338 /* Answer if necessary */ 04339 usedindex = zt_get_index(p->owner, p, 0); 04340 if (usedindex > -1) { 04341 p->subs[usedindex].needanswer = 1; 04342 } 04343 ast_setstate(p->owner, AST_STATE_UP); 04344 } 04345 p->callwaitingrepeat = 0; 04346 p->cidcwexpire = 0; 04347 if (ast_bridged_channel(p->owner)) 04348 ast_moh_stop(ast_bridged_channel(p->owner)); 04349 } else 04350 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04351 update_conf(p); 04352 break; 04353 default: 04354 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04355 } 04356 f = &p->subs[index].f; 04357 return f; 04358 } 04359 if (!p->radio) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04360 /* If it's not us, return NULL immediately */ 04361 if (ast != p->owner) { 04362 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04363 f = &p->subs[index].f; 04364 return f; 04365 } 04366 f = zt_handle_event(ast); 04367 return f; 04368 }
static int action_transfer | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 10087 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), s, TRANSFER, and zap_fake_event().
Referenced by load_module().
10088 { 10089 struct zt_pvt *p = NULL; 10090 char *channel = astman_get_header(m, "ZapChannel"); 10091 if (ast_strlen_zero(channel)) { 10092 astman_send_error(s, m, "No channel specified"); 10093 return 0; 10094 } 10095 p = find_channel(atoi(channel)); 10096 if (!p) { 10097 astman_send_error(s, m, "No such channel"); 10098 return 0; 10099 } 10100 zap_fake_event(p,TRANSFER); 10101 astman_send_ack(s, m, "ZapTransfer"); 10102 return 0; 10103 }
static int action_transferhangup | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 10105 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, s, and zap_fake_event().
Referenced by load_module().
10106 { 10107 struct zt_pvt *p = NULL; 10108 char *channel = astman_get_header(m, "ZapChannel"); 10109 if (ast_strlen_zero(channel)) { 10110 astman_send_error(s, m, "No channel specified"); 10111 return 0; 10112 } 10113 p = find_channel(atoi(channel)); 10114 if (!p) { 10115 astman_send_error(s, m, "No such channel"); 10116 return 0; 10117 } 10118 zap_fake_event(p,HANGUP); 10119 astman_send_ack(s, m, "ZapHangup"); 10120 return 0; 10121 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 10123 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), zt_pvt::owner, s, and zap_queue_frame().
Referenced by load_module().
10124 { 10125 struct zt_pvt *p = NULL; 10126 char *channel = astman_get_header(m, "ZapChannel"); 10127 char *number = astman_get_header(m, "Number"); 10128 int i; 10129 if (ast_strlen_zero(channel)) { 10130 astman_send_error(s, m, "No channel specified"); 10131 return 0; 10132 } 10133 if (ast_strlen_zero(number)) { 10134 astman_send_error(s, m, "No number specified"); 10135 return 0; 10136 } 10137 p = find_channel(atoi(channel)); 10138 if (!p) { 10139 astman_send_error(s, m, "No such channel"); 10140 return 0; 10141 } 10142 if (!p->owner) { 10143 astman_send_error(s, m, "Channel does not have it's owner"); 10144 return 0; 10145 } 10146 for (i=0; i<strlen(number); i++) { 10147 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 10148 zap_queue_frame(p, &f, NULL); 10149 } 10150 astman_send_ack(s, m, "ZapDialOffhook"); 10151 return 0; 10152 }
static int action_zapdndoff | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 10069 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.
Referenced by load_module().
10070 { 10071 struct zt_pvt *p = NULL; 10072 char *channel = astman_get_header(m, "ZapChannel"); 10073 if (ast_strlen_zero(channel)) { 10074 astman_send_error(s, m, "No channel specified"); 10075 return 0; 10076 } 10077 p = find_channel(atoi(channel)); 10078 if (!p) { 10079 astman_send_error(s, m, "No such channel"); 10080 return 0; 10081 } 10082 p->dnd = 0; 10083 astman_send_ack(s, m, "DND Disabled"); 10084 return 0; 10085 }
static int action_zapdndon | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 10051 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.
Referenced by load_module().
10052 { 10053 struct zt_pvt *p = NULL; 10054 char *channel = astman_get_header(m, "ZapChannel"); 10055 if (ast_strlen_zero(channel)) { 10056 astman_send_error(s, m, "No channel specified"); 10057 return 0; 10058 } 10059 p = find_channel(atoi(channel)); 10060 if (!p) { 10061 astman_send_error(s, m, "No such channel"); 10062 return 0; 10063 } 10064 p->dnd = 1; 10065 astman_send_ack(s, m, "DND Enabled"); 10066 return 0; 10067 }
static int action_zaprestart | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 9682 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), s, and zap_restart().
09683 { 09684 if (zap_restart() != 0) { 09685 astman_send_error(s, m, "Failed rereading zaptel configuration"); 09686 return 1; 09687 } 09688 astman_send_ack(s, m, "ZapRestart: Success"); 09689 return 0; 09690 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
Definition at line 10154 of file chan_zap.c.
References alarm, alarm2str(), ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, s, zt_pvt::sig, and sig2str.
Referenced by load_module().
10155 { 10156 struct zt_pvt *tmp = NULL; 10157 char *id = astman_get_header(m, "ActionID"); 10158 char idText[256] = ""; 10159 10160 astman_send_ack(s, m, "Zapata channel status will follow"); 10161 if (!ast_strlen_zero(id)) 10162 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 10163 10164 ast_mutex_lock(&iflock); 10165 10166 tmp = iflist; 10167 while (tmp) { 10168 if (tmp->channel > 0) { 10169 int alarm = get_alarms(tmp); 10170 ast_cli(s->fd, 10171 "Event: ZapShowChannels\r\n" 10172 "Channel: %d\r\n" 10173 "Signalling: %s\r\n" 10174 "Context: %s\r\n" 10175 "DND: %s\r\n" 10176 "Alarm: %s\r\n" 10177 "%s" 10178 "\r\n", 10179 tmp->channel, sig2str(tmp->sig), tmp->context, 10180 tmp->dnd ? "Enabled" : "Disabled", 10181 alarm2str(alarm), idText); 10182 } 10183 10184 tmp = tmp->next; 10185 } 10186 10187 ast_mutex_unlock(&iflock); 10188 10189 ast_cli(s->fd, 10190 "Event: ZapShowChannelsComplete\r\n" 10191 "%s" 10192 "\r\n", 10193 idText); 10194 return 0; 10195 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1095 of file chan_zap.c.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01096 { 01097 int x; 01098 for (x=0;x<sizeof(alarms) / sizeof(alarms[0]); x++) { 01099 if (alarms[x].alarm & alarm) 01100 return alarms[x].name; 01101 } 01102 return alarm ? "Unknown Alarm" : "No Alarm"; 01103 }
static int alloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 963 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().
Referenced by ss_thread(), zt_handle_event(), and zt_request().
00964 { 00965 ZT_BUFFERINFO bi; 00966 int res; 00967 if (p->subs[x].zfd < 0) { 00968 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 00969 if (p->subs[x].zfd > -1) { 00970 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 00971 if (!res) { 00972 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 00973 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 00974 bi.numbufs = numbufs; 00975 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 00976 if (res < 0) { 00977 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 00978 } 00979 } else 00980 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 00981 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 00982 ast_log(LOG_WARNING,"Unable to get channel number for pseudo channel on FD %d\n",p->subs[x].zfd); 00983 zt_close(p->subs[x].zfd); 00984 p->subs[x].zfd = -1; 00985 return -1; 00986 } 00987 if (option_debug) 00988 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 00989 return 0; 00990 } else 00991 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00992 return -1; 00993 } 00994 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 00995 return -1; 00996 }
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the interface list (of zt_pvt's).
AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock | ) |
static int attempt_transfer | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3340 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, ast_indicate(), ast_log(), ast_moh_stop(), ast_mutex_unlock(), AST_SOFTHANGUP_DEV, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, ast_channel::name, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), and unalloc_sub().
03341 { 03342 /* In order to transfer, we need at least one of the channels to 03343 actually be in a call bridge. We can't conference two applications 03344 together (but then, why would we want to?) */ 03345 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03346 /* The three-way person we're about to transfer to could still be in MOH, so 03347 stop if now if appropriate */ 03348 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03349 ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner)); 03350 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03351 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03352 } 03353 if (p->subs[SUB_REAL].owner->cdr) { 03354 /* Move CDR from second channel to current one */ 03355 p->subs[SUB_THREEWAY].owner->cdr = 03356 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03357 p->subs[SUB_REAL].owner->cdr = NULL; 03358 } 03359 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03360 /* Move CDR from second channel's bridge to current one */ 03361 p->subs[SUB_THREEWAY].owner->cdr = 03362 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03363 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03364 } 03365 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03366 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03367 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03368 return -1; 03369 } 03370 /* Orphan the channel after releasing the lock */ 03371 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03372 unalloc_sub(p, SUB_THREEWAY); 03373 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03374 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03375 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03376 } 03377 ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner)); 03378 if (p->subs[SUB_THREEWAY].owner->cdr) { 03379 /* Move CDR from second channel to current one */ 03380 p->subs[SUB_REAL].owner->cdr = 03381 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03382 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03383 } 03384 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03385 /* Move CDR from second channel's bridge to current one */ 03386 p->subs[SUB_REAL].owner->cdr = 03387 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03388 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03389 } 03390 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03391 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03392 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03393 return -1; 03394 } 03395 /* Three-way is now the REAL */ 03396 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03397 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03398 unalloc_sub(p, SUB_THREEWAY); 03399 /* Tell the caller not to hangup */ 03400 return 1; 03401 } else { 03402 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03403 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03404 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03405 return -1; 03406 } 03407 return 0; 03408 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
int | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7393 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, LOG_DEBUG, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and zt_pvt::subs.
Referenced by zt_request().
07394 { 07395 int res; 07396 ZT_PARAMS par; 07397 07398 /* First, check group matching */ 07399 if (groupmatch) { 07400 if ((p->group & groupmatch) != groupmatch) 07401 return 0; 07402 *groupmatched = 1; 07403 } 07404 /* Check to see if we have a channel match */ 07405 if (channelmatch != -1) { 07406 if (p->channel != channelmatch) 07407 return 0; 07408 *channelmatched = 1; 07409 } 07410 /* We're at least busy at this point */ 07411 if (busy) { 07412 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07413 *busy = 1; 07414 } 07415 /* If do not disturb, definitely not */ 07416 if (p->dnd) 07417 return 0; 07418 /* If guard time, definitely not */ 07419 if (p->guardtime && (time(NULL) < p->guardtime)) 07420 return 0; 07421 07422 /* If no owner definitely available */ 07423 if (!p->owner) { 07424 #ifdef ZAPATA_PRI 07425 /* Trust PRI */ 07426 if (p->pri) { 07427 if (p->resetting || p->call) 07428 return 0; 07429 else 07430 return 1; 07431 } 07432 #endif 07433 #ifdef ZAPATA_R2 07434 /* Trust R2 as well */ 07435 if (p->r2) { 07436 if (p->hasr2call || p->r2blocked) 07437 return 0; 07438 else 07439 return 1; 07440 } 07441 #endif 07442 if (!p->radio) 07443 { 07444 if (!p->sig || (p->sig == SIG_FXSLS)) 07445 return 1; 07446 /* Check hook state */ 07447 if (p->subs[SUB_REAL].zfd > -1) 07448 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07449 else { 07450 /* Assume not off hook on CVRS */ 07451 res = 0; 07452 par.rxisoffhook = 0; 07453 } 07454 if (res) { 07455 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07456 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07457 /* When "onhook" that means no battery on the line, and thus 07458 it is out of service..., if it's on a TDM card... If it's a channel 07459 bank, there is no telling... */ 07460 if (par.rxbits > -1) 07461 return 1; 07462 if (par.rxisoffhook) 07463 return 1; 07464 else 07465 #ifdef ZAP_CHECK_HOOKSTATE 07466 return 0; 07467 #else 07468 return 1; 07469 #endif 07470 } else if (par.rxisoffhook) { 07471 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07472 /* Not available when the other end is off hook */ 07473 return 0; 07474 } 07475 } 07476 return 1; 07477 } 07478 07479 /* If it's not an FXO, forget about call wait */ 07480 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07481 return 0; 07482 07483 if (!p->callwaiting) { 07484 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07485 return 0; 07486 } 07487 07488 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07489 /* If there is already a call waiting call, then we can't take a second one */ 07490 return 0; 07491 } 07492 07493 if ((p->owner->_state != AST_STATE_UP) && 07494 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07495 /* If the current call is not up, then don't allow the call */ 07496 return 0; 07497 } 07498 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07499 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07500 return 0; 07501 } 07502 /* We're cool */ 07503 return 1; 07504 }
static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1557 of file chan_zap.c.
References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, and zt_pvt::txgain.
Referenced by ss_thread().
01558 { 01559 int res; 01560 01561 /* Bump receive gain by 5.0db */ 01562 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01563 if (res) { 01564 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01565 return -1; 01566 } 01567 01568 return 0; 01569 }
Definition at line 7506 of file chan_zap.c.
References ast_log(), ast_mutex_init(), zt_pvt::destroy, destroy_zt_pvt(), iflist, LOG_ERROR, malloc, zt_pvt::next, SUB_REAL, and zt_open().
Referenced by zt_request().
07507 { 07508 struct zt_pvt *p; 07509 ZT_BUFFERINFO bi; 07510 int res; 07511 p = malloc(sizeof(struct zt_pvt)); 07512 if (p) { 07513 memcpy(p, src, sizeof(struct zt_pvt)); 07514 ast_mutex_init(&p->lock); 07515 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07516 /* Allocate a zapata structure */ 07517 if (p->subs[SUB_REAL].zfd < 0) { 07518 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07519 destroy_zt_pvt(&p); 07520 return NULL; 07521 } 07522 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07523 if (!res) { 07524 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07525 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07526 bi.numbufs = numbufs; 07527 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07528 if (res < 0) { 07529 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 07530 } 07531 } else 07532 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 07533 } 07534 p->destroy = 1; 07535 p->next = iflist; 07536 iflist = p; 07537 return p; 07538 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3482 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, and VERBOSE_PREFIX_3.
Referenced by zt_handle_event().
03483 { 03484 ZT_CONFINFO ci; 03485 /* Fine if we already have a master, etc */ 03486 if (p->master || (p->confno > -1)) 03487 return 0; 03488 memset(&ci, 0, sizeof(ci)); 03489 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03490 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03491 return 0; 03492 } 03493 /* If we have no master and don't have a confno, then 03494 if we're in a conference, it's probably a MeetMe room or 03495 some such, so don't let us 3-way out! */ 03496 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03497 if (option_verbose > 2) 03498 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03499 return 1; 03500 } 03501 return 0; 03502 }
static int conf_add | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 1200 of file chan_zap.c.
References ast_log(), zt_pvt::confno, zt_subchannel::curconf, LOG_DEBUG, LOG_WARNING, and zt_subchannel::zfd.
Referenced by update_conf().
01201 { 01202 /* If the conference already exists, and we're already in it 01203 don't bother doing anything */ 01204 ZT_CONFINFO zi; 01205 01206 memset(&zi, 0, sizeof(zi)); 01207 zi.chan = 0; 01208 01209 if (slavechannel > 0) { 01210 /* If we have only one slave, do a digital mon */ 01211 zi.confmode = ZT_CONF_DIGITALMON; 01212 zi.confno = slavechannel; 01213 } else { 01214 if (!index) { 01215 /* Real-side and pseudo-side both participate in conference */ 01216 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01217 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01218 } else 01219 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01220 zi.confno = p->confno; 01221 } 01222 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01223 return 0; 01224 if (c->zfd < 0) 01225 return 0; 01226 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01227 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01228 return -1; 01229 } 01230 if (slavechannel < 1) { 01231 p->confno = zi.confno; 01232 } 01233 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01234 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01235 return 0; 01236 }
static int conf_del | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 1249 of file chan_zap.c.
References ast_log(), zt_subchannel::curconf, isourconf(), LOG_DEBUG, LOG_WARNING, and zt_subchannel::zfd.
Referenced by update_conf(), and zt_unlink().
01250 { 01251 ZT_CONFINFO zi; 01252 if (/* Can't delete if there's no zfd */ 01253 (c->zfd < 0) || 01254 /* Don't delete from the conference if it's not our conference */ 01255 !isourconf(p, c) 01256 /* Don't delete if we don't think it's conferenced at all (implied) */ 01257 ) return 0; 01258 memset(&zi, 0, sizeof(zi)); 01259 zi.chan = 0; 01260 zi.confno = 0; 01261 zi.confmode = 0; 01262 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01263 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01264 return -1; 01265 } 01266 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01267 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01268 return 0; 01269 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 11249 of file chan_zap.c.
11250 { 11251 return (char *) desc; 11252 }
Definition at line 2170 of file chan_zap.c.
References destroy_zt_pvt(), iflist, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::prev, SUB_REAL, zt_pvt::subs, and zt_close().
Referenced by zap_destroy_channel(), zap_restart(), and zt_hangup().
02171 { 02172 int owned = 0; 02173 int i = 0; 02174 02175 if (!now) { 02176 if (cur->owner) { 02177 owned = 1; 02178 } 02179 02180 for (i = 0; i < 3; i++) { 02181 if (cur->subs[i].owner) { 02182 owned = 1; 02183 } 02184 } 02185 if (!owned) { 02186 if (prev) { 02187 prev->next = cur->next; 02188 if (prev->next) 02189 prev->next->prev = prev; 02190 else 02191 ifend = prev; 02192 } else { 02193 iflist = cur->next; 02194 if (iflist) 02195 iflist->prev = NULL; 02196 else 02197 ifend = NULL; 02198 } 02199 if (cur->subs[SUB_REAL].zfd > -1) { 02200 zt_close(cur->subs[SUB_REAL].zfd); 02201 } 02202 destroy_zt_pvt(&cur); 02203 } 02204 } else { 02205 if (prev) { 02206 prev->next = cur->next; 02207 if (prev->next) 02208 prev->next->prev = prev; 02209 else 02210 ifend = prev; 02211 } else { 02212 iflist = cur->next; 02213 if (iflist) 02214 iflist->prev = NULL; 02215 else 02216 ifend = NULL; 02217 } 02218 if (cur->subs[SUB_REAL].zfd > -1) { 02219 zt_close(cur->subs[SUB_REAL].zfd); 02220 } 02221 destroy_zt_pvt(&cur); 02222 } 02223 return 0; 02224 }
static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2157 of file chan_zap.c.
References ast_mutex_destroy(), free, zt_pvt::lock, zt_pvt::next, and zt_pvt::prev.
Referenced by __unload_module(), chandup(), destroy_channel(), and mkintf().
02158 { 02159 struct zt_pvt *p = *pvt; 02160 /* Remove channel from the list */ 02161 if(p->prev) 02162 p->prev->next = p->next; 02163 if(p->next) 02164 p->next->prev = p->prev; 02165 ast_mutex_destroy(&p->lock); 02166 free(p); 02167 *pvt = NULL; 02168 }
static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 2962 of file chan_zap.c.
References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, and zt_pvt::subs.
Referenced by zt_bridge().
02963 { 02964 #ifdef ZT_TONEDETECT 02965 int val; 02966 #endif 02967 02968 p->ignoredtmf = 1; 02969 02970 #ifdef ZT_TONEDETECT 02971 val = 0; 02972 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 02973 #endif 02974 if (!p->hardwaredtmf && p->dsp) { 02975 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 02976 ast_dsp_set_features(p->dsp, p->dsp_features); 02977 } 02978 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6555 of file chan_zap.c.
References ast_app_has_voicemail(), ast_fdisset(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), zt_pvt::channel, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, event2str(), pollfd::events, pollfd::fd, free, handle_init_event(), iflist, last, LOG_DEBUG, LOG_ERROR, malloc, MAX_CALLERID_SIZE, zt_pvt::msgstate, msglist::next, zt_pvt::next, option_debug, zt_pvt::owner, poll(), POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, vmwi_generate(), zt_subchannel::zfd, and zt_get_event().
06556 { 06557 int count, res, res2, spoint, pollres=0; 06558 struct zt_pvt *i; 06559 struct zt_pvt *last = NULL; 06560 time_t thispass = 0, lastpass = 0; 06561 int found; 06562 char buf[1024]; 06563 struct pollfd *pfds=NULL; 06564 int lastalloc = -1; 06565 /* This thread monitors all the frame relay interfaces which are not yet in use 06566 (and thus do not have a separate thread) indefinitely */ 06567 /* From here on out, we die whenever asked */ 06568 #if 0 06569 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 06570 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 06571 return NULL; 06572 } 06573 ast_log(LOG_DEBUG, "Monitor starting...\n"); 06574 #endif 06575 for(;;) { 06576 /* Lock the interface list */ 06577 if (ast_mutex_lock(&iflock)) { 06578 ast_log(LOG_ERROR, "Unable to grab interface lock\n"); 06579 return NULL; 06580 } 06581 if (!pfds || (lastalloc != ifcount)) { 06582 if (pfds) 06583 free(pfds); 06584 if (ifcount) { 06585 pfds = malloc(ifcount * sizeof(struct pollfd)); 06586 if (!pfds) { 06587 ast_log(LOG_WARNING, "Critical memory error. Zap dies.\n"); 06588 ast_mutex_unlock(&iflock); 06589 return NULL; 06590 } 06591 } 06592 lastalloc = ifcount; 06593 } 06594 /* Build the stuff we're going to poll on, that is the socket of every 06595 zt_pvt that does not have an associated owner channel */ 06596 count = 0; 06597 i = iflist; 06598 while(i) { 06599 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 06600 if (!i->owner && !i->subs[SUB_REAL].owner) { 06601 /* This needs to be watched, as it lacks an owner */ 06602 pfds[count].fd = i->subs[SUB_REAL].zfd; 06603 pfds[count].events = POLLPRI; 06604 pfds[count].revents = 0; 06605 /* Message waiting or r2 channels also get watched for reading */ 06606 #ifdef ZAPATA_R2 06607 if (i->cidspill || i->r2) 06608 #else 06609 if (i->cidspill) 06610 #endif 06611 pfds[count].events |= POLLIN; 06612 count++; 06613 } 06614 } 06615 i = i->next; 06616 } 06617 /* Okay, now that we know what to do, release the interface lock */ 06618 ast_mutex_unlock(&iflock); 06619 06620 pthread_testcancel(); 06621 /* Wait at least a second for something to happen */ 06622 res = poll(pfds, count, 1000); 06623 pthread_testcancel(); 06624 /* Okay, poll has finished. Let's see what happened. */ 06625 if (res < 0) { 06626 if ((errno != EAGAIN) && (errno != EINTR)) 06627 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 06628 continue; 06629 } 06630 /* Alright, lock the interface list again, and let's look and see what has 06631 happened */ 06632 if (ast_mutex_lock(&iflock)) { 06633 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 06634 continue; 06635 } 06636 found = 0; 06637 spoint = 0; 06638 lastpass = thispass; 06639 thispass = time(NULL); 06640 i = iflist; 06641 while(i) { 06642 if (thispass != lastpass) { 06643 if (!found && ((i == last) || ((i == iflist) && !last))) { 06644 last = i; 06645 if (last) { 06646 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 06647 (last->sig & __ZT_SIG_FXO)) { 06648 res = ast_app_has_voicemail(last->mailbox, NULL); 06649 if (last->msgstate != res) { 06650 int x; 06651 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 06652 x = ZT_FLUSH_BOTH; 06653 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 06654 if (res2) 06655 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 06656 last->cidspill = malloc(MAX_CALLERID_SIZE); 06657 if (last->cidspill) { 06658 /* Turn on on hook transfer for 4 seconds */ 06659 x = 4000; 06660 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 06661 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 06662 last->cidpos = 0; 06663 last->msgstate = res; 06664 last->onhooktime = thispass; 06665 } 06666 found ++; 06667 } 06668 } 06669 last = last->next; 06670 } 06671 } 06672 } 06673 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 06674 if (i->radio && !i->owner) 06675 { 06676 res = zt_get_event(i->subs[SUB_REAL].zfd); 06677 if (res) 06678 { 06679 if (option_debug) 06680 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 06681 /* Don't hold iflock while handling init events */ 06682 ast_mutex_unlock(&iflock); 06683 handle_init_event(i, res); 06684 ast_mutex_lock(&iflock); 06685 } 06686 i = i->next; 06687 continue; 06688 } 06689 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 06690 if (pollres & POLLIN) { 06691 if (i->owner || i->subs[SUB_REAL].owner) { 06692 #ifdef ZAPATA_PRI 06693 if (!i->pri) 06694 #endif 06695 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 06696 i = i->next; 06697 continue; 06698 } 06699 #ifdef ZAPATA_R2 06700 if (i->r2) { 06701 /* If it's R2 signalled, we always have to check for events */ 06702 mfcr2_event_t *e; 06703 e = mfcr2_check_event(i->r2); 06704 if (e) 06705 handle_init_r2_event(i, e); 06706 else { 06707 e = mfcr2_schedule_run(i->r2); 06708 if (e) 06709 handle_init_r2_event(i, e); 06710 } 06711 i = i->next; 06712 continue; 06713 } 06714 #endif 06715 if (!i->cidspill) { 06716 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 06717 i = i->next; 06718 continue; 06719 } 06720 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 06721 if (res > 0) { 06722 /* We read some number of bytes. Write an equal amount of data */ 06723 if (res > i->cidlen - i->cidpos) 06724 res = i->cidlen - i->cidpos; 06725 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 06726 if (res2 > 0) { 06727 i->cidpos += res2; 06728 if (i->cidpos >= i->cidlen) { 06729 free(i->cidspill); 06730 i->cidspill = 0; 06731 i->cidpos = 0; 06732 i->cidlen = 0; 06733 } 06734 } else { 06735 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 06736 i->msgstate = -1; 06737 } 06738 } else { 06739 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 06740 } 06741 if (option_debug) 06742 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06743 /* Don't hold iflock while handling init events -- race with chlock */ 06744 ast_mutex_unlock(&iflock); 06745 handle_init_event(i, res); 06746 ast_mutex_lock(&iflock); 06747 } 06748 #ifdef ZAPATA_R2 06749 if ((pollres & POLLPRI) || (i->r2 && !i->sigchecked)) 06750 #else 06751 if (pollres & POLLPRI) 06752 #endif 06753 { 06754 if (i->owner || i->subs[SUB_REAL].owner) { 06755 #ifdef ZAPATA_PRI 06756 if (!i->pri) 06757 #endif 06758 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 06759 i = i->next; 06760 continue; 06761 } 06762 res = zt_get_event(i->subs[SUB_REAL].zfd); 06763 if (option_debug) 06764 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06765 /* Don't hold iflock while handling init events */ 06766 ast_mutex_unlock(&iflock); 06767 handle_init_event(i, res); 06768 ast_mutex_lock(&iflock); 06769 } 06770 } 06771 i=i->next; 06772 } 06773 ast_mutex_unlock(&iflock); 06774 } 06775 /* Never reached */ 06776 return NULL; 06777 06778 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 2980 of file chan_zap.c.
References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, and zt_pvt::subs.
Referenced by zt_bridge().
02981 { 02982 #ifdef ZT_TONEDETECT 02983 int val; 02984 #endif 02985 02986 if (p->channel == CHAN_PSEUDO) 02987 return; 02988 02989 p->ignoredtmf = 0; 02990 02991 #ifdef ZT_TONEDETECT 02992 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 02993 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 02994 #endif 02995 if (!p->hardwaredtmf && p->dsp) { 02996 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 02997 ast_dsp_set_features(p->dsp, p->dsp_features); 02998 } 02999 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1105 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
01106 { 01107 static char buf[256]; 01108 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01109 return events[event]; 01110 sprintf(buf, "Event %d", event); /* safe */ 01111 return buf; 01112 }
static void fill_rxgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1482 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01483 { 01484 int j; 01485 int k; 01486 float linear_gain = pow(10.0, gain / 20.0); 01487 01488 switch (law) { 01489 case ZT_LAW_ALAW: 01490 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01491 if (gain) { 01492 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01493 if (k > 32767) k = 32767; 01494 if (k < -32767) k = -32767; 01495 g->rxgain[j] = AST_LIN2A(k); 01496 } else { 01497 g->rxgain[j] = j; 01498 } 01499 } 01500 break; 01501 case ZT_LAW_MULAW: 01502 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01503 if (gain) { 01504 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01505 if (k > 32767) k = 32767; 01506 if (k < -32767) k = -32767; 01507 g->rxgain[j] = AST_LIN2MU(k); 01508 } else { 01509 g->rxgain[j] = j; 01510 } 01511 } 01512 break; 01513 } 01514 }
static void fill_txgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1448 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01449 { 01450 int j; 01451 int k; 01452 float linear_gain = pow(10.0, gain / 20.0); 01453 01454 switch (law) { 01455 case ZT_LAW_ALAW: 01456 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01457 if (gain) { 01458 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01459 if (k > 32767) k = 32767; 01460 if (k < -32767) k = -32767; 01461 g->txgain[j] = AST_LIN2A(k); 01462 } else { 01463 g->txgain[j] = j; 01464 } 01465 } 01466 break; 01467 case ZT_LAW_MULAW: 01468 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01469 if (gain) { 01470 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01471 if (k > 32767) k = 32767; 01472 if (k < -32767) k = -32767; 01473 g->txgain[j] = AST_LIN2MU(k); 01474 } else { 01475 g->txgain[j] = j; 01476 } 01477 } 01478 break; 01479 } 01480 }
static struct zt_pvt* find_channel | ( | int | channel | ) | [static] |
Definition at line 10039 of file chan_zap.c.
References zt_pvt::channel, iflist, and zt_pvt::next.
10040 { 10041 struct zt_pvt *p = iflist; 10042 while(p) { 10043 if (p->channel == channel) { 10044 break; 10045 } 10046 p = p->next; 10047 } 10048 return p; 10049 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3504 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::span, SUB_REAL, and zt_pvt::subs.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03505 { 03506 int res; 03507 ZT_SPANINFO zi; 03508 memset(&zi, 0, sizeof(zi)); 03509 zi.spanno = p->span; 03510 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03511 if (res < 0) { 03512 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03513 return 0; 03514 } 03515 return zi.alarms; 03516 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6361 of file chan_zap.c.
References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, EVENT_FLAG_SYSTEM, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
Referenced by do_monitor().
06362 { 06363 int res; 06364 pthread_t threadid; 06365 pthread_attr_t attr; 06366 struct ast_channel *chan; 06367 pthread_attr_init(&attr); 06368 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06369 /* Handle an event on a given channel for the monitor thread. */ 06370 switch(event) { 06371 case ZT_EVENT_NONE: 06372 case ZT_EVENT_BITSCHANGED: 06373 if (i->radio) break; 06374 #ifdef ZAPATA_R2 06375 if (i->r2) { 06376 mfcr2_event_t *e; 06377 e = r2_get_event_bits(i); 06378 i->sigchecked = 1; 06379 if (e) 06380 handle_init_r2_event(i, e); 06381 } 06382 #endif 06383 break; 06384 case ZT_EVENT_WINKFLASH: 06385 case ZT_EVENT_RINGOFFHOOK: 06386 if (i->inalarm) break; 06387 if (i->radio) break; 06388 /* Got a ring/answer. What kind of channel are we? */ 06389 switch(i->sig) { 06390 case SIG_FXOLS: 06391 case SIG_FXOGS: 06392 case SIG_FXOKS: 06393 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06394 if (i->cidspill) { 06395 /* Cancel VMWI spill */ 06396 free(i->cidspill); 06397 i->cidspill = NULL; 06398 } 06399 if (i->immediate) { 06400 zt_enable_ec(i); 06401 /* The channel is immediately up. Start right away */ 06402 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06403 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06404 if (!chan) { 06405 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06406 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06407 if (res < 0) 06408 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06409 } 06410 } else { 06411 /* Check for callerid, digits, etc */ 06412 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06413 if (chan) { 06414 if (has_voicemail(i)) 06415 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06416 else 06417 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06418 if (res < 0) 06419 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel); 06420 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06421 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06422 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06423 if (res < 0) 06424 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06425 ast_hangup(chan); 06426 } 06427 } else 06428 ast_log(LOG_WARNING, "Unable to create channel\n"); 06429 } 06430 break; 06431 case SIG_FXSLS: 06432 case SIG_FXSGS: 06433 case SIG_FXSKS: 06434 i->ringt = i->ringt_base; 06435 /* Fall through */ 06436 case SIG_EMWINK: 06437 case SIG_FEATD: 06438 case SIG_FEATDMF: 06439 case SIG_E911: 06440 case SIG_FEATB: 06441 case SIG_EM: 06442 case SIG_EM_E1: 06443 case SIG_SFWINK: 06444 case SIG_SF_FEATD: 06445 case SIG_SF_FEATDMF: 06446 case SIG_SF_FEATB: 06447 case SIG_SF: 06448 /* Check for callerid, digits, etc */ 06449 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06450 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06451 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06452 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06453 if (res < 0) 06454 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06455 ast_hangup(chan); 06456 } else if (!chan) { 06457 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06458 } 06459 break; 06460 default: 06461 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06462 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06463 if (res < 0) 06464 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06465 return -1; 06466 } 06467 break; 06468 case ZT_EVENT_NOALARM: 06469 i->inalarm = 0; 06470 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06471 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06472 "Channel: %d\r\n", i->channel); 06473 break; 06474 case ZT_EVENT_ALARM: 06475 i->inalarm = 1; 06476 res = get_alarms(i); 06477 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res)); 06478 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06479 "Alarm: %s\r\n" 06480 "Channel: %d\r\n", 06481 alarm2str(res), i->channel); 06482 /* fall thru intentionally */ 06483 case ZT_EVENT_ONHOOK: 06484 if (i->radio) break; 06485 /* Back on hook. Hang up. */ 06486 switch(i->sig) { 06487 case SIG_FXOLS: 06488 case SIG_FXOGS: 06489 case SIG_FEATD: 06490 case SIG_FEATDMF: 06491 case SIG_E911: 06492 case SIG_FEATB: 06493 case SIG_EM: 06494 case SIG_EM_E1: 06495 case SIG_EMWINK: 06496 case SIG_SF_FEATD: 06497 case SIG_SF_FEATDMF: 06498 case SIG_SF_FEATB: 06499 case SIG_SF: 06500 case SIG_SFWINK: 06501 case SIG_FXSLS: 06502 case SIG_FXSGS: 06503 case SIG_FXSKS: 06504 case SIG_GR303FXSKS: 06505 zt_disable_ec(i); 06506 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06507 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06508 break; 06509 case SIG_GR303FXOKS: 06510 case SIG_FXOKS: 06511 zt_disable_ec(i); 06512 /* Diddle the battery for the zhone */ 06513 #ifdef ZHONE_HACK 06514 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06515 usleep(1); 06516 #endif 06517 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06518 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06519 break; 06520 case SIG_PRI: 06521 zt_disable_ec(i); 06522 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06523 break; 06524 default: 06525 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06526 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06527 return -1; 06528 } 06529 break; 06530 case ZT_EVENT_POLARITY: 06531 switch(i->sig) { 06532 case SIG_FXSLS: 06533 case SIG_FXSKS: 06534 case SIG_FXSGS: 06535 if (i->cid_start == CID_START_POLARITY) { 06536 i->polarity = POLARITY_REV; 06537 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06538 "CID detection on channel %d\n", 06539 i->channel); 06540 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06541 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06542 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06543 } 06544 } 06545 break; 06546 default: 06547 ast_log(LOG_WARNING, "handle_init_event detected " 06548 "polarity reversal on non-FXO (SIG_FXS) " 06549 "interface %d\n", i->channel); 06550 } 06551 } 06552 return 0; 06553 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9897 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
09898 { 09899 int i, j; 09900 for (i=0;i<num_cadence;i++) { 09901 char output[1024]; 09902 char tmp[16], tmp2[64]; 09903 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 09904 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 09905 09906 for (j=0;j<16;j++) { 09907 if (cadences[i].ringcadence[j] == 0) 09908 break; 09909 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 09910 if (cidrings[i] * 2 - 1 == j) 09911 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 09912 else 09913 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 09914 if (j != 0) 09915 strncat(output, ",", sizeof(output) - strlen(output) - 1); 09916 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 09917 } 09918 ast_cli(fd,"%s\n",output); 09919 } 09920 return 0; 09921 }
static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1677 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01678 { 01679 01680 return ast_app_has_voicemail(p->mailbox, NULL); 01681 }
static int isourconf | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c | |||
) | [static] |
Definition at line 1238 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01239 { 01240 /* If they're listening to our channel, they're ours */ 01241 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01242 return 1; 01243 /* If they're a talker on our (allocated) conference, they're ours */ 01244 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01245 return 1; 01246 return 0; 01247 }
Definition at line 1271 of file chan_zap.c.
References zt_subchannel::inthreeway, MAX_SLAVES, zt_pvt::slaves, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by update_conf().
01272 { 01273 int x; 01274 int useslavenative; 01275 struct zt_pvt *slave = NULL; 01276 /* Start out optimistic */ 01277 useslavenative = 1; 01278 /* Update conference state in a stateless fashion */ 01279 for (x=0;x<3;x++) { 01280 /* Any three-way calling makes slave native mode *definitely* out 01281 of the question */ 01282 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01283 useslavenative = 0; 01284 } 01285 /* If we don't have any 3-way calls, check to see if we have 01286 precisely one slave */ 01287 if (useslavenative) { 01288 for (x=0;x<MAX_SLAVES;x++) { 01289 if (p->slaves[x]) { 01290 if (slave) { 01291 /* Whoops already have a slave! No 01292 slave native and stop right away */ 01293 slave = NULL; 01294 useslavenative = 0; 01295 break; 01296 } else { 01297 /* We have one slave so far */ 01298 slave = p->slaves[x]; 01299 } 01300 } 01301 } 01302 } 01303 /* If no slave, slave native definitely out */ 01304 if (!slave) 01305 useslavenative = 0; 01306 else if (slave->law != p->law) { 01307 useslavenative = 0; 01308 slave = NULL; 01309 } 01310 if (out) 01311 *out = slave; 01312 return useslavenative; 01313 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 11254 of file chan_zap.c.
References ASTERISK_GPL_KEY.
11255 { 11256 return ASTERISK_GPL_KEY; 11257 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 11085 of file chan_zap.c.
References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zapshowchannels(), ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register, ast_mutex_init(), AST_PTHREADT_NULL, lock, LOG_ERROR, round_robin, setup_zap(), zap_cli, and zap_tech.
11086 { 11087 int res; 11088 11089 #ifdef ZAPATA_PRI 11090 int y,i; 11091 memset(pris, 0, sizeof(pris)); 11092 for (y=0;y<NUM_SPANS;y++) { 11093 ast_mutex_init(&pris[y].lock); 11094 pris[y].offset = -1; 11095 pris[y].master = AST_PTHREADT_NULL; 11096 for (i=0;i<NUM_DCHANS;i++) 11097 pris[y].fds[i] = -1; 11098 } 11099 pri_set_error(zt_pri_error); 11100 pri_set_message(zt_pri_message); 11101 #endif 11102 res = setup_zap(0); 11103 /* Make sure we can register our Zap channel type */ 11104 if(res) { 11105 return -1; 11106 } 11107 if (ast_channel_register(&zap_tech)) { 11108 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 11109 __unload_module(); 11110 return -1; 11111 } 11112 #ifdef ZAPATA_PRI 11113 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0])); 11114 #endif 11115 #ifdef ZAPATA_R2 11116 ast_cli_register_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0])); 11117 #endif 11118 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0])); 11119 11120 memset(round_robin, 0, sizeof(round_robin)); 11121 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 11122 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 11123 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 11124 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 11125 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 11126 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 11127 11128 return res; 11129 }
static struct zt_pvt* mkintf | ( | int | channel, | |
int | signalling, | |||
int | radio, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static] |
Definition at line 6932 of file chan_zap.c.
References ast_log(), ast_mutex_init(), ast_strlen_zero(), CHAN_PSEUDO, zt_pvt::channel, destroy_zt_pvt(), iflist, zt_pvt::lock, LOG_ERROR, malloc, MAX_CHANNELS, zt_pvt::next, zt_pvt::prev, sig2str, SIG_FXOKS, SIG_FXSKS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SUB_REAL, channel::subs, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().
Referenced by setup_zap().
06933 { 06934 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 06935 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 06936 char fn[80]; 06937 #if 1 06938 struct zt_bufferinfo bi; 06939 #endif 06940 struct zt_spaninfo si; 06941 int res; 06942 int span=0; 06943 int here = 0; 06944 int x; 06945 struct zt_pvt **wlist; 06946 struct zt_pvt **wend; 06947 ZT_PARAMS p; 06948 06949 wlist = &iflist; 06950 wend = &ifend; 06951 06952 #ifdef ZAPATA_PRI 06953 if (pri) { 06954 wlist = &pri->crvs; 06955 wend = &pri->crvend; 06956 } 06957 #endif 06958 06959 tmp2 = *wlist; 06960 prev = NULL; 06961 06962 while (tmp2) { 06963 if (!tmp2->destroy) { 06964 if (tmp2->channel == channel) { 06965 tmp = tmp2; 06966 here = 1; 06967 break; 06968 } 06969 if (tmp2->channel > channel) { 06970 break; 06971 } 06972 } 06973 prev = tmp2; 06974 tmp2 = tmp2->next; 06975 } 06976 06977 if (!here && !reloading) { 06978 tmp = (struct zt_pvt*)malloc(sizeof(struct zt_pvt)); 06979 if (!tmp) { 06980 ast_log(LOG_ERROR, "MALLOC FAILED\n"); 06981 destroy_zt_pvt(&tmp); 06982 return NULL; 06983 } 06984 memset(tmp, 0, sizeof(struct zt_pvt)); 06985 ast_mutex_init(&tmp->lock); 06986 ifcount++; 06987 for (x=0;x<3;x++) 06988 tmp->subs[x].zfd = -1; 06989 tmp->channel = channel; 06990 } 06991 06992 if (tmp) { 06993 if (!here) { 06994 if ((channel != CHAN_PSEUDO) && !pri) { 06995 snprintf(fn, sizeof(fn), "%d", channel); 06996 /* Open non-blocking */ 06997 if (!here) 06998 tmp->subs[SUB_REAL].zfd = zt_open(fn); 06999 /* Allocate a zapata structure */ 07000 if (tmp->subs[SUB_REAL].zfd < 0) { 07001 ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel); 07002 destroy_zt_pvt(&tmp); 07003 return NULL; 07004 } 07005 memset(&p, 0, sizeof(p)); 07006 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07007 if (res < 0) { 07008 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07009 destroy_zt_pvt(&tmp); 07010 return NULL; 07011 } 07012 if (p.sigtype != (signalling & 0x3ffff)) { 07013 ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(signalling), sig2str(p.sigtype)); 07014 destroy_zt_pvt(&tmp); 07015 return tmp; 07016 } 07017 tmp->law = p.curlaw; 07018 tmp->span = p.spanno; 07019 span = p.spanno - 1; 07020 } else { 07021 if (channel == CHAN_PSEUDO) 07022 signalling = 0; 07023 else if ((signalling != SIG_FXOKS) && (signalling != SIG_FXSKS)) { 07024 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07025 return NULL; 07026 } 07027 } 07028 #ifdef ZAPATA_PRI 07029 if ((signalling == SIG_PRI) || (signalling == SIG_GR303FXOKS) || (signalling == SIG_GR303FXSKS)) { 07030 int offset; 07031 int myswitchtype; 07032 int matchesdchan; 07033 int x,y; 07034 offset = 0; 07035 if ((signalling == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07036 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07037 destroy_zt_pvt(&tmp); 07038 return NULL; 07039 } 07040 if (span >= NUM_SPANS) { 07041 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07042 destroy_zt_pvt(&tmp); 07043 return NULL; 07044 } else { 07045 si.spanno = 0; 07046 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07047 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07048 destroy_zt_pvt(&tmp); 07049 return NULL; 07050 } 07051 /* Store the logical span first based upon the real span */ 07052 tmp->logicalspan = pris[span].prilogicalspan; 07053 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07054 if (span < 0) { 07055 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07056 destroy_zt_pvt(&tmp); 07057 return NULL; 07058 } 07059 if (signalling == SIG_PRI) 07060 myswitchtype = switchtype; 07061 else 07062 myswitchtype = PRI_SWITCH_GR303_TMC; 07063 /* Make sure this isn't a d-channel */ 07064 matchesdchan=0; 07065 for (x=0;x<NUM_SPANS;x++) { 07066 for (y=0;y<NUM_DCHANS;y++) { 07067 if (pris[x].dchannels[y] == tmp->channel) { 07068 matchesdchan = 1; 07069 break; 07070 } 07071 } 07072 } 07073 offset = p.chanpos; 07074 if (!matchesdchan) { 07075 if (pris[span].nodetype && (pris[span].nodetype != pritype)) { 07076 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07077 destroy_zt_pvt(&tmp); 07078 return NULL; 07079 } 07080 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07081 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07082 destroy_zt_pvt(&tmp); 07083 return NULL; 07084 } 07085 if ((pris[span].dialplan) && (pris[span].dialplan != dialplan)) { 07086 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07087 destroy_zt_pvt(&tmp); 07088 return NULL; 07089 } 07090 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, idledial)) { 07091 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, idledial); 07092 destroy_zt_pvt(&tmp); 07093 return NULL; 07094 } 07095 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, idleext)) { 07096 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, idleext); 07097 destroy_zt_pvt(&tmp); 07098 return NULL; 07099 } 07100 if (pris[span].minunused && (pris[span].minunused != minunused)) { 07101 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, minunused); 07102 destroy_zt_pvt(&tmp); 07103 return NULL; 07104 } 07105 if (pris[span].minidle && (pris[span].minidle != minidle)) { 07106 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, minidle); 07107 destroy_zt_pvt(&tmp); 07108 return NULL; 07109 } 07110 if (pris[span].numchans >= MAX_CHANNELS) { 07111 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07112 pris[span].trunkgroup); 07113 destroy_zt_pvt(&tmp); 07114 return NULL; 07115 } 07116 pris[span].nodetype = pritype; 07117 pris[span].switchtype = myswitchtype; 07118 pris[span].nsf = nsf; 07119 pris[span].dialplan = dialplan; 07120 pris[span].localdialplan = localdialplan; 07121 pris[span].pvts[pris[span].numchans++] = tmp; 07122 pris[span].minunused = minunused; 07123 pris[span].minidle = minidle; 07124 pris[span].overlapdial = overlapdial; 07125 pris[span].facilityenable = facilityenable; 07126 ast_copy_string(pris[span].idledial, idledial, sizeof(pris[span].idledial)); 07127 ast_copy_string(pris[span].idleext, idleext, sizeof(pris[span].idleext)); 07128 ast_copy_string(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix)); 07129 ast_copy_string(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix)); 07130 ast_copy_string(pris[span].localprefix, localprefix, sizeof(pris[span].localprefix)); 07131 ast_copy_string(pris[span].privateprefix, privateprefix, sizeof(pris[span].privateprefix)); 07132 ast_copy_string(pris[span].unknownprefix, unknownprefix, sizeof(pris[span].unknownprefix)); 07133 pris[span].resetinterval = resetinterval; 07134 07135 tmp->pri = &pris[span]; 07136 tmp->prioffset = offset; 07137 tmp->call = NULL; 07138 } else { 07139 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07140 destroy_zt_pvt(&tmp); 07141 return NULL; 07142 } 07143 } 07144 } else { 07145 tmp->prioffset = 0; 07146 } 07147 #endif 07148 #ifdef ZAPATA_R2 07149 if (signalling == SIG_R2) { 07150 if (r2prot < 0) { 07151 ast_log(LOG_WARNING, "R2 Country not specified for channel %d -- Assuming China\n", tmp->channel); 07152 tmp->r2prot = MFCR2_PROT_CHINA; 07153 } else 07154 tmp->r2prot = r2prot; 07155 tmp->r2 = mfcr2_new(tmp->subs[SUB_REAL].zfd, tmp->r2prot, 1); 07156 if (!tmp->r2) { 07157 ast_log(LOG_WARNING, "Unable to create r2 call :(\n"); 07158 zt_close(tmp->subs[SUB_REAL].zfd); 07159 destroy_zt_pvt(&tmp); 07160 return NULL; 07161 } 07162 } else { 07163 if (tmp->r2) 07164 mfcr2_free(tmp->r2); 07165 tmp->r2 = NULL; 07166 } 07167 #endif 07168 } else { 07169 signalling = tmp->sig; 07170 radio = tmp->radio; 07171 memset(&p, 0, sizeof(p)); 07172 if (tmp->subs[SUB_REAL].zfd > -1) 07173 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07174 } 07175 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07176 if ((signalling == SIG_FXSKS) || (signalling == SIG_FXSLS) || 07177 (signalling == SIG_EM) || (signalling == SIG_EM_E1) || (signalling == SIG_EMWINK) || 07178 (signalling == SIG_FEATD) || (signalling == SIG_FEATDMF) || (signalling == SIG_FEATDMF_TA) || 07179 (signalling == SIG_FEATB) || (signalling == SIG_E911) || 07180 (signalling == SIG_SF) || (signalling == SIG_SFWINK) || 07181 (signalling == SIG_SF_FEATD) || (signalling == SIG_SF_FEATDMF) || 07182 (signalling == SIG_SF_FEATB)) { 07183 p.starttime = 250; 07184 } 07185 if (radio) { 07186 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07187 p.channo = channel; 07188 p.rxwinktime = 1; 07189 p.rxflashtime = 1; 07190 p.starttime = 1; 07191 p.debouncetime = 5; 07192 } 07193 if (!radio) { 07194 p.channo = channel; 07195 /* Override timing settings based on config file */ 07196 if (cur_prewink >= 0) 07197 p.prewinktime = cur_prewink; 07198 if (cur_preflash >= 0) 07199 p.preflashtime = cur_preflash; 07200 if (cur_wink >= 0) 07201 p.winktime = cur_wink; 07202 if (cur_flash >= 0) 07203 p.flashtime = cur_flash; 07204 if (cur_start >= 0) 07205 p.starttime = cur_start; 07206 if (cur_rxwink >= 0) 07207 p.rxwinktime = cur_rxwink; 07208 if (cur_rxflash >= 0) 07209 p.rxflashtime = cur_rxflash; 07210 if (cur_debounce >= 0) 07211 p.debouncetime = cur_debounce; 07212 } 07213 07214 /* dont set parms on a pseudo-channel (or CRV) */ 07215 if (tmp->subs[SUB_REAL].zfd >= 0) 07216 { 07217 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07218 if (res < 0) { 07219 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07220 destroy_zt_pvt(&tmp); 07221 return NULL; 07222 } 07223 } 07224 #if 1 07225 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07226 memset(&bi, 0, sizeof(bi)); 07227 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07228 if (!res) { 07229 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07230 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07231 bi.numbufs = numbufs; 07232 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07233 if (res < 0) { 07234 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07235 } 07236 } else 07237 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07238 } 07239 #endif 07240 tmp->immediate = immediate; 07241 tmp->transfertobusy = transfertobusy; 07242 tmp->sig = signalling; 07243 tmp->radio = radio; 07244 tmp->ringt_base = ringt_base; 07245 tmp->firstradio = 0; 07246 if ((signalling == SIG_FXOKS) || (signalling == SIG_FXOLS) || (signalling == SIG_FXOGS)) 07247 tmp->permcallwaiting = callwaiting; 07248 else 07249 tmp->permcallwaiting = 0; 07250 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07251 tmp->destroy = 0; 07252 tmp->drings = drings; 07253 tmp->usedistinctiveringdetection = usedistinctiveringdetection; 07254 tmp->callwaitingcallerid = callwaitingcallerid; 07255 tmp->threewaycalling = threewaycalling; 07256 tmp->adsi = adsi; 07257 tmp->permhidecallerid = hidecallerid; 07258 tmp->callreturn = callreturn; 07259 tmp->echocancel = echocancel; 07260 tmp->echotraining = echotraining; 07261 tmp->pulse = pulse; 07262 tmp->echocanbridged = echocanbridged; 07263 tmp->busydetect = busydetect; 07264 tmp->busycount = busycount; 07265 tmp->busy_tonelength = busy_tonelength; 07266 tmp->busy_quietlength = busy_quietlength; 07267 tmp->callprogress = callprogress; 07268 tmp->cancallforward = cancallforward; 07269 tmp->dtmfrelax = relaxdtmf; 07270 tmp->callwaiting = tmp->permcallwaiting; 07271 tmp->hidecallerid = tmp->permhidecallerid; 07272 tmp->channel = channel; 07273 tmp->stripmsd = stripmsd; 07274 tmp->use_callerid = use_callerid; 07275 tmp->cid_signalling = cid_signalling; 07276 tmp->cid_start = cid_start; 07277 tmp->zaptrcallerid = zaptrcallerid; 07278 tmp->restrictcid = restrictcid; 07279 tmp->use_callingpres = use_callingpres; 07280 tmp->priindication_oob = priindication_oob; 07281 tmp->priexclusive = cur_priexclusive; 07282 if (tmp->usedistinctiveringdetection) { 07283 if (!tmp->use_callerid) { 07284 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07285 tmp->use_callerid = 1; 07286 } 07287 } 07288 07289 ast_copy_string(tmp->accountcode, accountcode, sizeof(tmp->accountcode)); 07290 tmp->amaflags = amaflags; 07291 if (!here) { 07292 tmp->confno = -1; 07293 tmp->propconfno = -1; 07294 } 07295 tmp->canpark = canpark; 07296 tmp->transfer = transfer; 07297 ast_copy_string(tmp->defcontext,context,sizeof(tmp->defcontext)); 07298 ast_copy_string(tmp->language, language, sizeof(tmp->language)); 07299 ast_copy_string(tmp->musicclass, musicclass, sizeof(tmp->musicclass)); 07300 ast_copy_string(tmp->context, context, sizeof(tmp->context)); 07301 ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num)); 07302 tmp->cid_ton = 0; 07303 ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name)); 07304 ast_copy_string(tmp->mailbox, mailbox, sizeof(tmp->mailbox)); 07305 tmp->msgstate = -1; 07306 tmp->group = cur_group; 07307 tmp->callgroup=cur_callergroup; 07308 tmp->pickupgroup=cur_pickupgroup; 07309 tmp->rxgain = rxgain; 07310 tmp->txgain = txgain; 07311 tmp->tonezone = tonezone; 07312 tmp->onhooktime = time(NULL); 07313 if (tmp->subs[SUB_REAL].zfd > -1) { 07314 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07315 if (tmp->dsp) 07316 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07317 update_conf(tmp); 07318 if (!here) { 07319 if ((signalling != SIG_PRI) && (signalling != SIG_R2)) 07320 /* Hang it up to be sure it's good */ 07321 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07322 } 07323 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07324 #ifdef ZAPATA_PRI 07325 /* the dchannel is down so put the channel in alarm */ 07326 if (tmp->pri && !pri_is_up(tmp->pri)) 07327 tmp->inalarm = 1; 07328 else 07329 tmp->inalarm = 0; 07330 #endif 07331 memset(&si, 0, sizeof(si)); 07332 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07333 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07334 destroy_zt_pvt(&tmp); 07335 return NULL; 07336 } 07337 if (si.alarms) tmp->inalarm = 1; 07338 } 07339 07340 tmp->polarityonanswerdelay = polarityonanswerdelay; 07341 tmp->answeronpolarityswitch = answeronpolarityswitch; 07342 tmp->hanguponpolarityswitch = hanguponpolarityswitch; 07343 tmp->sendcalleridafter = sendcalleridafter; 07344 07345 } 07346 if (tmp && !here) { 07347 /* nothing on the iflist */ 07348 if (!*wlist) { 07349 *wlist = tmp; 07350 tmp->prev = NULL; 07351 tmp->next = NULL; 07352 *wend = tmp; 07353 } else { 07354 /* at least one member on the iflist */ 07355 struct zt_pvt *working = *wlist; 07356 07357 /* check if we maybe have to put it on the begining */ 07358 if (working->channel > tmp->channel) { 07359 tmp->next = *wlist; 07360 tmp->prev = NULL; 07361 (*wlist)->prev = tmp; 07362 *wlist = tmp; 07363 } else { 07364 /* go through all the members and put the member in the right place */ 07365 while (working) { 07366 /* in the middle */ 07367 if (working->next) { 07368 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07369 tmp->next = working->next; 07370 tmp->prev = working; 07371 working->next->prev = tmp; 07372 working->next = tmp; 07373 break; 07374 } 07375 } else { 07376 /* the last */ 07377 if (working->channel < tmp->channel) { 07378 working->next = tmp; 07379 tmp->next = NULL; 07380 tmp->prev = working; 07381 *wend = tmp; 07382 break; 07383 } 07384 } 07385 working = working->next; 07386 } 07387 } 07388 } 07389 } 07390 return tmp; 07391 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5177 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05178 { 05179 char c; 05180 05181 *str = 0; /* start with empty output buffer */ 05182 for (;;) 05183 { 05184 /* Wait for the first digit (up to specified ms). */ 05185 c = ast_waitfordigit(chan, ms); 05186 /* if timeout, hangup or error, return as such */ 05187 if (c < 1) 05188 return c; 05189 *str++ = c; 05190 *str = 0; 05191 if (strchr(term, c)) 05192 return 1; 05193 } 05194 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 4706 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_DEBUG, option_debug, READ_SIZE, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_write().
04707 { 04708 int sent=0; 04709 int size; 04710 int res; 04711 int fd; 04712 fd = p->subs[index].zfd; 04713 while(len) { 04714 size = len; 04715 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 04716 size = (linear ? READ_SIZE * 2 : READ_SIZE); 04717 res = write(fd, buf, size); 04718 if (res != size) { 04719 if (option_debug) 04720 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 04721 return sent; 04722 } 04723 len -= size; 04724 buf += size; 04725 } 04726 return sent; 04727 }
int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 11232 of file chan_zap.c.
References ast_log(), and setup_zap().
11233 { 11234 int res = 0; 11235 11236 res = setup_zap(1); 11237 if (res) { 11238 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 11239 return -1; 11240 } 11241 return 0; 11242 }
static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1315 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::confno, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_hangup().
01316 { 01317 ZT_CONFINFO zi; 01318 memset(&zi, 0, sizeof(zi)); 01319 p->confno = -1; 01320 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01321 if (p->subs[SUB_REAL].zfd > -1) { 01322 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01323 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01324 } 01325 return 0; 01326 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 6780 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), and LOG_ERROR.
06781 { 06782 pthread_attr_t attr; 06783 pthread_attr_init(&attr); 06784 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06785 /* If we're supposed to be stopped -- stay stopped */ 06786 if (monitor_thread == AST_PTHREADT_STOP) 06787 return 0; 06788 if (ast_mutex_lock(&monlock)) { 06789 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 06790 return -1; 06791 } 06792 if (monitor_thread == pthread_self()) { 06793 ast_mutex_unlock(&monlock); 06794 ast_log(LOG_WARNING, "Cannot kill myself\n"); 06795 return -1; 06796 } 06797 if (monitor_thread != AST_PTHREADT_NULL) { 06798 /* Just signal it to be sure it wakes up */ 06799 #if 0 06800 pthread_cancel(monitor_thread); 06801 #endif 06802 pthread_kill(monitor_thread, SIGURG); 06803 #if 0 06804 pthread_join(monitor_thread, NULL); 06805 #endif 06806 } else { 06807 /* Start a new monitor */ 06808 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) { 06809 ast_mutex_unlock(&monlock); 06810 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 06811 return -1; 06812 } 06813 } 06814 ast_mutex_unlock(&monlock); 06815 return 0; 06816 }
static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1641 of file chan_zap.c.
References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, and zt_pvt::subs.
Referenced by send_callerid(), and zt_read().
01642 { 01643 int res; 01644 if (p->saveconf.confmode) { 01645 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01646 p->saveconf.confmode = 0; 01647 if (res) { 01648 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01649 return -1; 01650 } 01651 } 01652 if (option_debug) 01653 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01654 return 0; 01655 }
static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1571 of file chan_zap.c.
References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, and zt_pvt::txgain.
Referenced by zt_hangup().
01572 { 01573 int res; 01574 01575 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01576 if (res) { 01577 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01578 return -1; 01579 } 01580 01581 return 0; 01582 }
static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1613 of file chan_zap.c.
References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, and zt_pvt::subs.
Referenced by zt_callwait().
01614 { 01615 struct zt_confinfo c; 01616 int res; 01617 if (p->saveconf.confmode) { 01618 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01619 return -1; 01620 } 01621 p->saveconf.chan = 0; 01622 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01623 if (res) { 01624 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01625 p->saveconf.confmode = 0; 01626 return -1; 01627 } 01628 c.chan = 0; 01629 c.confno = 0; 01630 c.confmode = ZT_CONF_NORMAL; 01631 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01632 if (res) { 01633 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01634 return -1; 01635 } 01636 if (option_debug) 01637 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01638 return 0; 01639 }
static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1683 of file chan_zap.c.
References ast_log(), zt_pvt::callwaitcas, CIDCW_EXPIRE_SAMPLES, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, and zt_setlinear().
Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().
01684 { 01685 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01686 int res; 01687 /* Take out of linear mode if necessary */ 01688 if (p->subs[SUB_REAL].linear) { 01689 p->subs[SUB_REAL].linear = 0; 01690 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01691 } 01692 while(p->cidpos < p->cidlen) { 01693 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01694 if (res < 0) { 01695 if (errno == EAGAIN) 01696 return 0; 01697 else { 01698 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01699 return -1; 01700 } 01701 } 01702 if (!res) 01703 return 0; 01704 p->cidpos += res; 01705 } 01706 free(p->cidspill); 01707 p->cidspill = NULL; 01708 if (p->callwaitcas) { 01709 /* Wait for CID/CW to expire */ 01710 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01711 } else 01712 restore_conference(p); 01713 return 0; 01714 }
int send_cwcidspill | ( | struct zt_pvt * | p | ) |
Definition at line 1659 of file chan_zap.c.
References ast_callerid_callwaiting_generate(), AST_LAW, ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, malloc, MAX_CALLERID_SIZE, option_verbose, READ_SIZE, send_callerid(), and VERBOSE_PREFIX_3.
Referenced by zt_read().
01660 { 01661 p->callwaitcas = 0; 01662 p->cidcwexpire = 0; 01663 p->cidspill = malloc(MAX_CALLERID_SIZE); 01664 if (p->cidspill) { 01665 memset(p->cidspill, 0x7f, MAX_CALLERID_SIZE); 01666 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01667 /* Make sure we account for the end */ 01668 p->cidlen += READ_SIZE * 4; 01669 p->cidpos = 0; 01670 send_callerid(p); 01671 if (option_verbose > 2) 01672 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01673 } else return -1; 01674 return 0; 01675 }
int set_actual_gain | ( | int | fd, | |
int | chan, | |||
float | rxgain, | |||
float | txgain, | |||
int | law | |||
) |
Definition at line 1552 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), restore_gains(), and zt_call().
01553 { 01554 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01555 }
int set_actual_rxgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) |
Definition at line 1534 of file chan_zap.c.
References ast_log(), fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01535 { 01536 struct zt_gains g; 01537 int res; 01538 01539 memset(&g, 0, sizeof(g)); 01540 g.chan = chan; 01541 res = ioctl(fd, ZT_GETGAINS, &g); 01542 if (res) { 01543 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01544 return res; 01545 } 01546 01547 fill_rxgain(&g, gain, law); 01548 01549 return ioctl(fd, ZT_SETGAINS, &g); 01550 }
int set_actual_txgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) |
Definition at line 1516 of file chan_zap.c.
References ast_log(), fill_txgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01517 { 01518 struct zt_gains g; 01519 int res; 01520 01521 memset(&g, 0, sizeof(g)); 01522 g.chan = chan; 01523 res = ioctl(fd, ZT_GETGAINS, &g); 01524 if (res) { 01525 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01526 return res; 01527 } 01528 01529 fill_txgain(&g, gain, law); 01530 01531 return ioctl(fd, ZT_SETGAINS, &g); 01532 }
static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 10291 of file chan_zap.c.
References ast_callerid_split(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_get_group(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose(), cfg, CHAN_PSEUDO, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_V23, CID_START_POLARITY, CID_START_RING, CID_START_USEHIST, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, ast_variable::lineno, LOG_ERROR, mkintf(), ast_variable::name, ast_variable::next, option_verbose, READ_SIZE, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, strsep(), ast_variable::value, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.
Referenced by load_module(), reload(), and zap_restart().
10292 { 10293 struct ast_config *cfg; 10294 struct ast_variable *v; 10295 struct zt_pvt *tmp; 10296 char *chan; 10297 char *c; 10298 char *ringc; 10299 int start, finish,x; 10300 int y; 10301 int found_pseudo = 0; 10302 int cur_radio = 0; 10303 #ifdef ZAPATA_PRI 10304 int spanno; 10305 int i; 10306 int logicalspan; 10307 int trunkgroup; 10308 int dchannels[NUM_DCHANS]; 10309 struct zt_pri *pri; 10310 #endif 10311 10312 cfg = ast_config_load(config); 10313 10314 /* We *must* have a config file otherwise stop immediately */ 10315 if (!cfg) { 10316 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 10317 return -1; 10318 } 10319 10320 10321 if (ast_mutex_lock(&iflock)) { 10322 /* It's a little silly to lock it, but we mind as well just to be sure */ 10323 ast_log(LOG_ERROR, "Unable to lock interface list???\n"); 10324 return -1; 10325 } 10326 #ifdef ZAPATA_PRI 10327 if (!reload) { 10328 /* Process trunkgroups first */ 10329 v = ast_variable_browse(cfg, "trunkgroups"); 10330 while(v) { 10331 if (!strcasecmp(v->name, "trunkgroup")) { 10332 trunkgroup = atoi(v->value); 10333 if (trunkgroup > 0) { 10334 if ((c = strchr(v->value, ','))) { 10335 i = 0; 10336 memset(dchannels, 0, sizeof(dchannels)); 10337 while(c && (i < NUM_DCHANS)) { 10338 dchannels[i] = atoi(c + 1); 10339 if (dchannels[i] < 0) { 10340 ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of zapata.conf\n", trunkgroup, v->lineno); 10341 } else 10342 i++; 10343 c = strchr(c + 1, ','); 10344 } 10345 if (i) { 10346 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 10347 ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of zapata.conf\n", trunkgroup, dchannels[0], v->lineno); 10348 } else if (option_verbose > 1) 10349 ast_verbose(VERBOSE_PREFIX_2 "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s"); 10350 } else 10351 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 10352 } else 10353 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 10354 } else 10355 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 10356 } else if (!strcasecmp(v->name, "spanmap")) { 10357 spanno = atoi(v->value); 10358 if (spanno > 0) { 10359 if ((c = strchr(v->value, ','))) { 10360 trunkgroup = atoi(c + 1); 10361 if (trunkgroup > 0) { 10362 if ((c = strchr(c + 1, ','))) 10363 logicalspan = atoi(c + 1); 10364 else 10365 logicalspan = 0; 10366 if (logicalspan >= 0) { 10367 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 10368 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 10369 } else if (option_verbose > 1) 10370 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 10371 } else 10372 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 10373 } else 10374 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 10375 } else 10376 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 10377 } else 10378 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 10379 } else { 10380 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 10381 } 10382 v = v->next; 10383 } 10384 } 10385 #endif 10386 v = ast_variable_browse(cfg, "channels"); 10387 while(v) { 10388 /* Create the interface list */ 10389 if (!strcasecmp(v->name, "channel") 10390 #ifdef ZAPATA_PRI 10391 || !strcasecmp(v->name, "crv") 10392 #endif 10393 ) { 10394 if (reload == 0) { 10395 if (cur_signalling < 0) { 10396 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 10397 ast_config_destroy(cfg); 10398 ast_mutex_unlock(&iflock); 10399 return -1; 10400 } 10401 } 10402 c = v->value; 10403 10404 #ifdef ZAPATA_PRI 10405 pri = NULL; 10406 if (!strcasecmp(v->name, "crv")) { 10407 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 10408 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", v->lineno); 10409 ast_config_destroy(cfg); 10410 ast_mutex_unlock(&iflock); 10411 return -1; 10412 } 10413 if (trunkgroup < 1) { 10414 ast_log(LOG_WARNING, "CRV trunk group must be a postive number at line %d\n", v->lineno); 10415 ast_config_destroy(cfg); 10416 ast_mutex_unlock(&iflock); 10417 return -1; 10418 } 10419 c+=y; 10420 for (y=0;y<NUM_SPANS;y++) { 10421 if (pris[y].trunkgroup == trunkgroup) { 10422 pri = pris + y; 10423 break; 10424 } 10425 } 10426 if (!pri) { 10427 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, v->lineno); 10428 ast_config_destroy(cfg); 10429 ast_mutex_unlock(&iflock); 10430 return -1; 10431 } 10432 } 10433 #endif 10434 chan = strsep(&c, ","); 10435 while(chan) { 10436 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 10437 /* Range */ 10438 } else if (sscanf(chan, "%d", &start)) { 10439 /* Just one */ 10440 finish = start; 10441 } else if (!strcasecmp(chan, "pseudo")) { 10442 finish = start = CHAN_PSEUDO; 10443 found_pseudo = 1; 10444 } else { 10445 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", v->value, chan); 10446 ast_config_destroy(cfg); 10447 ast_mutex_unlock(&iflock); 10448 return -1; 10449 } 10450 if (finish < start) { 10451 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 10452 x = finish; 10453 finish = start; 10454 start = x; 10455 } 10456 for (x=start;x<=finish;x++) { 10457 #ifdef ZAPATA_PRI 10458 tmp = mkintf(x, cur_signalling, cur_radio, pri, reload); 10459 #else 10460 tmp = mkintf(x, cur_signalling, cur_radio, NULL, reload); 10461 #endif 10462 10463 if (tmp) { 10464 if (option_verbose > 2) { 10465 #ifdef ZAPATA_PRI 10466 if (pri) 10467 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup,x, sig2str(tmp->sig)); 10468 else 10469 #endif 10470 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 10471 } 10472 } else { 10473 if (reload == 1) 10474 ast_log(LOG_ERROR, "Unable to reconfigure channel '%s'\n", v->value); 10475 else 10476 ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value); 10477 ast_config_destroy(cfg); 10478 ast_mutex_unlock(&iflock); 10479 return -1; 10480 } 10481 } 10482 chan = strsep(&c, ","); 10483 } 10484 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 10485 if (ast_true(v->value)) 10486 usedistinctiveringdetection = 1; 10487 } else if (!strcasecmp(v->name, "dring1context")) { 10488 ast_copy_string(drings.ringContext[0].contextData,v->value,sizeof(drings.ringContext[0].contextData)); 10489 } else if (!strcasecmp(v->name, "dring2context")) { 10490 ast_copy_string(drings.ringContext[1].contextData,v->value,sizeof(drings.ringContext[1].contextData)); 10491 } else if (!strcasecmp(v->name, "dring3context")) { 10492 ast_copy_string(drings.ringContext[2].contextData,v->value,sizeof(drings.ringContext[2].contextData)); 10493 } else if (!strcasecmp(v->name, "dring1")) { 10494 ringc = v->value; 10495 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 10496 } else if (!strcasecmp(v->name, "dring2")) { 10497 ringc = v->value; 10498 sscanf(ringc,"%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 10499 } else if (!strcasecmp(v->name, "dring3")) { 10500 ringc = v->value; 10501 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 10502 } else if (!strcasecmp(v->name, "usecallerid")) { 10503 use_callerid = ast_true(v->value); 10504 } else if (!strcasecmp(v->name, "cidsignalling")) { 10505 if (!strcasecmp(v->value, "bell")) 10506 cid_signalling = CID_SIG_BELL; 10507 else if (!strcasecmp(v->value, "v23")) 10508 cid_signalling = CID_SIG_V23; 10509 else if (!strcasecmp(v->value, "dtmf")) 10510 cid_signalling = CID_SIG_DTMF; 10511 else if (ast_true(v->value)) 10512 cid_signalling = CID_SIG_BELL; 10513 } else if (!strcasecmp(v->name, "cidstart")) { 10514 if (!strcasecmp(v->value, "ring")) 10515 cid_start = CID_START_RING; 10516 else if (!strcasecmp(v->value, "polarity")) 10517 cid_start = CID_START_POLARITY; 10518 else if (!strcasecmp(v->value, "usehist")) 10519 cid_start = CID_START_USEHIST; 10520 else if (ast_true(v->value)) 10521 cid_start = CID_START_RING; 10522 } else if (!strcasecmp(v->name, "threewaycalling")) { 10523 threewaycalling = ast_true(v->value); 10524 } else if (!strcasecmp(v->name, "cancallforward")) { 10525 cancallforward = ast_true(v->value); 10526 } else if (!strcasecmp(v->name, "relaxdtmf")) { 10527 if (ast_true(v->value)) 10528 relaxdtmf = DSP_DIGITMODE_RELAXDTMF; 10529 else 10530 relaxdtmf = 0; 10531 } else if (!strcasecmp(v->name, "mailbox")) { 10532 ast_copy_string(mailbox, v->value, sizeof(mailbox)); 10533 } else if (!strcasecmp(v->name, "adsi")) { 10534 adsi = ast_true(v->value); 10535 } else if (!strcasecmp(v->name, "transfer")) { 10536 transfer = ast_true(v->value); 10537 } else if (!strcasecmp(v->name, "canpark")) { 10538 canpark = ast_true(v->value); 10539 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 10540 echocanbridged = ast_true(v->value); 10541 } else if (!strcasecmp(v->name, "busydetect")) { 10542 busydetect = ast_true(v->value); 10543 } else if (!strcasecmp(v->name, "busycount")) { 10544 busycount = atoi(v->value); 10545 } else if (!strcasecmp(v->name, "busypattern")) { 10546 if (sscanf(v->value, "%d,%d", &busy_tonelength, &busy_quietlength) != 2) { 10547 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 10548 } 10549 } else if (!strcasecmp(v->name, "callprogress")) { 10550 if (ast_true(v->value)) 10551 callprogress |= 1; 10552 else 10553 callprogress &= ~1; 10554 } else if (!strcasecmp(v->name, "faxdetect")) { 10555 if (!strcasecmp(v->value, "incoming")) { 10556 callprogress |= 4; 10557 callprogress &= ~2; 10558 } else if (!strcasecmp(v->value, "outgoing")) { 10559 callprogress &= ~4; 10560 callprogress |= 2; 10561 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 10562 callprogress |= 6; 10563 else 10564 callprogress &= ~6; 10565 } else if (!strcasecmp(v->name, "echocancel")) { 10566 if (!ast_strlen_zero(v->value)) { 10567 y = atoi(v->value); 10568 } else 10569 y = 0; 10570 if ((y == 32) || (y == 64) || (y == 128) || (y == 256)) 10571 echocancel = y; 10572 else { 10573 echocancel = ast_true(v->value); 10574 if (echocancel) 10575 echocancel=128; 10576 } 10577 } else if (!strcasecmp(v->name, "echotraining")) { 10578 if (sscanf(v->value, "%d", &y) == 1) { 10579 if ((y < 10) || (y > 4000)) { 10580 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 2000 ms at line %d\n", v->lineno); 10581 } else { 10582 echotraining = y; 10583 } 10584 } else if (ast_true(v->value)) { 10585 echotraining = 400; 10586 } else 10587 echotraining = 0; 10588 } else if (!strcasecmp(v->name, "hidecallerid")) { 10589 hidecallerid = ast_true(v->value); 10590 } else if (!strcasecmp(v->name, "pulsedial")) { 10591 pulse = ast_true(v->value); 10592 } else if (!strcasecmp(v->name, "callreturn")) { 10593 callreturn = ast_true(v->value); 10594 } else if (!strcasecmp(v->name, "callwaiting")) { 10595 callwaiting = ast_true(v->value); 10596 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 10597 callwaitingcallerid = ast_true(v->value); 10598 } else if (!strcasecmp(v->name, "context")) { 10599 ast_copy_string(context, v->value, sizeof(context)); 10600 } else if (!strcasecmp(v->name, "language")) { 10601 ast_copy_string(language, v->value, sizeof(language)); 10602 } else if (!strcasecmp(v->name, "progzone")) { 10603 ast_copy_string(progzone, v->value, sizeof(progzone)); 10604 } else if (!strcasecmp(v->name, "musiconhold")) { 10605 ast_copy_string(musicclass, v->value, sizeof(musicclass)); 10606 } else if (!strcasecmp(v->name, "stripmsd")) { 10607 stripmsd = atoi(v->value); 10608 } else if (!strcasecmp(v->name, "jitterbuffers")) { 10609 numbufs = atoi(v->value); 10610 } else if (!strcasecmp(v->name, "group")) { 10611 cur_group = ast_get_group(v->value); 10612 } else if (!strcasecmp(v->name, "callgroup")) { 10613 cur_callergroup = ast_get_group(v->value); 10614 } else if (!strcasecmp(v->name, "pickupgroup")) { 10615 cur_pickupgroup = ast_get_group(v->value); 10616 } else if (!strcasecmp(v->name, "immediate")) { 10617 immediate = ast_true(v->value); 10618 } else if (!strcasecmp(v->name, "transfertobusy")) { 10619 transfertobusy = ast_true(v->value); 10620 } else if (!strcasecmp(v->name, "rxgain")) { 10621 if (sscanf(v->value, "%f", &rxgain) != 1) { 10622 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 10623 } 10624 } else if (!strcasecmp(v->name, "txgain")) { 10625 if (sscanf(v->value, "%f", &txgain) != 1) { 10626 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 10627 } 10628 } else if (!strcasecmp(v->name, "tonezone")) { 10629 if (sscanf(v->value, "%d", &tonezone) != 1) { 10630 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 10631 } 10632 } else if (!strcasecmp(v->name, "callerid")) { 10633 if (!strcasecmp(v->value, "asreceived")) { 10634 cid_num[0] = '\0'; 10635 cid_name[0] = '\0'; 10636 } else { 10637 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 10638 } 10639 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 10640 zaptrcallerid = ast_true(v->value); 10641 } else if (!strcasecmp(v->name, "restrictcid")) { 10642 restrictcid = ast_true(v->value); 10643 } else if (!strcasecmp(v->name, "usecallingpres")) { 10644 use_callingpres = ast_true(v->value); 10645 } else if (!strcasecmp(v->name, "accountcode")) { 10646 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10647 } else if (!strcasecmp(v->name, "amaflags")) { 10648 y = ast_cdr_amaflags2int(v->value); 10649 if (y < 0) 10650 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 10651 else 10652 amaflags = y; 10653 } else if(!reload){ 10654 if (!strcasecmp(v->name, "signalling")) { 10655 if (!strcasecmp(v->value, "em")) { 10656 cur_signalling = SIG_EM; 10657 } else if (!strcasecmp(v->value, "em_e1")) { 10658 cur_signalling = SIG_EM_E1; 10659 } else if (!strcasecmp(v->value, "em_w")) { 10660 cur_signalling = SIG_EMWINK; 10661 cur_radio = 0; 10662 } else if (!strcasecmp(v->value, "fxs_ls")) { 10663 cur_signalling = SIG_FXSLS; 10664 cur_radio = 0; 10665 } else if (!strcasecmp(v->value, "fxs_gs")) { 10666 cur_signalling = SIG_FXSGS; 10667 cur_radio = 0; 10668 } else if (!strcasecmp(v->value, "fxs_ks")) { 10669 cur_signalling = SIG_FXSKS; 10670 cur_radio = 0; 10671 } else if (!strcasecmp(v->value, "fxo_ls")) { 10672 cur_signalling = SIG_FXOLS; 10673 cur_radio = 0; 10674 } else if (!strcasecmp(v->value, "fxo_gs")) { 10675 cur_signalling = SIG_FXOGS; 10676 cur_radio = 0; 10677 } else if (!strcasecmp(v->value, "fxo_ks")) { 10678 cur_signalling = SIG_FXOKS; 10679 cur_radio = 0; 10680 } else if (!strcasecmp(v->value, "fxs_rx")) { 10681 cur_signalling = SIG_FXSKS; 10682 cur_radio = 1; 10683 } else if (!strcasecmp(v->value, "fxo_rx")) { 10684 cur_signalling = SIG_FXOLS; 10685 cur_radio = 1; 10686 } else if (!strcasecmp(v->value, "fxs_tx")) { 10687 cur_signalling = SIG_FXSLS; 10688 cur_radio = 1; 10689 } else if (!strcasecmp(v->value, "fxo_tx")) { 10690 cur_signalling = SIG_FXOGS; 10691 cur_radio = 1; 10692 } else if (!strcasecmp(v->value, "em_rx")) { 10693 cur_signalling = SIG_EM; 10694 cur_radio = 1; 10695 } else if (!strcasecmp(v->value, "em_tx")) { 10696 cur_signalling = SIG_EM; 10697 cur_radio = 1; 10698 } else if (!strcasecmp(v->value, "em_rxtx")) { 10699 cur_signalling = SIG_EM; 10700 cur_radio = 2; 10701 } else if (!strcasecmp(v->value, "em_txrx")) { 10702 cur_signalling = SIG_EM; 10703 cur_radio = 2; 10704 } else if (!strcasecmp(v->value, "sf")) { 10705 cur_signalling = SIG_SF; 10706 cur_radio = 0; 10707 } else if (!strcasecmp(v->value, "sf_w")) { 10708 cur_signalling = SIG_SFWINK; 10709 cur_radio = 0; 10710 } else if (!strcasecmp(v->value, "sf_featd")) { 10711 cur_signalling = SIG_FEATD; 10712 cur_radio = 0; 10713 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10714 cur_signalling = SIG_FEATDMF; 10715 cur_radio = 0; 10716 } else if (!strcasecmp(v->value, "sf_featb")) { 10717 cur_signalling = SIG_SF_FEATB; 10718 cur_radio = 0; 10719 } else if (!strcasecmp(v->value, "sf")) { 10720 cur_signalling = SIG_SF; 10721 cur_radio = 0; 10722 } else if (!strcasecmp(v->value, "sf_rx")) { 10723 cur_signalling = SIG_SF; 10724 cur_radio = 1; 10725 } else if (!strcasecmp(v->value, "sf_tx")) { 10726 cur_signalling = SIG_SF; 10727 cur_radio = 1; 10728 } else if (!strcasecmp(v->value, "sf_rxtx")) { 10729 cur_signalling = SIG_SF; 10730 cur_radio = 2; 10731 } else if (!strcasecmp(v->value, "sf_txrx")) { 10732 cur_signalling = SIG_SF; 10733 cur_radio = 2; 10734 } else if (!strcasecmp(v->value, "featd")) { 10735 cur_signalling = SIG_FEATD; 10736 cur_radio = 0; 10737 } else if (!strcasecmp(v->value, "featdmf")) { 10738 cur_signalling = SIG_FEATDMF; 10739 cur_radio = 0; 10740 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10741 cur_signalling = SIG_FEATDMF_TA; 10742 cur_radio = 0; 10743 } else if (!strcasecmp(v->value, "e911")) { 10744 cur_signalling = SIG_E911; 10745 cur_radio = 0; 10746 } else if (!strcasecmp(v->value, "featb")) { 10747 cur_signalling = SIG_FEATB; 10748 cur_radio = 0; 10749 #ifdef ZAPATA_PRI 10750 } else if (!strcasecmp(v->value, "pri_net")) { 10751 cur_radio = 0; 10752 cur_signalling = SIG_PRI; 10753 pritype = PRI_NETWORK; 10754 } else if (!strcasecmp(v->value, "pri_cpe")) { 10755 cur_signalling = SIG_PRI; 10756 cur_radio = 0; 10757 pritype = PRI_CPE; 10758 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 10759 cur_signalling = SIG_GR303FXOKS; 10760 cur_radio = 0; 10761 pritype = PRI_NETWORK; 10762 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 10763 cur_signalling = SIG_GR303FXSKS; 10764 cur_radio = 0; 10765 pritype = PRI_CPE; 10766 #endif 10767 #ifdef ZAPATA_R2 10768 } else if (!strcasecmp(v->value, "r2")) { 10769 cur_signalling = SIG_R2; 10770 cur_radio = 0; 10771 #endif 10772 } else { 10773 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10774 } 10775 #ifdef ZAPATA_R2 10776 } else if (!strcasecmp(v->name, "r2country")) { 10777 r2prot = str2r2prot(v->value); 10778 if (r2prot < 0) { 10779 ast_log(LOG_WARNING, "Unknown R2 Country '%s' at line %d.\n", v->value, v->lineno); 10780 } 10781 #endif 10782 #ifdef ZAPATA_PRI 10783 } else if (!strcasecmp(v->name, "pridialplan")) { 10784 if (!strcasecmp(v->value, "national")) { 10785 dialplan = PRI_NATIONAL_ISDN + 1; 10786 } else if (!strcasecmp(v->value, "unknown")) { 10787 dialplan = PRI_UNKNOWN + 1; 10788 } else if (!strcasecmp(v->value, "private")) { 10789 dialplan = PRI_PRIVATE + 1; 10790 } else if (!strcasecmp(v->value, "international")) { 10791 dialplan = PRI_INTERNATIONAL_ISDN + 1; 10792 } else if (!strcasecmp(v->value, "local")) { 10793 dialplan = PRI_LOCAL_ISDN + 1; 10794 } else if (!strcasecmp(v->value, "dynamic")) { 10795 dialplan = -1; 10796 } else { 10797 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10798 } 10799 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 10800 if (!strcasecmp(v->value, "national")) { 10801 localdialplan = PRI_NATIONAL_ISDN + 1; 10802 } else if (!strcasecmp(v->value, "unknown")) { 10803 localdialplan = PRI_UNKNOWN + 1; 10804 } else if (!strcasecmp(v->value, "private")) { 10805 localdialplan = PRI_PRIVATE + 1; 10806 } else if (!strcasecmp(v->value, "international")) { 10807 localdialplan = PRI_INTERNATIONAL_ISDN + 1; 10808 } else if (!strcasecmp(v->value, "local")) { 10809 localdialplan = PRI_LOCAL_ISDN + 1; 10810 } else if (!strcasecmp(v->value, "dynamic")) { 10811 localdialplan = -1; 10812 } else { 10813 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10814 } 10815 } else if (!strcasecmp(v->name, "switchtype")) { 10816 if (!strcasecmp(v->value, "national")) 10817 switchtype = PRI_SWITCH_NI2; 10818 else if (!strcasecmp(v->value, "ni1")) 10819 switchtype = PRI_SWITCH_NI1; 10820 else if (!strcasecmp(v->value, "dms100")) 10821 switchtype = PRI_SWITCH_DMS100; 10822 else if (!strcasecmp(v->value, "4ess")) 10823 switchtype = PRI_SWITCH_ATT4ESS; 10824 else if (!strcasecmp(v->value, "5ess")) 10825 switchtype = PRI_SWITCH_LUCENT5E; 10826 else if (!strcasecmp(v->value, "euroisdn")) 10827 switchtype = PRI_SWITCH_EUROISDN_E1; 10828 else if (!strcasecmp(v->value, "qsig")) 10829 switchtype = PRI_SWITCH_QSIG; 10830 else { 10831 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 10832 ast_config_destroy(cfg); 10833 ast_mutex_unlock(&iflock); 10834 return -1; 10835 } 10836 } else if (!strcasecmp(v->name, "nsf")) { 10837 if (!strcasecmp(v->value, "sdn")) 10838 nsf = PRI_NSF_SDN; 10839 else if (!strcasecmp(v->value, "megacom")) 10840 nsf = PRI_NSF_MEGACOM; 10841 else if (!strcasecmp(v->value, "accunet")) 10842 nsf = PRI_NSF_ACCUNET; 10843 else if (!strcasecmp(v->value, "none")) 10844 nsf = PRI_NSF_NONE; 10845 else { 10846 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 10847 nsf = PRI_NSF_NONE; 10848 } 10849 } else if (!strcasecmp(v->name, "priindication")) { 10850 if (!strcasecmp(v->value, "outofband")) 10851 priindication_oob = 1; 10852 else if (!strcasecmp(v->value, "inband")) 10853 priindication_oob = 0; 10854 else 10855 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n", 10856 v->value, v->lineno); 10857 } else if (!strcasecmp(v->name, "priexclusive")) { 10858 cur_priexclusive = ast_true(v->value); 10859 } else if (!strcasecmp(v->name, "internationalprefix")) { 10860 ast_copy_string(internationalprefix, v->value, sizeof(internationalprefix)); 10861 } else if (!strcasecmp(v->name, "nationalprefix")) { 10862 ast_copy_string(nationalprefix, v->value, sizeof(nationalprefix)); 10863 } else if (!strcasecmp(v->name, "localprefix")) { 10864 ast_copy_string(localprefix, v->value, sizeof(localprefix)); 10865 } else if (!strcasecmp(v->name, "privateprefix")) { 10866 ast_copy_string(privateprefix, v->value, sizeof(privateprefix)); 10867 } else if (!strcasecmp(v->name, "unknownprefix")) { 10868 ast_copy_string(unknownprefix, v->value, sizeof(unknownprefix)); 10869 } else if (!strcasecmp(v->name, "resetinterval")) { 10870 if (!strcasecmp(v->value, "never")) 10871 resetinterval = -1; 10872 else if( atoi(v->value) >= 60 ) 10873 resetinterval = atoi(v->value); 10874 else 10875 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 10876 v->value, v->lineno); 10877 } else if (!strcasecmp(v->name, "minunused")) { 10878 minunused = atoi(v->value); 10879 } else if (!strcasecmp(v->name, "minidle")) { 10880 minidle = atoi(v->value); 10881 } else if (!strcasecmp(v->name, "idleext")) { 10882 ast_copy_string(idleext, v->value, sizeof(idleext)); 10883 } else if (!strcasecmp(v->name, "idledial")) { 10884 ast_copy_string(idledial, v->value, sizeof(idledial)); 10885 } else if (!strcasecmp(v->name, "overlapdial")) { 10886 overlapdial = ast_true(v->value); 10887 } else if (!strcasecmp(v->name, "pritimer")) { 10888 #ifdef PRI_GETSET_TIMERS 10889 char *timerc; 10890 int timer, timeridx; 10891 c = v->value; 10892 timerc = strsep(&c, ","); 10893 if (timerc) { 10894 timer = atoi(c); 10895 if (!timer) 10896 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 10897 else { 10898 if ((timeridx = pri_timer2idx(timerc)) >= 0) 10899 pritimers[timeridx] = timer; 10900 else 10901 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 10902 } 10903 } else 10904 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 10905 10906 } else if (!strcasecmp(v->name, "facilityenable")) { 10907 facilityenable = ast_true(v->value); 10908 #endif /* PRI_GETSET_TIMERS */ 10909 #endif /* ZAPATA_PRI */ 10910 } else if (!strcasecmp(v->name, "cadence")) { 10911 /* setup to scan our argument */ 10912 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 10913 int i; 10914 struct zt_ring_cadence new_cadence; 10915 int cid_location = -1; 10916 int firstcadencepos = 0; 10917 char original_args[80]; 10918 int cadence_is_ok = 1; 10919 10920 ast_copy_string(original_args, v->value, sizeof(original_args)); 10921 /* 16 cadences allowed (8 pairs) */ 10922 element_count = sscanf(v->value, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]); 10923 10924 /* Cadence must be even (on/off) */ 10925 if (element_count % 2 == 1) { 10926 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 10927 cadence_is_ok = 0; 10928 } 10929 10930 /* Ring cadences cannot be negative */ 10931 for (i=0;i<element_count;i++) { 10932 if (c[i] == 0) { 10933 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 10934 cadence_is_ok = 0; 10935 break; 10936 } else if (c[i] < 0) { 10937 if (i % 2 == 1) { 10938 /* Silence duration, negative possibly okay */ 10939 if (cid_location == -1) { 10940 cid_location = i; 10941 c[i] *= -1; 10942 } else { 10943 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 10944 cadence_is_ok = 0; 10945 break; 10946 } 10947 } else { 10948 if (firstcadencepos == 0) { 10949 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 10950 /* duration will be passed negative to the zaptel driver */ 10951 } else { 10952 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 10953 cadence_is_ok = 0; 10954 break; 10955 } 10956 } 10957 } 10958 } 10959 10960 /* Substitute our scanned cadence */ 10961 for (i=0;i<16;i++) { 10962 new_cadence.ringcadence[i] = c[i]; 10963 } 10964 10965 if (cadence_is_ok) { 10966 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 10967 if (element_count < 2) { 10968 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 10969 } else { 10970 if (cid_location == -1) { 10971 /* user didn't say; default to first pause */ 10972 cid_location = 1; 10973 } else { 10974 /* convert element_index to cidrings value */ 10975 cid_location = (cid_location + 1) / 2; 10976 } 10977 /* ---we like their cadence; try to install it--- */ 10978 if (!user_has_defined_cadences++) 10979 /* this is the first user-defined cadence; clear the default user cadences */ 10980 num_cadence = 0; 10981 if ((num_cadence+1) >= NUM_CADENCE_MAX) 10982 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 10983 else { 10984 cadences[num_cadence] = new_cadence; 10985 cidrings[num_cadence++] = cid_location; 10986 if (option_verbose > 2) 10987 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 10988 } 10989 } 10990 } 10991 } else if (!strcasecmp(v->name, "ringtimeout")) { 10992 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 10993 } else if (!strcasecmp(v->name, "prewink")) { 10994 cur_prewink = atoi(v->value); 10995 } else if (!strcasecmp(v->name, "preflash")) { 10996 cur_preflash = atoi(v->value); 10997 } else if (!strcasecmp(v->name, "wink")) { 10998 cur_wink = atoi(v->value); 10999 } else if (!strcasecmp(v->name, "flash")) { 11000 cur_flash = atoi(v->value); 11001 } else if (!strcasecmp(v->name, "start")) { 11002 cur_start = atoi(v->value); 11003 } else if (!strcasecmp(v->name, "rxwink")) { 11004 cur_rxwink = atoi(v->value); 11005 } else if (!strcasecmp(v->name, "rxflash")) { 11006 cur_rxflash = atoi(v->value); 11007 } else if (!strcasecmp(v->name, "debounce")) { 11008 cur_debounce = atoi(v->value); 11009 } else if (!strcasecmp(v->name, "toneduration")) { 11010 int toneduration; 11011 int ctlfd; 11012 int res; 11013 struct zt_dialparams dps; 11014 11015 ctlfd = open("/dev/zap/ctl", O_RDWR); 11016 if (ctlfd == -1) { 11017 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 11018 return -1; 11019 } 11020 11021 toneduration = atoi(v->value); 11022 if (toneduration > -1) { 11023 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 11024 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 11025 if (res < 0) { 11026 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 11027 return -1; 11028 } 11029 } 11030 close(ctlfd); 11031 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 11032 polarityonanswerdelay = atoi(v->value); 11033 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 11034 answeronpolarityswitch = ast_true(v->value); 11035 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 11036 hanguponpolarityswitch = ast_true(v->value); 11037 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 11038 sendcalleridafter = atoi(v->value); 11039 } else if (!strcasecmp(v->name, "defaultcic")) { 11040 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 11041 } else if (!strcasecmp(v->name, "defaultozz")) { 11042 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 11043 } 11044 } else 11045 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11046 v = v->next; 11047 } 11048 if (!found_pseudo && reload == 0) { 11049 11050 /* Make sure pseudo isn't a member of any groups if 11051 we're automatically making it. */ 11052 cur_group = 0; 11053 cur_callergroup = 0; 11054 cur_pickupgroup = 0; 11055 11056 tmp = mkintf(CHAN_PSEUDO, cur_signalling, cur_radio, NULL, reload); 11057 11058 if (tmp) { 11059 if (option_verbose > 2) 11060 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 11061 } else { 11062 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 11063 } 11064 } 11065 ast_mutex_unlock(&iflock); 11066 ast_config_destroy(cfg); 11067 #ifdef ZAPATA_PRI 11068 if (!reload) { 11069 for (x=0;x<NUM_SPANS;x++) { 11070 if (pris[x].pvts[0]) { 11071 if (start_pri(pris + x)) { 11072 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 11073 return -1; 11074 } else if (option_verbose > 1) 11075 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 11076 } 11077 } 11078 } 11079 #endif 11080 /* And start the monitor for the first time */ 11081 restart_monitor(); 11082 return 0; 11083 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5214 of file chan_zap.c.
References alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_moh_stop(), ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_read(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_free(), callerid_get(), callerid_new(), zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, zt_pvt::cid_start, CID_START_USEHIST, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, ast_frame::frametype, free, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, ast_channel::language, zt_pvt::lastcid_num, callerid_state::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, manager_event(), my_getsigstr(), ast_channel::name, name, NEED_MFDETECT, callerid_state::number, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::transfer, ast_channel::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_history(), zt_get_index(), zt_set_hook(), zt_wait_event(), and zt_wink().
Referenced by handle_init_event(), and zt_handle_event().
05215 { 05216 struct ast_channel *chan = data; 05217 struct zt_pvt *p = chan->tech_pvt; 05218 char exten[AST_MAX_EXTENSION]=""; 05219 char exten2[AST_MAX_EXTENSION]=""; 05220 unsigned char buf[256]; 05221 char dtmfcid[300]; 05222 char dtmfbuf[300]; 05223 struct callerid_state *cs; 05224 char *name=NULL, *number=NULL; 05225 int distMatches; 05226 int curRingData[3]; 05227 int receivedRingT; 05228 int counter1; 05229 int counter; 05230 int samples = 0; 05231 05232 int flags; 05233 int i; 05234 int timeout; 05235 int getforward=0; 05236 char *s1, *s2; 05237 int len = 0; 05238 int res; 05239 int index; 05240 if (option_verbose > 2) 05241 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05242 index = zt_get_index(chan, p, 1); 05243 if (index < 0) { 05244 ast_log(LOG_WARNING, "Huh?\n"); 05245 ast_hangup(chan); 05246 return NULL; 05247 } 05248 if (p->dsp) 05249 ast_dsp_digitreset(p->dsp); 05250 switch(p->sig) { 05251 #ifdef ZAPATA_PRI 05252 case SIG_PRI: 05253 /* Now loop looking for an extension */ 05254 ast_copy_string(exten, p->exten, sizeof(exten)); 05255 len = strlen(exten); 05256 res = 0; 05257 while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05258 if (len && !ast_ignore_pattern(chan->context, exten)) 05259 tone_zone_play_tone(p->subs[index].zfd, -1); 05260 else 05261 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05262 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05263 timeout = matchdigittimeout; 05264 else 05265 timeout = gendigittimeout; 05266 res = ast_waitfordigit(chan, timeout); 05267 if (res < 0) { 05268 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05269 ast_hangup(chan); 05270 return NULL; 05271 } else if (res) { 05272 exten[len++] = res; 05273 exten[len] = '\0'; 05274 } else 05275 break; 05276 } 05277 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05278 if (ast_strlen_zero(exten)) { 05279 if (option_verbose > 2) 05280 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05281 exten[0] = 's'; 05282 exten[1] = '\0'; 05283 } 05284 tone_zone_play_tone(p->subs[index].zfd, -1); 05285 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05286 /* Start the real PBX */ 05287 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05288 if (p->dsp) ast_dsp_digitreset(p->dsp); 05289 zt_enable_ec(p); 05290 ast_setstate(chan, AST_STATE_RING); 05291 res = ast_pbx_run(chan); 05292 if (res) { 05293 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05294 } 05295 } else { 05296 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05297 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05298 ast_hangup(chan); 05299 p->exten[0] = '\0'; 05300 /* Since we send release complete here, we won't get one */ 05301 p->call = NULL; 05302 } 05303 return NULL; 05304 break; 05305 #endif 05306 case SIG_FEATD: 05307 case SIG_FEATDMF: 05308 case SIG_E911: 05309 case SIG_FEATB: 05310 case SIG_EMWINK: 05311 case SIG_SF_FEATD: 05312 case SIG_SF_FEATDMF: 05313 case SIG_SF_FEATB: 05314 case SIG_SFWINK: 05315 if (zt_wink(p, index)) 05316 return NULL; 05317 /* Fall through */ 05318 case SIG_EM: 05319 case SIG_EM_E1: 05320 case SIG_SF: 05321 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05322 if (p->dsp) 05323 ast_dsp_digitreset(p->dsp); 05324 /* set digit mode appropriately */ 05325 if (p->dsp) { 05326 if (NEED_MFDETECT(p)) 05327 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05328 else 05329 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05330 } 05331 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05332 /* Wait for the first digit only if immediate=no */ 05333 if (!p->immediate) 05334 /* Wait for the first digit (up to 5 seconds). */ 05335 res = ast_waitfordigit(chan, 5000); 05336 else res = 0; 05337 if (res > 0) { 05338 /* save first char */ 05339 dtmfbuf[0] = res; 05340 switch(p->sig) { 05341 case SIG_FEATD: 05342 case SIG_SF_FEATD: 05343 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05344 if (res > 0) 05345 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05346 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05347 break; 05348 case SIG_FEATDMF: 05349 case SIG_E911: 05350 case SIG_SF_FEATDMF: 05351 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05352 if (res > 0) { 05353 /* if E911, take off hook */ 05354 if (p->sig == SIG_E911) 05355 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05356 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05357 } 05358 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05359 break; 05360 case SIG_FEATB: 05361 case SIG_SF_FEATB: 05362 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05363 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05364 break; 05365 case SIG_EMWINK: 05366 /* if we received a '*', we are actually receiving Feature Group D 05367 dial syntax, so use that mode; otherwise, fall through to normal 05368 mode 05369 */ 05370 if (res == '*') { 05371 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05372 if (res > 0) 05373 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05374 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05375 break; 05376 } 05377 default: 05378 /* If we got the first digit, get the rest */ 05379 len = 1; 05380 dtmfbuf[len] = '\0'; 05381 while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05382 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05383 timeout = matchdigittimeout; 05384 } else { 05385 timeout = gendigittimeout; 05386 } 05387 res = ast_waitfordigit(chan, timeout); 05388 if (res < 0) { 05389 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05390 ast_hangup(chan); 05391 return NULL; 05392 } else if (res) { 05393 dtmfbuf[len++] = res; 05394 dtmfbuf[len] = '\0'; 05395 } else { 05396 break; 05397 } 05398 } 05399 break; 05400 } 05401 } 05402 if (res == -1) { 05403 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05404 ast_hangup(chan); 05405 return NULL; 05406 } else if (res < 0) { 05407 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05408 ast_hangup(chan); 05409 return NULL; 05410 } 05411 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05412 if (ast_strlen_zero(exten)) 05413 ast_copy_string(exten, "s", sizeof(exten)); 05414 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05415 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05416 if (exten[0] == '*') { 05417 char *stringp=NULL; 05418 ast_copy_string(exten2, exten, sizeof(exten2)); 05419 /* Parse out extension and callerid */ 05420 stringp=exten2 +1; 05421 s1 = strsep(&stringp, "*"); 05422 s2 = strsep(&stringp, "*"); 05423 if (s2) { 05424 if (!ast_strlen_zero(p->cid_num)) 05425 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05426 else 05427 ast_set_callerid(chan, s1, NULL, s1); 05428 ast_copy_string(exten, s2, sizeof(exten)); 05429 } else 05430 ast_copy_string(exten, s1, sizeof(exten)); 05431 } else if (p->sig == SIG_FEATD) 05432 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05433 } 05434 if (p->sig == SIG_FEATDMF) { 05435 if (exten[0] == '*') { 05436 char *stringp=NULL; 05437 ast_copy_string(exten2, exten, sizeof(exten2)); 05438 /* Parse out extension and callerid */ 05439 stringp=exten2 +1; 05440 s1 = strsep(&stringp, "#"); 05441 s2 = strsep(&stringp, "#"); 05442 if (s2) { 05443 if (!ast_strlen_zero(p->cid_num)) 05444 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05445 else 05446 if(*(s1 + 2)) 05447 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05448 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05449 } else 05450 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05451 } else 05452 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05453 } 05454 if (p->sig == SIG_E911) { 05455 if (exten[0] == '*') { 05456 char *stringp=NULL; 05457 ast_copy_string(exten2, exten, sizeof(exten2)); 05458 /* Parse out extension and callerid */ 05459 stringp=exten2 +1; 05460 s1 = strsep(&stringp, "#"); 05461 s2 = strsep(&stringp, "#"); 05462 if (s2 && (*(s2 + 1) == '0')) { 05463 if(*(s2 + 2)) 05464 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05465 } 05466 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05467 else ast_copy_string(exten, "911", sizeof(exten)); 05468 } else 05469 ast_log(LOG_WARNING, "Got a non-E911 input on channel %d. Assuming E&M Wink instead\n", p->channel); 05470 } 05471 if (p->sig == SIG_FEATB) { 05472 if (exten[0] == '*') { 05473 char *stringp=NULL; 05474 ast_copy_string(exten2, exten, sizeof(exten2)); 05475 /* Parse out extension and callerid */ 05476 stringp=exten2 +1; 05477 s1 = strsep(&stringp, "#"); 05478 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05479 } else 05480 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05481 } 05482 if (p->sig == SIG_FEATDMF) { 05483 zt_wink(p, index); 05484 } 05485 zt_enable_ec(p); 05486 if (NEED_MFDETECT(p)) { 05487 if (p->dsp) { 05488 if (!p->hardwaredtmf) 05489 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05490 else { 05491 ast_dsp_free(p->dsp); 05492 p->dsp = NULL; 05493 } 05494 } 05495 } 05496 05497 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05498 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05499 if (p->dsp) ast_dsp_digitreset(p->dsp); 05500 res = ast_pbx_run(chan); 05501 if (res) { 05502 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05503 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05504 } 05505 return NULL; 05506 } else { 05507 if (option_verbose > 2) 05508 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05509 sleep(2); 05510 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05511 if (res < 0) 05512 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05513 else 05514 sleep(1); 05515 res = ast_streamfile(chan, "ss-noservice", chan->language); 05516 if (res >= 0) 05517 ast_waitstream(chan, ""); 05518 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05519 ast_hangup(chan); 05520 return NULL; 05521 } 05522 break; 05523 case SIG_FXOLS: 05524 case SIG_FXOGS: 05525 case SIG_FXOKS: 05526 /* Read the first digit */ 05527 timeout = firstdigittimeout; 05528 /* If starting a threeway call, never timeout on the first digit so someone 05529 can use flash-hook as a "hold" feature */ 05530 if (p->subs[SUB_THREEWAY].owner) 05531 timeout = 999999; 05532 while(len < AST_MAX_EXTENSION-1) { 05533 /* Read digit unless it's supposed to be immediate, in which case the 05534 only answer is 's' */ 05535 if (p->immediate) 05536 res = 's'; 05537 else 05538 res = ast_waitfordigit(chan, timeout); 05539 timeout = 0; 05540 if (res < 0) { 05541 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05542 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05543 ast_hangup(chan); 05544 return NULL; 05545 } else if (res) { 05546 exten[len++]=res; 05547 exten[len] = '\0'; 05548 } 05549 if (!ast_ignore_pattern(chan->context, exten)) 05550 tone_zone_play_tone(p->subs[index].zfd, -1); 05551 else 05552 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05553 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05554 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05555 if (getforward) { 05556 /* Record this as the forwarding extension */ 05557 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05558 if (option_verbose > 2) 05559 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 05560 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05561 if (res) 05562 break; 05563 usleep(500000); 05564 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05565 sleep(1); 05566 memset(exten, 0, sizeof(exten)); 05567 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05568 len = 0; 05569 getforward = 0; 05570 } else { 05571 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05572 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05573 if (!ast_strlen_zero(p->cid_num)) { 05574 if (!p->hidecallerid) 05575 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05576 else 05577 ast_set_callerid(chan, NULL, NULL, p->cid_num); 05578 } 05579 if (!ast_strlen_zero(p->cid_name)) { 05580 if (!p->hidecallerid) 05581 ast_set_callerid(chan, NULL, p->cid_name, NULL); 05582 } 05583 ast_setstate(chan, AST_STATE_RING); 05584 zt_enable_ec(p); 05585 res = ast_pbx_run(chan); 05586 if (res) { 05587 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05588 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05589 } 05590 return NULL; 05591 } 05592 } else { 05593 /* It's a match, but they just typed a digit, and there is an ambiguous match, 05594 so just set the timeout to matchdigittimeout and wait some more */ 05595 timeout = matchdigittimeout; 05596 } 05597 } else if (res == 0) { 05598 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 05599 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05600 zt_wait_event(p->subs[index].zfd); 05601 ast_hangup(chan); 05602 return NULL; 05603 } else if (p->callwaiting && !strcmp(exten, "*70")) { 05604 if (option_verbose > 2) 05605 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 05606 /* Disable call waiting if enabled */ 05607 p->callwaiting = 0; 05608 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05609 if (res) { 05610 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05611 chan->name, strerror(errno)); 05612 } 05613 len = 0; 05614 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 05615 memset(exten, 0, sizeof(exten)); 05616 timeout = firstdigittimeout; 05617 05618 } else if (!strcmp(exten,ast_pickup_ext())) { 05619 /* Scan all channels and see if any there 05620 * ringing channqels with that have call groups 05621 * that equal this channels pickup group 05622 */ 05623 if (index == SUB_REAL) { 05624 /* Switch us from Third call to Call Wait */ 05625 if (p->subs[SUB_THREEWAY].owner) { 05626 /* If you make a threeway call and the *8# a call, it should actually 05627 look like a callwait */ 05628 alloc_sub(p, SUB_CALLWAIT); 05629 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 05630 unalloc_sub(p, SUB_THREEWAY); 05631 } 05632 zt_enable_ec(p); 05633 if (ast_pickup_call(chan)) { 05634 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 05635 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05636 zt_wait_event(p->subs[index].zfd); 05637 } 05638 ast_hangup(chan); 05639 return NULL; 05640 } else { 05641 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 05642 ast_hangup(chan); 05643 return NULL; 05644 } 05645 05646 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 05647 if (option_verbose > 2) 05648 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 05649 /* Disable Caller*ID if enabled */ 05650 p->hidecallerid = 1; 05651 if (chan->cid.cid_num) 05652 free(chan->cid.cid_num); 05653 chan->cid.cid_num = NULL; 05654 if (chan->cid.cid_name) 05655 free(chan->cid.cid_name); 05656 chan->cid.cid_name = NULL; 05657 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05658 if (res) { 05659 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05660 chan->name, strerror(errno)); 05661 } 05662 len = 0; 05663 memset(exten, 0, sizeof(exten)); 05664 timeout = firstdigittimeout; 05665 } else if (p->callreturn && !strcmp(exten, "*69")) { 05666 res = 0; 05667 if (!ast_strlen_zero(p->lastcid_num)) { 05668 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 05669 } 05670 if (!res) 05671 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05672 break; 05673 } else if (!strcmp(exten, "*78")) { 05674 /* Do not disturb */ 05675 if (option_verbose > 2) { 05676 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 05677 } 05678 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05679 "Channel: Zap/%d\r\n" 05680 "Status: enabled\r\n", p->channel); 05681 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05682 p->dnd = 1; 05683 getforward = 0; 05684 memset(exten, 0, sizeof(exten)); 05685 len = 0; 05686 } else if (!strcmp(exten, "*79")) { 05687 /* Do not disturb */ 05688 if (option_verbose > 2) 05689 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 05690 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05691 "Channel: Zap/%d\r\n" 05692 "Status: disabled\r\n", p->channel); 05693 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05694 p->dnd = 0; 05695 getforward = 0; 05696 memset(exten, 0, sizeof(exten)); 05697 len = 0; 05698 } else if (p->cancallforward && !strcmp(exten, "*72")) { 05699 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05700 getforward = 1; 05701 memset(exten, 0, sizeof(exten)); 05702 len = 0; 05703 } else if (p->cancallforward && !strcmp(exten, "*73")) { 05704 if (option_verbose > 2) 05705 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 05706 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05707 memset(p->call_forward, 0, sizeof(p->call_forward)); 05708 getforward = 0; 05709 memset(exten, 0, sizeof(exten)); 05710 len = 0; 05711 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 05712 p->subs[SUB_THREEWAY].owner && 05713 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 05714 /* This is a three way call, the main call being a real channel, 05715 and we're parking the first call. */ 05716 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 05717 if (option_verbose > 2) 05718 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 05719 break; 05720 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 05721 if (option_verbose > 2) 05722 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 05723 res = ast_db_put("blacklist", p->lastcid_num, "1"); 05724 if (!res) { 05725 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05726 memset(exten, 0, sizeof(exten)); 05727 len = 0; 05728 } 05729 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 05730 if (option_verbose > 2) 05731 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 05732 /* Enable Caller*ID if enabled */ 05733 p->hidecallerid = 0; 05734 if (chan->cid.cid_num) 05735 free(chan->cid.cid_num); 05736 chan->cid.cid_num = NULL; 05737 if (chan->cid.cid_name) 05738 free(chan->cid.cid_name); 05739 chan->cid.cid_name = NULL; 05740 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 05741 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05742 if (res) { 05743 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05744 chan->name, strerror(errno)); 05745 } 05746 len = 0; 05747 memset(exten, 0, sizeof(exten)); 05748 timeout = firstdigittimeout; 05749 } else if (!strcmp(exten, "*0")) { 05750 struct ast_channel *nbridge = 05751 p->subs[SUB_THREEWAY].owner; 05752 struct zt_pvt *pbridge = NULL; 05753 /* set up the private struct of the bridged one, if any */ 05754 if (nbridge && ast_bridged_channel(nbridge)) 05755 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 05756 if (nbridge && pbridge && 05757 (!strcmp(nbridge->type,"Zap")) && 05758 (!strcmp(ast_bridged_channel(nbridge)->type, "Zap")) && 05759 ISTRUNK(pbridge)) { 05760 int func = ZT_FLASH; 05761 /* Clear out the dial buffer */ 05762 p->dop.dialstr[0] = '\0'; 05763 /* flash hookswitch */ 05764 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05765 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05766 nbridge->name, strerror(errno)); 05767 } 05768 swap_subs(p, SUB_REAL, SUB_THREEWAY); 05769 unalloc_sub(p, SUB_THREEWAY); 05770 p->owner = p->subs[SUB_REAL].owner; 05771 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 05772 ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner)); 05773 ast_hangup(chan); 05774 return NULL; 05775 } else { 05776 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05777 zt_wait_event(p->subs[index].zfd); 05778 tone_zone_play_tone(p->subs[index].zfd, -1); 05779 swap_subs(p, SUB_REAL, SUB_THREEWAY); 05780 unalloc_sub(p, SUB_THREEWAY); 05781 p->owner = p->subs[SUB_REAL].owner; 05782 ast_hangup(chan); 05783 return NULL; 05784 } 05785 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 05786 ((exten[0] != '*') || (strlen(exten) > 2))) { 05787 if (option_debug) 05788 ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context); 05789 break; 05790 } 05791 if (!timeout) 05792 timeout = gendigittimeout; 05793 if (len && !ast_ignore_pattern(chan->context, exten)) 05794 tone_zone_play_tone(p->subs[index].zfd, -1); 05795 } 05796 break; 05797 case SIG_FXSLS: 05798 case SIG_FXSGS: 05799 case SIG_FXSKS: 05800 #ifdef ZAPATA_PRI 05801 if (p->pri) { 05802 /* This is a GR-303 trunk actually. Wait for the first ring... */ 05803 struct ast_frame *f; 05804 int res; 05805 time_t start; 05806 05807 time(&start); 05808 ast_setstate(chan, AST_STATE_RING); 05809 while(time(NULL) < start + 3) { 05810 res = ast_waitfor(chan, 1000); 05811 if (res) { 05812 f = ast_read(chan); 05813 if (!f) { 05814 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 05815 ast_hangup(chan); 05816 return NULL; 05817 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 05818 res = 1; 05819 } else 05820 res = 0; 05821 ast_frfree(f); 05822 if (res) { 05823 ast_log(LOG_DEBUG, "Got ring!\n"); 05824 res = 0; 05825 break; 05826 } 05827 } 05828 } 05829 } 05830 #endif 05831 /* If we're using an X100P in the UK, caller ID needs to be extracted from 05832 * the history buffer */ 05833 if (p->use_callerid && p->cid_start == CID_START_USEHIST) { 05834 ast_log(LOG_DEBUG,"Using history buffer to extract UK caller ID\n"); 05835 cs = callerid_new(cid_signalling); 05836 if (cs) { 05837 unsigned char cidbuf[16384]; 05838 res=0; 05839 05840 res = zt_get_history(p->subs[index].zfd,cidbuf,sizeof(cidbuf)); 05841 if(res<0) { 05842 ast_log(LOG_ERROR,"zt_get_history failed: %s\n", strerror(errno)); 05843 } else { 05844 res=callerid_feed(cs,cidbuf,sizeof(cidbuf),AST_LAW(p)); 05845 if (res < 0) { 05846 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 05847 } 05848 } 05849 05850 if(res==1) { 05851 callerid_get(cs, &name, &number, &flags); 05852 if (option_debug) 05853 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 05854 } 05855 } 05856 if (p->usedistinctiveringdetection == 1) { 05857 #if 1 05858 bump_gains(p); 05859 #endif 05860 len = 0; 05861 distMatches = 0; 05862 /* Clear the current ring data array so we dont have old data in it. */ 05863 for (receivedRingT=0; receivedRingT < 3; receivedRingT++) { 05864 curRingData[receivedRingT] = 0; 05865 } 05866 receivedRingT = 0; 05867 counter = 0; 05868 counter1 = 0; 05869 /* Check to see if context is what it should be, if not set to be. */ 05870 if (strcmp(p->context,p->defcontext) != 0) { 05871 strncpy(p->context, p->defcontext, sizeof(p->context)-1); 05872 strncpy(chan->context,p->defcontext,sizeof(chan->context)-1); 05873 } 05874 05875 for(;;) { 05876 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 05877 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 05878 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 05879 callerid_free(cs); 05880 ast_hangup(chan); 05881 return NULL; 05882 } 05883 if (i & ZT_IOMUX_SIGEVENT) { 05884 res = zt_get_event(p->subs[index].zfd); 05885 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 05886 res = 0; 05887 /* Let us detect distinctive ring */ 05888 05889 curRingData[receivedRingT] = p->ringt; 05890 05891 if (p->ringt < ringt_base/2) 05892 break; 05893 ++receivedRingT; /* Increment the ringT counter so we can match it against 05894 values in zapata.conf for distinctive ring */ 05895 } else if (i & ZT_IOMUX_READ) { 05896 res = read(p->subs[index].zfd, buf, sizeof(buf)); 05897 if (res < 0) { 05898 if (errno != ELAST) { 05899 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 05900 callerid_free(cs); 05901 ast_hangup(chan); 05902 return NULL; 05903 } 05904 break; 05905 } 05906 if (p->ringt) 05907 p->ringt--; 05908 if (p->ringt == 1) { 05909 res = -1; 05910 break; 05911 } 05912 } 05913 } 05914 if(option_verbose > 2) 05915 /* this only shows up if you have n of the dring patterns filled in */ 05916 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 05917 05918 for (counter=0; counter < 3; counter++) { 05919 /* Check to see if the rings we received match any of the ones in zapata.conf for this 05920 channel */ 05921 distMatches = 0; 05922 for (counter1=0; counter1 < 3; counter1++) { 05923 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 05924 (p->drings.ringnum[counter].ring[counter1]-10)) { 05925 distMatches++; 05926 } 05927 } 05928 if (distMatches == 3) { 05929 /* The ring matches, set the context to whatever is for distinctive ring.. */ 05930 strncpy(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)-1); 05931 strncpy(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)-1); 05932 if(option_verbose > 2) 05933 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 05934 break; 05935 } 05936 } 05937 } 05938 /* Restore linear mode (if appropriate) for Caller*ID processing */ 05939 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05940 #if 1 05941 restore_gains(p); 05942 #endif 05943 } 05944 05945 /* If we want caller id, we're in a prering state due to a polarity reversal 05946 * and we're set to use a polarity reversal to trigger the start of caller id, 05947 * grab the caller id and wait for ringing to start... */ 05948 if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 05949 /* If set to use DTMF CID signalling, listen for DTMF */ 05950 if (p->cid_signalling == CID_SIG_DTMF) { 05951 int i = 0; 05952 cs = NULL; 05953 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 05954 "channel %s\n", chan->name); 05955 zt_setlinear(p->subs[index].zfd, 0); 05956 res = 2000; 05957 for (;;) { 05958 struct ast_frame *f; 05959 res = ast_waitfor(chan, res); 05960 if (res <= 0) { 05961 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 05962 "Exiting simple switch\n"); 05963 ast_hangup(chan); 05964 return NULL; 05965 } 05966 f = ast_read(chan); 05967 if (f->frametype == AST_FRAME_DTMF) { 05968 dtmfbuf[i++] = f->subclass; 05969 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 05970 res = 2000; 05971 } 05972 ast_frfree(f); 05973 if (chan->_state == AST_STATE_RING || 05974 chan->_state == AST_STATE_RINGING) 05975 break; /* Got ring */ 05976 } 05977 dtmfbuf[i] = 0; 05978 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05979 /* Got cid and ring. */ 05980 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 05981 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 05982 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 05983 dtmfcid, flags); 05984 /* If first byte is NULL, we have no cid */ 05985 if (dtmfcid[0]) 05986 number = dtmfcid; 05987 else 05988 number = 0; 05989 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 05990 } else if (p->cid_signalling == CID_SIG_V23) { 05991 cs = callerid_new(p->cid_signalling); 05992 if (cs) { 05993 samples = 0; 05994 #if 1 05995 bump_gains(p); 05996 #endif 05997 /* Take out of linear mode for Caller*ID processing */ 05998 zt_setlinear(p->subs[index].zfd, 0); 05999 06000 /* First we wait and listen for the Caller*ID */ 06001 for(;;) { 06002 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06003 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06004 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06005 callerid_free(cs); 06006 ast_hangup(chan); 06007 return NULL; 06008 } 06009 if (i & ZT_IOMUX_SIGEVENT) { 06010 res = zt_get_event(p->subs[index].zfd); 06011 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06012 res = 0; 06013 break; 06014 } else if (i & ZT_IOMUX_READ) { 06015 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06016 if (res < 0) { 06017 if (errno != ELAST) { 06018 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06019 callerid_free(cs); 06020 ast_hangup(chan); 06021 return NULL; 06022 } 06023 break; 06024 } 06025 samples += res; 06026 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06027 if (res < 0) { 06028 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06029 break; 06030 } else if (res) 06031 break; 06032 else if (samples > (8000 * 10)) 06033 break; 06034 } 06035 } 06036 if (res == 1) { 06037 callerid_get(cs, &name, &number, &flags); 06038 if (option_debug) 06039 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06040 } 06041 if (res < 0) { 06042 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06043 } 06044 06045 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06046 res = 2000; 06047 for (;;) { 06048 struct ast_frame *f; 06049 res = ast_waitfor(chan, res); 06050 if (res <= 0) { 06051 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06052 "Exiting simple switch\n"); 06053 ast_hangup(chan); 06054 return NULL; 06055 } 06056 f = ast_read(chan); 06057 ast_frfree(f); 06058 if (chan->_state == AST_STATE_RING || 06059 chan->_state == AST_STATE_RINGING) 06060 break; /* Got ring */ 06061 } 06062 06063 /* We must have a ring by now, so, if configured, lets try to listen for 06064 * distinctive ringing */ 06065 if (p->usedistinctiveringdetection == 1) { 06066 len = 0; 06067 distMatches = 0; 06068 /* Clear the current ring data array so we dont have old data in it. */ 06069 for (receivedRingT=0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06070 curRingData[receivedRingT] = 0; 06071 receivedRingT = 0; 06072 counter = 0; 06073 counter1 = 0; 06074 /* Check to see if context is what it should be, if not set to be. */ 06075 if (strcmp(p->context,p->defcontext) != 0) { 06076 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06077 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06078 } 06079 06080 for(;;) { 06081 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06082 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06083 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06084 callerid_free(cs); 06085 ast_hangup(chan); 06086 return NULL; 06087 } 06088 if (i & ZT_IOMUX_SIGEVENT) { 06089 res = zt_get_event(p->subs[index].zfd); 06090 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06091 res = 0; 06092 /* Let us detect distinctive ring */ 06093 06094 curRingData[receivedRingT] = p->ringt; 06095 06096 if (p->ringt < p->ringt_base/2) 06097 break; 06098 /* Increment the ringT counter so we can match it against 06099 values in zapata.conf for distinctive ring */ 06100 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06101 break; 06102 } else if (i & ZT_IOMUX_READ) { 06103 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06104 if (res < 0) { 06105 if (errno != ELAST) { 06106 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06107 callerid_free(cs); 06108 ast_hangup(chan); 06109 return NULL; 06110 } 06111 break; 06112 } 06113 if (p->ringt) 06114 p->ringt--; 06115 if (p->ringt == 1) { 06116 res = -1; 06117 break; 06118 } 06119 } 06120 } 06121 if(option_verbose > 2) 06122 /* this only shows up if you have n of the dring patterns filled in */ 06123 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06124 06125 for (counter=0; counter < 3; counter++) { 06126 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06127 channel */ 06128 distMatches = 0; 06129 for (counter1=0; counter1 < 3; counter1++) { 06130 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06131 (p->drings.ringnum[counter].ring[counter1]-10)) { 06132 distMatches++; 06133 } 06134 } 06135 if (distMatches == 3) { 06136 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06137 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06138 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06139 if(option_verbose > 2) 06140 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06141 break; 06142 } 06143 } 06144 } 06145 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06146 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06147 #if 1 06148 restore_gains(p); 06149 #endif 06150 } else 06151 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06152 } else { 06153 ast_log(LOG_WARNING, "Channel %s in prering " 06154 "state, but I have nothing to do. " 06155 "Terminating simple switch, should be " 06156 "restarted by the actual ring.\n", 06157 chan->name); 06158 ast_hangup(chan); 06159 return NULL; 06160 } 06161 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06162 /* FSK Bell202 callerID */ 06163 cs = callerid_new(p->cid_signalling); 06164 if (cs) { 06165 #if 1 06166 bump_gains(p); 06167 #endif 06168 samples = 0; 06169 len = 0; 06170 distMatches = 0; 06171 /* Clear the current ring data array so we dont have old data in it. */ 06172 for (receivedRingT=0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06173 curRingData[receivedRingT] = 0; 06174 receivedRingT = 0; 06175 counter = 0; 06176 counter1 = 0; 06177 /* Check to see if context is what it should be, if not set to be. */ 06178 if (strcmp(p->context,p->defcontext) != 0) { 06179 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06180 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06181 } 06182 06183 /* Take out of linear mode for Caller*ID processing */ 06184 zt_setlinear(p->subs[index].zfd, 0); 06185 for(;;) { 06186 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06187 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06188 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06189 callerid_free(cs); 06190 ast_hangup(chan); 06191 return NULL; 06192 } 06193 if (i & ZT_IOMUX_SIGEVENT) { 06194 res = zt_get_event(p->subs[index].zfd); 06195 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06196 res = 0; 06197 /* Let us detect callerid when the telco uses distinctive ring */ 06198 06199 curRingData[receivedRingT] = p->ringt; 06200 06201 if (p->ringt < p->ringt_base/2) 06202 break; 06203 /* Increment the ringT counter so we can match it against 06204 values in zapata.conf for distinctive ring */ 06205 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06206 break; 06207 } else if (i & ZT_IOMUX_READ) { 06208 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06209 if (res < 0) { 06210 if (errno != ELAST) { 06211 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06212 callerid_free(cs); 06213 ast_hangup(chan); 06214 return NULL; 06215 } 06216 break; 06217 } 06218 if (p->ringt) 06219 p->ringt--; 06220 if (p->ringt == 1) { 06221 res = -1; 06222 break; 06223 } 06224 samples += res; 06225 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06226 if (res < 0) { 06227 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06228 break; 06229 } else if (res) 06230 break; 06231 else if (samples > (8000 * 10)) 06232 break; 06233 } 06234 } 06235 if (p->usedistinctiveringdetection == 1) { 06236 if(option_verbose > 2) 06237 /* this only shows up if you have n of the dring patterns filled in */ 06238 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06239 06240 for (counter=0; counter < 3; counter++) { 06241 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06242 channel */ 06243 distMatches = 0; 06244 for (counter1=0; counter1 < 3; counter1++) { 06245 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06246 (p->drings.ringnum[counter].ring[counter1]-10)) { 06247 distMatches++; 06248 } 06249 } 06250 if (distMatches == 3) { 06251 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06252 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06253 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06254 if(option_verbose > 2) 06255 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06256 break; 06257 } 06258 } 06259 } 06260 if (res == 1) { 06261 callerid_get(cs, &name, &number, &flags); 06262 if (option_debug) 06263 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06264 } 06265 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06266 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06267 #if 1 06268 restore_gains(p); 06269 #endif 06270 if (res < 0) { 06271 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06272 } 06273 } else 06274 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06275 } 06276 else 06277 cs = NULL; 06278 if (number || name) { 06279 if (chan->cid.cid_num) { 06280 free(chan->cid.cid_num); 06281 chan->cid.cid_num = NULL; 06282 } 06283 if (chan->cid.cid_name) { 06284 free(chan->cid.cid_name); 06285 chan->cid.cid_name = NULL; 06286 } 06287 } 06288 if (number) 06289 ast_shrink_phone_number(number); 06290 06291 ast_set_callerid(chan, number, name, number); 06292 06293 if (cs) 06294 callerid_free(cs); 06295 ast_setstate(chan, AST_STATE_RING); 06296 chan->rings = 1; 06297 p->ringt = p->ringt_base; 06298 res = ast_pbx_run(chan); 06299 if (res) { 06300 ast_hangup(chan); 06301 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06302 } 06303 return NULL; 06304 default: 06305 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06306 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06307 if (res < 0) 06308 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06309 } 06310 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06311 if (res < 0) 06312 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06313 ast_hangup(chan); 06314 return NULL; 06315 }
static void swap_subs | ( | struct zt_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 861 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, ast_channel::fds, zt_subchannel::inthreeway, LOG_DEBUG, zt_subchannel::owner, zt_pvt::subs, wakeup_sub(), and zt_subchannel::zfd.
Referenced by attempt_transfer(), ss_thread(), zt_answer(), zt_handle_event(), and zt_hangup().
00862 { 00863 int tchan; 00864 int tinthreeway; 00865 struct ast_channel *towner; 00866 00867 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 00868 00869 tchan = p->subs[a].chan; 00870 towner = p->subs[a].owner; 00871 tinthreeway = p->subs[a].inthreeway; 00872 00873 p->subs[a].chan = p->subs[b].chan; 00874 p->subs[a].owner = p->subs[b].owner; 00875 p->subs[a].inthreeway = p->subs[b].inthreeway; 00876 00877 p->subs[b].chan = tchan; 00878 p->subs[b].owner = towner; 00879 p->subs[b].inthreeway = tinthreeway; 00880 00881 if (p->subs[a].owner) 00882 p->subs[a].owner->fds[0] = p->subs[a].zfd; 00883 if (p->subs[b].owner) 00884 p->subs[b].owner->fds[0] = p->subs[b].zfd; 00885 wakeup_sub(p, a, NULL); 00886 wakeup_sub(p, b, NULL); 00887 }
static int unalloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 998 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, zt_subchannel::curconf, zt_subchannel::inthreeway, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, zt_subchannel::owner, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::subs, zt_subchannel::zfd, and zt_close().
00999 { 01000 if (!x) { 01001 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 01002 return -1; 01003 } 01004 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 01005 if (p->subs[x].zfd > -1) { 01006 zt_close(p->subs[x].zfd); 01007 } 01008 p->subs[x].zfd = -1; 01009 p->subs[x].linear = 0; 01010 p->subs[x].chan = 0; 01011 p->subs[x].owner = NULL; 01012 p->subs[x].inthreeway = 0; 01013 p->polarity = POLARITY_IDLE; 01014 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 01015 return 0; 01016 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 10281 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
10282 { 10283 #ifdef ZAPATA_PRI 10284 int y; 10285 for (y=0;y<NUM_SPANS;y++) 10286 ast_mutex_destroy(&pris[y].lock); 10287 #endif 10288 return __unload_module(); 10289 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1328 of file chan_zap.c.
References conf_add(), conf_del(), zt_subchannel::inthreeway, isslavenative(), zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), zt_bridge(), zt_handle_event(), and zt_hangup().
01329 { 01330 int needconf = 0; 01331 int x; 01332 int useslavenative; 01333 struct zt_pvt *slave = NULL; 01334 01335 useslavenative = isslavenative(p, &slave); 01336 /* Start with the obvious, general stuff */ 01337 for (x=0;x<3;x++) { 01338 /* Look for three way calls */ 01339 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01340 conf_add(p, &p->subs[x], x, 0); 01341 needconf++; 01342 } else { 01343 conf_del(p, &p->subs[x], x); 01344 } 01345 } 01346 /* If we have a slave, add him to our conference now. or DAX 01347 if this is slave native */ 01348 for (x=0;x<MAX_SLAVES;x++) { 01349 if (p->slaves[x]) { 01350 if (useslavenative) 01351 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01352 else { 01353 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01354 needconf++; 01355 } 01356 } 01357 } 01358 /* If we're supposed to be in there, do so now */ 01359 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01360 if (useslavenative) 01361 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01362 else { 01363 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01364 needconf++; 01365 } 01366 } 01367 /* If we have a master, add ourselves to his conference */ 01368 if (p->master) { 01369 if (isslavenative(p->master, NULL)) { 01370 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01371 } else { 01372 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01373 } 01374 } 01375 if (!needconf) { 01376 /* Nobody is left (or should be left) in our conference. 01377 Kill it. */ 01378 p->confno = -1; 01379 } 01380 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01381 return 0; 01382 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 11244 of file chan_zap.c.
11245 { 11246 return usecnt; 11247 }
static void wakeup_sub | ( | struct zt_pvt * | p, | |
int | a, | |||
void * | pri | |||
) | [static] |
Definition at line 800 of file chan_zap.c.
References AST_FRAME_NULL, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), zt_pvt::lock, ast_channel::lock, zt_subchannel::owner, and zt_pvt::subs.
Referenced by swap_subs().
00802 { 00803 struct ast_frame null = { AST_FRAME_NULL, }; 00804 #ifdef ZAPATA_PRI 00805 if (pri) 00806 ast_mutex_unlock(&pri->lock); 00807 #endif 00808 for (;;) { 00809 if (p->subs[a].owner) { 00810 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00811 ast_mutex_unlock(&p->lock); 00812 usleep(1); 00813 ast_mutex_lock(&p->lock); 00814 } else { 00815 ast_queue_frame(p->subs[a].owner, &null); 00816 ast_mutex_unlock(&p->subs[a].owner->lock); 00817 break; 00818 } 00819 } else 00820 break; 00821 } 00822 #ifdef ZAPATA_PRI 00823 if (pri) 00824 ast_mutex_lock(&pri->lock); 00825 #endif 00826 }
static int zap_destroy_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9628 of file chan_zap.c.
References zt_pvt::channel, destroy_channel(), iflist, zt_pvt::next, zt_pvt::prev, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
09629 { 09630 int channel = 0; 09631 struct zt_pvt *tmp = NULL; 09632 struct zt_pvt *prev = NULL; 09633 09634 if (argc != 4) { 09635 return RESULT_SHOWUSAGE; 09636 } 09637 channel = atoi(argv[3]); 09638 09639 tmp = iflist; 09640 while (tmp) { 09641 if (tmp->channel == channel) { 09642 destroy_channel(prev, tmp, 1); 09643 return RESULT_SUCCESS; 09644 } 09645 prev = tmp; 09646 tmp = tmp->next; 09647 } 09648 return RESULT_FAILURE; 09649 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 10023 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, ast_channel::name, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
10024 { 10025 if (p) { 10026 switch(mode) { 10027 case TRANSFER: 10028 p->fake_event = ZT_EVENT_WINKFLASH; 10029 break; 10030 case HANGUP: 10031 p->fake_event = ZT_EVENT_ONHOOK; 10032 break; 10033 default: 10034 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 10035 } 10036 } 10037 return 0; 10038 }
Definition at line 831 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.
Referenced by action_zapdialoffhook().
00833 { 00834 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00835 #ifdef ZAPATA_PRI 00836 if (pri) 00837 ast_mutex_unlock(&pri->lock); 00838 #endif 00839 for (;;) { 00840 if (p->owner) { 00841 if (ast_mutex_trylock(&p->owner->lock)) { 00842 ast_mutex_unlock(&p->lock); 00843 usleep(1); 00844 ast_mutex_lock(&p->lock); 00845 } else { 00846 ast_queue_frame(p->owner, f); 00847 ast_mutex_unlock(&p->owner->lock); 00848 break; 00849 } 00850 } else 00851 break; 00852 } 00853 #ifdef ZAPATA_PRI 00854 if (pri) 00855 ast_mutex_lock(&pri->lock); 00856 #endif 00857 }
static int zap_restart | ( | void | ) | [static] |
Definition at line 9652 of file chan_zap.c.
References ast_log(), ast_verbose(), destroy_channel(), iflist, option_debug, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.
Referenced by action_zaprestart(), and zap_restart_cmd().
09653 { 09654 if (option_verbose > 0) 09655 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 09656 while (iflist) { 09657 if (option_debug) 09658 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 09659 /* Also updates iflist: */ 09660 destroy_channel(NULL, iflist, 1); 09661 } 09662 if (option_debug) 09663 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 09664 if (setup_zap(0) != 0) { 09665 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 09666 return 1; 09667 } 09668 return 0; 09669 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9671 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
09672 { 09673 if (argc != 2) { 09674 return RESULT_SHOWUSAGE; 09675 } 09676 09677 if (zap_restart() != 0) 09678 return RESULT_FAILURE; 09679 return RESULT_SUCCESS; 09680 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9753 of file chan_zap.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::callwaitcas, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::destroy, zt_pvt::dialing, zt_pvt::dsp, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::exten, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, lock, zt_pvt::master, ast_channel::name, zt_pvt::next, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and zt_pvt::subs.
09754 { 09755 int channel; 09756 struct zt_pvt *tmp = NULL; 09757 ZT_CONFINFO ci; 09758 ZT_PARAMS ps; 09759 int x; 09760 ast_mutex_t *lock; 09761 struct zt_pvt *start; 09762 #ifdef ZAPATA_PRI 09763 char *c; 09764 int trunkgroup; 09765 struct zt_pri *pri=NULL; 09766 #endif 09767 09768 lock = &iflock; 09769 start = iflist; 09770 09771 if (argc != 4) 09772 return RESULT_SHOWUSAGE; 09773 #ifdef ZAPATA_PRI 09774 if ((c = strchr(argv[3], ':'))) { 09775 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 09776 return RESULT_SHOWUSAGE; 09777 if ((trunkgroup < 1) || (channel < 1)) 09778 return RESULT_SHOWUSAGE; 09779 for (x=0;x<NUM_SPANS;x++) { 09780 if (pris[x].trunkgroup == trunkgroup) { 09781 pri = pris + x; 09782 break; 09783 } 09784 } 09785 if (pri) { 09786 start = pri->crvs; 09787 lock = &pri->lock; 09788 } else { 09789 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09790 return RESULT_FAILURE; 09791 } 09792 } else 09793 #endif 09794 channel = atoi(argv[3]); 09795 09796 ast_mutex_lock(lock); 09797 tmp = start; 09798 while (tmp) { 09799 if (tmp->channel == channel) { 09800 #ifdef ZAPATA_PRI 09801 if (pri) 09802 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 09803 else 09804 #endif 09805 ast_cli(fd, "Channel: %d\n", tmp->channel); 09806 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 09807 ast_cli(fd, "Span: %d\n", tmp->span); 09808 ast_cli(fd, "Extension: %s\n", tmp->exten); 09809 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 09810 ast_cli(fd, "Context: %s\n", tmp->context); 09811 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 09812 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 09813 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 09814 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 09815 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 09816 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 09817 ast_cli(fd, "Radio: %d\n", tmp->radio); 09818 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 09819 ast_cli(fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? tmp->subs[SUB_REAL].owner->name : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : ""); 09820 ast_cli(fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? tmp->subs[SUB_CALLWAIT].owner->name : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : ""); 09821 ast_cli(fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? tmp->subs[SUB_THREEWAY].owner->name : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : ""); 09822 ast_cli(fd, "Confno: %d\n", tmp->confno); 09823 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 09824 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 09825 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 09826 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 09827 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 09828 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 09829 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 09830 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 09831 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 09832 if (tmp->master) 09833 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 09834 for (x=0;x<MAX_SLAVES;x++) { 09835 if (tmp->slaves[x]) 09836 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 09837 } 09838 #ifdef ZAPATA_PRI 09839 if (tmp->pri) { 09840 ast_cli(fd, "PRI Flags: "); 09841 if (tmp->resetting) 09842 ast_cli(fd, "Resetting "); 09843 if (tmp->call) 09844 ast_cli(fd, "Call "); 09845 if (tmp->bearer) 09846 ast_cli(fd, "Bearer "); 09847 ast_cli(fd, "\n"); 09848 if (tmp->logicalspan) 09849 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 09850 else 09851 ast_cli(fd, "PRI Logical Span: Implicit\n"); 09852 } 09853 09854 #endif 09855 #ifdef ZAPATA_R2 09856 if (tmp->r2) { 09857 ast_cli(fd, "R2 Flags: "); 09858 if (tmp->r2blocked) 09859 ast_cli(fd, "Blocked "); 09860 if (tmp->hasr2call) 09861 ast_cli(fd, "Call "); 09862 ast_cli(fd, "\n"); 09863 } 09864 #endif 09865 memset(&ci, 0, sizeof(ci)); 09866 ps.channo = tmp->channel; 09867 if (tmp->subs[SUB_REAL].zfd > -1) { 09868 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 09869 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 09870 } 09871 #ifdef ZT_GETCONFMUTE 09872 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 09873 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 09874 } 09875 #endif 09876 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 09877 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 09878 } else { 09879 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 09880 } 09881 } 09882 ast_mutex_unlock(lock); 09883 return RESULT_SUCCESS; 09884 } 09885 tmp = tmp->next; 09886 } 09887 09888 ast_cli(fd, "Unable to find given channel %d\n", channel); 09889 ast_mutex_unlock(lock); 09890 return RESULT_FAILURE; 09891 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9692 of file chan_zap.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::context, zt_pvt::exten, FORMAT, FORMAT2, iflist, zt_pvt::language, lock, zt_pvt::musicclass, zt_pvt::next, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
09693 { 09694 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09695 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09696 struct zt_pvt *tmp = NULL; 09697 char tmps[20] = ""; 09698 ast_mutex_t *lock; 09699 struct zt_pvt *start; 09700 #ifdef ZAPATA_PRI 09701 int trunkgroup; 09702 struct zt_pri *pri=NULL; 09703 int x; 09704 #endif 09705 09706 lock = &iflock; 09707 start = iflist; 09708 09709 #ifdef ZAPATA_PRI 09710 if (argc == 4) { 09711 if ((trunkgroup = atoi(argv[3])) < 1) 09712 return RESULT_SHOWUSAGE; 09713 for (x=0;x<NUM_SPANS;x++) { 09714 if (pris[x].trunkgroup == trunkgroup) { 09715 pri = pris + x; 09716 break; 09717 } 09718 } 09719 if (pri) { 09720 start = pri->crvs; 09721 lock = &pri->lock; 09722 } else { 09723 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09724 return RESULT_FAILURE; 09725 } 09726 } else 09727 #endif 09728 if (argc != 3) 09729 return RESULT_SHOWUSAGE; 09730 09731 ast_mutex_lock(lock); 09732 #ifdef ZAPATA_PRI 09733 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MusicOnHold"); 09734 #else 09735 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MusicOnHold"); 09736 #endif 09737 09738 tmp = start; 09739 while (tmp) { 09740 if (tmp->channel > 0) { 09741 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 09742 } else 09743 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 09744 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->musicclass); 09745 tmp = tmp->next; 09746 } 09747 ast_mutex_unlock(lock); 09748 return RESULT_SUCCESS; 09749 #undef FORMAT 09750 #undef FORMAT2 09751 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9924 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), FORMAT, FORMAT2, and RESULT_FAILURE.
09924 { 09925 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 09926 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 09927 09928 int span; 09929 int res; 09930 char alarms[50]; 09931 09932 int ctl; 09933 ZT_SPANINFO s; 09934 09935 ctl = open("/dev/zap/ctl", O_RDWR); 09936 if (ctl < 0) { 09937 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 09938 ast_cli(fd, "No Zaptel interface found.\n"); 09939 return RESULT_FAILURE; 09940 } 09941 ast_cli(fd,FORMAT2, "Description", "Alarms","IRQ","bpviol","CRC4"); 09942 09943 for (span=1;span < ZT_MAX_SPANS;++span) { 09944 s.spanno = span; 09945 res = ioctl(ctl, ZT_SPANSTAT, &s); 09946 if (res) { 09947 continue; 09948 } 09949 alarms[0] = '\0'; 09950 if (s.alarms > 0) { 09951 if (s.alarms & ZT_ALARM_BLUE) 09952 strcat(alarms,"BLU/"); 09953 if (s.alarms & ZT_ALARM_YELLOW) 09954 strcat(alarms, "YEL/"); 09955 if (s.alarms & ZT_ALARM_RED) 09956 strcat(alarms, "RED/"); 09957 if (s.alarms & ZT_ALARM_LOOPBACK) 09958 strcat(alarms,"LB/"); 09959 if (s.alarms & ZT_ALARM_RECOVER) 09960 strcat(alarms,"REC/"); 09961 if (s.alarms & ZT_ALARM_NOTOPEN) 09962 strcat(alarms, "NOP/"); 09963 if (!strlen(alarms)) 09964 strcat(alarms, "UUU/"); 09965 if (strlen(alarms)) { 09966 /* Strip trailing / */ 09967 alarms[strlen(alarms)-1]='\0'; 09968 } 09969 } else { 09970 if (s.numchans) 09971 strcpy(alarms, "OK"); 09972 else 09973 strcpy(alarms, "UNCONFIGURED"); 09974 } 09975 09976 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 09977 } 09978 close(ctl); 09979 09980 return RESULT_SUCCESS; 09981 #undef FORMAT 09982 #undef FORMAT2 09983 }
static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1140 of file chan_zap.c.
References SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01141 { 01142 static char buf[256]; 01143 switch(sig) { 01144 case SIG_EM: 01145 return "E & M Immediate"; 01146 case SIG_EMWINK: 01147 return "E & M Wink"; 01148 case SIG_EM_E1: 01149 return "E & M E1"; 01150 case SIG_FEATD: 01151 return "Feature Group D (DTMF)"; 01152 case SIG_FEATDMF: 01153 return "Feature Group D (MF)"; 01154 case SIG_FEATDMF_TA: 01155 return "Feature Groud D (MF) Tandem Access"; 01156 case SIG_FEATB: 01157 return "Feature Group B (MF)"; 01158 case SIG_E911: 01159 return "E911 (MF)"; 01160 case SIG_FXSLS: 01161 return "FXS Loopstart"; 01162 case SIG_FXSGS: 01163 return "FXS Groundstart"; 01164 case SIG_FXSKS: 01165 return "FXS Kewlstart"; 01166 case SIG_FXOLS: 01167 return "FXO Loopstart"; 01168 case SIG_FXOGS: 01169 return "FXO Groundstart"; 01170 case SIG_FXOKS: 01171 return "FXO Kewlstart"; 01172 case SIG_PRI: 01173 return "PRI Signalling"; 01174 case SIG_R2: 01175 return "R2 Signalling"; 01176 case SIG_SF: 01177 return "SF (Tone) Signalling Immediate"; 01178 case SIG_SFWINK: 01179 return "SF (Tone) Signalling Wink"; 01180 case SIG_SF_FEATD: 01181 return "SF (Tone) Signalling with Feature Group D (DTMF)"; 01182 case SIG_SF_FEATDMF: 01183 return "SF (Tone) Signalling with Feature Group D (MF)"; 01184 case SIG_SF_FEATB: 01185 return "SF (Tone) Signalling with Feature Group B (MF)"; 01186 case SIG_GR303FXOKS: 01187 return "GR-303 Signalling with FXOKS"; 01188 case SIG_GR303FXSKS: 01189 return "GR-303 Signalling with FXSKS"; 01190 case 0: 01191 return "Pseudo Signalling"; 01192 default: 01193 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01194 return buf; 01195 } 01196 }
static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2644 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().
02645 { 02646 struct zt_pvt *p = ast->tech_pvt; 02647 int res=0; 02648 int index; 02649 int oldstate = ast->_state; 02650 ast_setstate(ast, AST_STATE_UP); 02651 ast_mutex_lock(&p->lock); 02652 index = zt_get_index(ast, p, 0); 02653 if (index < 0) 02654 index = SUB_REAL; 02655 /* nothing to do if a radio channel */ 02656 if (p->radio) { 02657 ast_mutex_unlock(&p->lock); 02658 return 0; 02659 } 02660 switch(p->sig) { 02661 case SIG_FXSLS: 02662 case SIG_FXSGS: 02663 case SIG_FXSKS: 02664 p->ringt = 0; 02665 /* Fall through */ 02666 case SIG_EM: 02667 case SIG_EM_E1: 02668 case SIG_EMWINK: 02669 case SIG_FEATD: 02670 case SIG_FEATDMF: 02671 case SIG_E911: 02672 case SIG_FEATB: 02673 case SIG_SF: 02674 case SIG_SFWINK: 02675 case SIG_SF_FEATD: 02676 case SIG_SF_FEATDMF: 02677 case SIG_SF_FEATB: 02678 case SIG_FXOLS: 02679 case SIG_FXOGS: 02680 case SIG_FXOKS: 02681 /* Pick up the line */ 02682 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02683 if(p->hanguponpolarityswitch) { 02684 gettimeofday(&p->polaritydelaytv, NULL); 02685 } 02686 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02687 tone_zone_play_tone(p->subs[index].zfd, -1); 02688 p->dialing = 0; 02689 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02690 if (oldstate == AST_STATE_RINGING) { 02691 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02692 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02693 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02694 p->owner = p->subs[SUB_REAL].owner; 02695 } 02696 } 02697 if (p->sig & __ZT_SIG_FXS) { 02698 zt_enable_ec(p); 02699 zt_train_ec(p); 02700 } 02701 break; 02702 #ifdef ZAPATA_PRI 02703 case SIG_PRI: 02704 /* Send a pri acknowledge */ 02705 if (!pri_grab(p, p->pri)) { 02706 p->proceeding = 1; 02707 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02708 pri_rel(p->pri); 02709 } else { 02710 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02711 res= -1; 02712 } 02713 break; 02714 #endif 02715 #ifdef ZAPATA_R2 02716 case SIG_R2: 02717 res = mfcr2_AnswerCall(p->r2, NULL); 02718 if (res) 02719 ast_log(LOG_WARNING, "R2 Answer call failed :( on %s\n", ast->name); 02720 break; 02721 #endif 02722 case 0: 02723 ast_mutex_unlock(&p->lock); 02724 return 0; 02725 default: 02726 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02727 res = -1; 02728 } 02729 ast_mutex_unlock(&p->lock); 02730 return res; 02731 }
static enum ast_bridge_result zt_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 3001 of file chan_zap.c.
References ast_channel::_state, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), AST_STATE_RINGING, ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), ast_channel::fds, ast_frame::frametype, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, master, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().
03002 { 03003 struct ast_channel *who; 03004 struct zt_pvt *p0, *p1, *op0, *op1; 03005 struct zt_pvt *master = NULL, *slave = NULL; 03006 struct ast_frame *f; 03007 int inconf = 0; 03008 int nothingok = 1; 03009 int ofd0, ofd1; 03010 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03011 int os0 = -1, os1 = -1; 03012 int priority = 0; 03013 struct ast_channel *oc0, *oc1; 03014 enum ast_bridge_result res; 03015 03016 #ifdef PRI_2BCT 03017 int triedtopribridge = 0; 03018 q931_call *q931c0 = NULL, *q931c1 = NULL; 03019 #endif 03020 03021 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03022 There is code below to handle it properly until DTMF is actually seen, 03023 but due to currently unresolved issues it's ignored... 03024 */ 03025 03026 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03027 return AST_BRIDGE_FAILED_NOWARN; 03028 03029 ast_mutex_lock(&c0->lock); 03030 ast_mutex_lock(&c1->lock); 03031 03032 p0 = c0->tech_pvt; 03033 p1 = c1->tech_pvt; 03034 /* cant do pseudo-channels here */ 03035 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03036 ast_mutex_unlock(&c0->lock); 03037 ast_mutex_unlock(&c1->lock); 03038 return AST_BRIDGE_FAILED_NOWARN; 03039 } 03040 03041 oi0 = zt_get_index(c0, p0, 0); 03042 oi1 = zt_get_index(c1, p1, 0); 03043 if ((oi0 < 0) || (oi1 < 0)) { 03044 ast_mutex_unlock(&c0->lock); 03045 ast_mutex_unlock(&c1->lock); 03046 return AST_BRIDGE_FAILED; 03047 } 03048 03049 op0 = p0 = c0->tech_pvt; 03050 op1 = p1 = c1->tech_pvt; 03051 ofd0 = c0->fds[0]; 03052 ofd1 = c1->fds[0]; 03053 oc0 = p0->owner; 03054 oc1 = p1->owner; 03055 03056 if (ast_mutex_trylock(&p0->lock)) { 03057 /* Don't block, due to potential for deadlock */ 03058 ast_mutex_unlock(&c0->lock); 03059 ast_mutex_unlock(&c1->lock); 03060 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03061 return AST_BRIDGE_RETRY; 03062 } 03063 if (ast_mutex_trylock(&p1->lock)) { 03064 /* Don't block, due to potential for deadlock */ 03065 ast_mutex_unlock(&p0->lock); 03066 ast_mutex_unlock(&c0->lock); 03067 ast_mutex_unlock(&c1->lock); 03068 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03069 return AST_BRIDGE_RETRY; 03070 } 03071 03072 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03073 if (p0->owner && p1->owner) { 03074 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03075 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03076 master = p0; 03077 slave = p1; 03078 inconf = 1; 03079 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03080 master = p1; 03081 slave = p0; 03082 inconf = 1; 03083 } else { 03084 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03085 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03086 p0->channel, 03087 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03088 p0->subs[SUB_REAL].inthreeway, p0->channel, 03089 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03090 p1->subs[SUB_REAL].inthreeway); 03091 } 03092 nothingok = 0; 03093 } 03094 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03095 if (p1->subs[SUB_THREEWAY].inthreeway) { 03096 master = p1; 03097 slave = p0; 03098 nothingok = 0; 03099 } 03100 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03101 if (p0->subs[SUB_THREEWAY].inthreeway) { 03102 master = p0; 03103 slave = p1; 03104 nothingok = 0; 03105 } 03106 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03107 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03108 don't put us in anything */ 03109 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03110 master = p1; 03111 slave = p0; 03112 nothingok = 0; 03113 } 03114 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03115 /* Same as previous */ 03116 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03117 master = p0; 03118 slave = p1; 03119 nothingok = 0; 03120 } 03121 } 03122 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03123 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03124 if (master && slave) { 03125 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03126 in an active threeway call with a channel that is ringing, we should 03127 indicate ringing. */ 03128 if ((oi1 == SUB_THREEWAY) && 03129 p1->subs[SUB_THREEWAY].inthreeway && 03130 p1->subs[SUB_REAL].owner && 03131 p1->subs[SUB_REAL].inthreeway && 03132 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03133 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03134 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03135 os1 = p1->subs[SUB_REAL].owner->_state; 03136 } else { 03137 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03138 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03139 } 03140 if ((oi0 == SUB_THREEWAY) && 03141 p0->subs[SUB_THREEWAY].inthreeway && 03142 p0->subs[SUB_REAL].owner && 03143 p0->subs[SUB_REAL].inthreeway && 03144 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03145 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03146 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03147 os0 = p0->subs[SUB_REAL].owner->_state; 03148 } else { 03149 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03150 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03151 } 03152 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03153 if (!p0->echocanbridged || !p1->echocanbridged) { 03154 /* Disable echo cancellation if appropriate */ 03155 zt_disable_ec(p0); 03156 zt_disable_ec(p1); 03157 } 03158 } 03159 zt_link(slave, master); 03160 master->inconference = inconf; 03161 } else if (!nothingok) 03162 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03163 03164 update_conf(p0); 03165 update_conf(p1); 03166 t0 = p0->subs[SUB_REAL].inthreeway; 03167 t1 = p1->subs[SUB_REAL].inthreeway; 03168 03169 ast_mutex_unlock(&p0->lock); 03170 ast_mutex_unlock(&p1->lock); 03171 03172 ast_mutex_unlock(&c0->lock); 03173 ast_mutex_unlock(&c1->lock); 03174 03175 /* Native bridge failed */ 03176 if ((!master || !slave) && !nothingok) { 03177 zt_enable_ec(p0); 03178 zt_enable_ec(p1); 03179 return AST_BRIDGE_FAILED; 03180 } 03181 03182 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03183 disable_dtmf_detect(op0); 03184 03185 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03186 disable_dtmf_detect(op1); 03187 03188 for (;;) { 03189 struct ast_channel *c0_priority[2] = {c0, c1}; 03190 struct ast_channel *c1_priority[2] = {c1, c0}; 03191 03192 /* Here's our main loop... Start by locking things, looking for private parts, 03193 and then balking if anything is wrong */ 03194 ast_mutex_lock(&c0->lock); 03195 ast_mutex_lock(&c1->lock); 03196 p0 = c0->tech_pvt; 03197 p1 = c1->tech_pvt; 03198 03199 if (op0 == p0) 03200 i0 = zt_get_index(c0, p0, 1); 03201 if (op1 == p1) 03202 i1 = zt_get_index(c1, p1, 1); 03203 ast_mutex_unlock(&c0->lock); 03204 ast_mutex_unlock(&c1->lock); 03205 03206 if (!timeoutms || 03207 (op0 != p0) || 03208 (op1 != p1) || 03209 (ofd0 != c0->fds[0]) || 03210 (ofd1 != c1->fds[0]) || 03211 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03212 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03213 (oc0 != p0->owner) || 03214 (oc1 != p1->owner) || 03215 (t0 != p0->subs[SUB_REAL].inthreeway) || 03216 (t1 != p1->subs[SUB_REAL].inthreeway) || 03217 (oi0 != i0) || 03218 (oi1 != i1)) { 03219 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03220 op0->channel, oi0, op1->channel, oi1); 03221 res = AST_BRIDGE_RETRY; 03222 goto return_from_bridge; 03223 } 03224 03225 #ifdef PRI_2BCT 03226 q931c0 = p0->call; 03227 q931c1 = p1->call; 03228 if (p0->transfer && p1->transfer 03229 && q931c0 && q931c1 03230 && !triedtopribridge) { 03231 pri_channel_bridge(q931c0, q931c1); 03232 triedtopribridge = 1; 03233 } 03234 #endif 03235 03236 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03237 if (!who) { 03238 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03239 continue; 03240 } 03241 f = ast_read(who); 03242 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03243 *fo = f; 03244 *rc = who; 03245 res = AST_BRIDGE_COMPLETE; 03246 goto return_from_bridge; 03247 } 03248 if (f->frametype == AST_FRAME_DTMF) { 03249 if ((who == c0) && p0->pulsedial) { 03250 ast_write(c1, f); 03251 } else if ((who == c1) && p1->pulsedial) { 03252 ast_write(c0, f); 03253 } else { 03254 *fo = f; 03255 *rc = who; 03256 res = AST_BRIDGE_COMPLETE; 03257 goto return_from_bridge; 03258 } 03259 } 03260 ast_frfree(f); 03261 03262 /* Swap who gets priority */ 03263 priority = !priority; 03264 } 03265 03266 return_from_bridge: 03267 if (op0 == p0) 03268 zt_enable_ec(p0); 03269 03270 if (op1 == p1) 03271 zt_enable_ec(p1); 03272 03273 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03274 enable_dtmf_detect(op0); 03275 03276 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03277 enable_dtmf_detect(op1); 03278 03279 zt_unlink(slave, master, 1); 03280 03281 return res; 03282 }
static int zt_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 1747 of file chan_zap.c.
References ast_channel::_state, ast_callerid_generate(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::callwaitrings, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, zt_pvt::finaldial, free, zt_pvt::hidecallerid, IS_DIGITAL, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_pvt::law, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, malloc, MAX_CALLERID_SIZE, n, ast_channel::name, zt_subchannel::needbusy, zt_subchannel::needringing, option_verbose, zt_pvt::outgoing, zt_pvt::owner, pbx_builtin_getvar_helper(), zt_pvt::priexclusive, zt_pvt::pulse, zt_pvt::radio, zt_pvt::rxgain, s, send_callerid(), zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::stripmsd, SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, ast_channel::transfercapability, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_subchannel::zfd, zt_callwait(), and zt_get_index().
01748 { 01749 struct zt_pvt *p = ast->tech_pvt; 01750 int x, res, index; 01751 char *c, *n, *l; 01752 #ifdef ZAPATA_PRI 01753 char *s=NULL; 01754 #endif 01755 char dest[256]; /* must be same length as p->dialdest */ 01756 ast_mutex_lock(&p->lock); 01757 ast_copy_string(dest, rdest, sizeof(dest)); 01758 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01759 if ((ast->_state == AST_STATE_BUSY)) { 01760 p->subs[SUB_REAL].needbusy = 1; 01761 ast_mutex_unlock(&p->lock); 01762 return 0; 01763 } 01764 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01765 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01766 ast_mutex_unlock(&p->lock); 01767 return -1; 01768 } 01769 p->dialednone = 0; 01770 if (p->radio) /* if a radio channel, up immediately */ 01771 { 01772 /* Special pseudo -- automatically up */ 01773 ast_setstate(ast, AST_STATE_UP); 01774 ast_mutex_unlock(&p->lock); 01775 return 0; 01776 } 01777 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01778 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01779 if (res) 01780 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01781 p->outgoing = 1; 01782 01783 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01784 01785 switch(p->sig) { 01786 case SIG_FXOLS: 01787 case SIG_FXOGS: 01788 case SIG_FXOKS: 01789 if (p->owner == ast) { 01790 /* Normal ring, on hook */ 01791 01792 /* Don't send audio while on hook, until the call is answered */ 01793 p->dialing = 1; 01794 if (p->use_callerid) { 01795 /* Generate the Caller-ID spill if desired */ 01796 if (p->cidspill) { 01797 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01798 free(p->cidspill); 01799 } 01800 p->cidspill = malloc(MAX_CALLERID_SIZE); 01801 p->callwaitcas = 0; 01802 if (p->cidspill) { 01803 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 01804 p->cidpos = 0; 01805 send_callerid(p); 01806 } else 01807 ast_log(LOG_WARNING, "Unable to generate CallerID spill\n"); 01808 } 01809 /* Choose proper cadence */ 01810 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 01811 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering-1])) 01812 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 01813 p->cidrings = cidrings[p->distinctivering - 1]; 01814 } else { 01815 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 01816 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 01817 p->cidrings = p->sendcalleridafter; 01818 } 01819 01820 01821 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 01822 c = strchr(dest, '/'); 01823 if (c) 01824 c++; 01825 if (c && (strlen(c) < p->stripmsd)) { 01826 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01827 c = NULL; 01828 } 01829 if (c) { 01830 p->dop.op = ZT_DIAL_OP_REPLACE; 01831 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 01832 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 01833 } else { 01834 p->dop.dialstr[0] = '\0'; 01835 } 01836 x = ZT_RING; 01837 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 01838 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 01839 ast_mutex_unlock(&p->lock); 01840 return -1; 01841 } 01842 p->dialing = 1; 01843 } else { 01844 /* Call waiting call */ 01845 p->callwaitrings = 0; 01846 if (ast->cid.cid_num) 01847 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 01848 else 01849 p->callwait_num[0] = '\0'; 01850 if (ast->cid.cid_name) 01851 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 01852 else 01853 p->callwait_name[0] = '\0'; 01854 /* Call waiting tone instead */ 01855 if (zt_callwait(ast)) { 01856 ast_mutex_unlock(&p->lock); 01857 return -1; 01858 } 01859 /* Make ring-back */ 01860 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 01861 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 01862 01863 } 01864 n = ast->cid.cid_name; 01865 l = ast->cid.cid_num; 01866 if (l) 01867 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 01868 else 01869 p->lastcid_num[0] = '\0'; 01870 if (n) 01871 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 01872 else 01873 p->lastcid_name[0] = '\0'; 01874 ast_setstate(ast, AST_STATE_RINGING); 01875 index = zt_get_index(ast, p, 0); 01876 if (index > -1) { 01877 p->subs[index].needringing = 1; 01878 } 01879 break; 01880 case SIG_FXSLS: 01881 case SIG_FXSGS: 01882 case SIG_FXSKS: 01883 case SIG_EMWINK: 01884 case SIG_EM: 01885 case SIG_EM_E1: 01886 case SIG_FEATD: 01887 case SIG_FEATDMF: 01888 case SIG_E911: 01889 case SIG_FEATB: 01890 case SIG_SFWINK: 01891 case SIG_SF: 01892 case SIG_SF_FEATD: 01893 case SIG_SF_FEATDMF: 01894 case SIG_FEATDMF_TA: 01895 case SIG_SF_FEATB: 01896 c = strchr(dest, '/'); 01897 if (c) 01898 c++; 01899 else 01900 c = ""; 01901 if (strlen(c) < p->stripmsd) { 01902 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01903 ast_mutex_unlock(&p->lock); 01904 return -1; 01905 } 01906 #ifdef ZAPATA_PRI 01907 /* Start the trunk, if not GR-303 */ 01908 if (!p->pri) { 01909 #endif 01910 x = ZT_START; 01911 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 01912 if (res < 0) { 01913 if (errno != EINPROGRESS) { 01914 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 01915 ast_mutex_unlock(&p->lock); 01916 return -1; 01917 } 01918 } 01919 #ifdef ZAPATA_PRI 01920 } 01921 #endif 01922 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 01923 p->dop.op = ZT_DIAL_OP_REPLACE; 01924 01925 c += p->stripmsd; 01926 01927 switch (p->sig) { 01928 case SIG_FEATD: 01929 l = ast->cid.cid_num; 01930 if (l) 01931 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 01932 else 01933 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 01934 break; 01935 case SIG_FEATDMF: 01936 l = ast->cid.cid_num; 01937 if (l) 01938 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 01939 else 01940 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 01941 break; 01942 case SIG_FEATDMF_TA: 01943 { 01944 char *cic = NULL, *ozz = NULL; 01945 01946 /* If you have to go through a Tandem Access point you need to use this */ 01947 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 01948 if (!ozz) 01949 ozz = defaultozz; 01950 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 01951 if (!cic) 01952 cic = defaultcic; 01953 if (!ozz || !cic) { 01954 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 01955 ast_mutex_unlock(&p->lock); 01956 return -1; 01957 } 01958 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 01959 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 01960 p->whichwink = 0; 01961 } 01962 break; 01963 case SIG_E911: 01964 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 01965 break; 01966 case SIG_FEATB: 01967 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 01968 break; 01969 default: 01970 if (p->pulse) 01971 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 01972 else 01973 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 01974 break; 01975 } 01976 01977 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 01978 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 01979 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 01980 p->echorest[sizeof(p->echorest) - 1] = '\0'; 01981 p->echobreak = 1; 01982 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 01983 } else 01984 p->echobreak = 0; 01985 if (!res) { 01986 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 01987 x = ZT_ONHOOK; 01988 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 01989 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 01990 ast_mutex_unlock(&p->lock); 01991 return -1; 01992 } 01993 } else 01994 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 01995 p->dialing = 1; 01996 if (ast_strlen_zero(c)) 01997 p->dialednone = 1; 01998 ast_setstate(ast, AST_STATE_DIALING); 01999 break; 02000 case 0: 02001 /* Special pseudo -- automatically up*/ 02002 ast_setstate(ast, AST_STATE_UP); 02003 break; 02004 case SIG_PRI: 02005 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02006 p->dialdest[0] = '\0'; 02007 break; 02008 default: 02009 ast_log(LOG_DEBUG, "not yet implemented\n"); 02010 ast_mutex_unlock(&p->lock); 02011 return -1; 02012 } 02013 #ifdef ZAPATA_PRI 02014 if (p->pri) { 02015 struct pri_sr *sr; 02016 #ifdef SUPPORT_USERUSER 02017 char *useruser; 02018 #endif 02019 int pridialplan; 02020 int dp_strip; 02021 int prilocaldialplan; 02022 int ldp_strip; 02023 int exclusive; 02024 02025 c = strchr(dest, '/'); 02026 if (c) 02027 c++; 02028 else 02029 c = dest; 02030 if (!p->hidecallerid) { 02031 l = ast->cid.cid_num; 02032 n = ast->cid.cid_name; 02033 } else { 02034 l = NULL; 02035 n = NULL; 02036 } 02037 if (strlen(c) < p->stripmsd) { 02038 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02039 ast_mutex_unlock(&p->lock); 02040 return -1; 02041 } 02042 if (p->sig != SIG_FXSKS) { 02043 p->dop.op = ZT_DIAL_OP_REPLACE; 02044 s = strchr(c + p->stripmsd, 'w'); 02045 if (s) { 02046 if (strlen(s) > 1) 02047 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02048 else 02049 p->dop.dialstr[0] = '\0'; 02050 *s = '\0'; 02051 } else { 02052 p->dop.dialstr[0] = '\0'; 02053 } 02054 } 02055 if (pri_grab(p, p->pri)) { 02056 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02057 ast_mutex_unlock(&p->lock); 02058 return -1; 02059 } 02060 if (!(p->call = pri_new_call(p->pri->pri))) { 02061 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02062 pri_rel(p->pri); 02063 ast_mutex_unlock(&p->lock); 02064 return -1; 02065 } 02066 if (!(sr = pri_sr_new())) { 02067 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02068 pri_rel(p->pri); 02069 ast_mutex_unlock(&p->lock); 02070 } 02071 if (p->bearer || (p->sig == SIG_FXSKS)) { 02072 if (p->bearer) { 02073 ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel); 02074 p->bearer->call = p->call; 02075 } else 02076 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02077 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02078 } 02079 p->digital = IS_DIGITAL(ast->transfercapability); 02080 /* Add support for exclusive override */ 02081 if (p->priexclusive) 02082 exclusive = 1; 02083 else { 02084 /* otherwise, traditional behavior */ 02085 if (p->pri->nodetype == PRI_NETWORK) 02086 exclusive = 0; 02087 else 02088 exclusive = 1; 02089 } 02090 02091 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02092 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02093 (p->digital ? -1 : 02094 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); 02095 if (p->pri->facilityenable) 02096 pri_facility_enable(p->pri->pri); 02097 02098 if (option_verbose > 2) 02099 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02100 dp_strip = 0; 02101 pridialplan = p->pri->dialplan - 1; 02102 if (pridialplan == -2) { /* compute dynamically */ 02103 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02104 dp_strip = strlen(p->pri->internationalprefix); 02105 pridialplan = PRI_INTERNATIONAL_ISDN; 02106 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02107 dp_strip = strlen(p->pri->nationalprefix); 02108 pridialplan = PRI_NATIONAL_ISDN; 02109 } else { 02110 pridialplan = PRI_LOCAL_ISDN; 02111 } 02112 } 02113 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02114 02115 ldp_strip = 0; 02116 prilocaldialplan = p->pri->localdialplan - 1; 02117 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02118 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02119 ldp_strip = strlen(p->pri->internationalprefix); 02120 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02121 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02122 ldp_strip = strlen(p->pri->nationalprefix); 02123 prilocaldialplan = PRI_NATIONAL_ISDN; 02124 } else { 02125 prilocaldialplan = PRI_LOCAL_ISDN; 02126 } 02127 } 02128 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02129 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02130 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL); 02131 02132 #ifdef SUPPORT_USERUSER 02133 /* User-user info */ 02134 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02135 02136 if (useruser) 02137 pri_sr_set_useruser(sr, useruser); 02138 #endif 02139 02140 if (pri_setup(p->pri->pri, p->call, sr)) { 02141 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02142 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02143 pri_rel(p->pri); 02144 ast_mutex_unlock(&p->lock); 02145 pri_sr_free(sr); 02146 return -1; 02147 } 02148 pri_sr_free(sr); 02149 ast_setstate(ast, AST_STATE_DIALING); 02150 pri_rel(p->pri); 02151 } 02152 #endif 02153 ast_mutex_unlock(&p->lock); 02154 return 0; 02155 }
static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1716 of file chan_zap.c.
References ast_gen_cas(), AST_LAW, ast_log(), zt_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, zt_pvt::callwaitingcallerid, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, LOG_WARNING, malloc, READ_SIZE, save_conference(), send_callerid(), and ast_channel::tech_pvt.
Referenced by zt_call(), and zt_read().
01717 { 01718 struct zt_pvt *p = ast->tech_pvt; 01719 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01720 if (p->cidspill) { 01721 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01722 free(p->cidspill); 01723 } 01724 p->cidspill = malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4); 01725 if (p->cidspill) { 01726 save_conference(p); 01727 /* Silence */ 01728 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01729 if (!p->callwaitrings && p->callwaitingcallerid) { 01730 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01731 p->callwaitcas = 1; 01732 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01733 } else { 01734 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01735 p->callwaitcas = 0; 01736 p->cidlen = 2400 + READ_SIZE * 4; 01737 } 01738 p->cidpos = 0; 01739 send_callerid(p); 01740 } else { 01741 ast_log(LOG_WARNING, "Unable to create SAS/CAS spill\n"); 01742 return -1; 01743 } 01744 return 0; 01745 }
static void zt_close | ( | int | fd | ) | [static] |
Definition at line 930 of file chan_zap.c.
Referenced by __unload_module(), alloc_sub(), destroy_channel(), mkintf(), and unalloc_sub().
static int zt_confmute | ( | struct zt_pvt * | p, | |
int | muted | |||
) | [inline, static] |
Definition at line 1597 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, and zt_pvt::subs.
Referenced by zt_handle_event(), zt_hangup(), zt_new(), and zt_read().
01598 { 01599 int x, y, res; 01600 x = muted; 01601 if (p->sig == SIG_PRI) { 01602 y = 1; 01603 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01604 if (res) 01605 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01606 } 01607 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01608 if (res < 0) 01609 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01610 return res; 01611 }
static int zt_digit | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1018 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DIALING, zt_pvt::dialdest, zt_pvt::dialing, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, and zt_get_index().
01019 { 01020 ZT_DIAL_OPERATION zo; 01021 struct zt_pvt *p; 01022 int res = 0; 01023 int index; 01024 p = ast->tech_pvt; 01025 ast_mutex_lock(&p->lock); 01026 index = zt_get_index(ast, p, 0); 01027 if ((index == SUB_REAL) && p->owner) { 01028 #ifdef ZAPATA_PRI 01029 if ((p->sig == SIG_PRI) && (ast->_state == AST_STATE_DIALING) && !p->proceeding) { 01030 if (p->setup_ack) { 01031 if (!pri_grab(p, p->pri)) { 01032 pri_information(p->pri->pri,p->call,digit); 01033 pri_rel(p->pri); 01034 } else 01035 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 01036 } else if (strlen(p->dialdest) < sizeof(p->dialdest) - 1) { 01037 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01038 res = strlen(p->dialdest); 01039 p->dialdest[res++] = digit; 01040 p->dialdest[res] = '\0'; 01041 } 01042 } else { 01043 #else 01044 { 01045 #endif 01046 zo.op = ZT_DIAL_OP_APPEND; 01047 zo.dialstr[0] = 'T'; 01048 zo.dialstr[1] = digit; 01049 zo.dialstr[2] = 0; 01050 if ((res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01051 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01052 else 01053 p->dialing = 1; 01054 } 01055 } 01056 ast_mutex_unlock(&p->lock); 01057 return res; 01058 }
static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1433 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, SUB_REAL, and zt_pvt::subs.
Referenced by __zt_exception(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01434 { 01435 int x; 01436 int res; 01437 if (p->echocancel) { 01438 x = 0; 01439 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01440 if (res) 01441 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01442 else 01443 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01444 } 01445 p->echocanon = 0; 01446 }
static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1384 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, and zt_pvt::subs.
Referenced by handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), and zt_handle_event().
01385 { 01386 int x; 01387 int res; 01388 if (!p) 01389 return; 01390 if (p->echocanon) { 01391 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01392 return; 01393 } 01394 if (p->digital) { 01395 ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n"); 01396 return; 01397 } 01398 if (p->echocancel) { 01399 if (p->sig == SIG_PRI) { 01400 x = 1; 01401 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01402 if (res) 01403 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01404 } 01405 x = p->echocancel; 01406 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01407 if (res) 01408 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01409 else { 01410 p->echocanon = 1; 01411 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01412 } 01413 } else 01414 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01415 }
struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) |
Definition at line 4370 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, and ast_channel::tech_pvt.
04371 { 04372 struct zt_pvt *p = ast->tech_pvt; 04373 struct ast_frame *f; 04374 ast_mutex_lock(&p->lock); 04375 f = __zt_exception(ast); 04376 ast_mutex_unlock(&p->lock); 04377 return f; 04378 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3284 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, ast_channel::name, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, and zt_unlink().
03285 { 03286 struct zt_pvt *p = newchan->tech_pvt; 03287 int x; 03288 ast_mutex_lock(&p->lock); 03289 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03290 if (p->owner == oldchan) { 03291 p->owner = newchan; 03292 } 03293 for (x=0;x<3;x++) 03294 if (p->subs[x].owner == oldchan) { 03295 if (!x) 03296 zt_unlink(NULL, p, 0); 03297 p->subs[x].owner = newchan; 03298 } 03299 if (newchan->_state == AST_STATE_RINGING) 03300 zt_indicate(newchan, AST_CONTROL_RINGING); 03301 update_conf(p); 03302 ast_mutex_unlock(&p->lock); 03303 return 0; 03304 }
static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 361 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
static int zt_get_history | ( | int | fd, | |
void * | buf, | |||
int | buf_size | |||
) | [static] |
Definition at line 955 of file chan_zap.c.
Referenced by ss_thread().
00956 { 00957 struct zt_history hist; 00958 hist.buf=buf; 00959 hist.len=buf_size; 00960 return ioctl(fd, ZT_GET_HISTORY, &hist); 00961 }
static int zt_get_index | ( | struct ast_channel * | ast, | |
struct zt_pvt * | p, | |||
int | nullok | |||
) | [static] |
Definition at line 780 of file chan_zap.c.
References ast_log(), LOG_WARNING, zt_subchannel::owner, and zt_pvt::subs.
Referenced by __zt_exception(), ss_thread(), zt_answer(), zt_bridge(), zt_call(), zt_digit(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), zt_sendtext(), zt_setoption(), and zt_write().
00781 { 00782 int res; 00783 if (p->subs[0].owner == ast) 00784 res = 0; 00785 else if (p->subs[1].owner == ast) 00786 res = 1; 00787 else if (p->subs[2].owner == ast) 00788 res = 2; 00789 else { 00790 res = -1; 00791 if (!nullok) 00792 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00793 } 00794 return res; 00795 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3518 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_hangup(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callwaitcas, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, zt_pvt::cid_num, ast_callerid::cid_num, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, zt_pvt::dialdest, zt_pvt::dialing, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, ast_channel::lock, zt_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::msgstate, ast_channel::name, zt_subchannel::needflash, ast_frame::offset, zt_pvt::onhooktime, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::overlapdial, zt_subchannel::owner, zt_pvt::owner, ast_channel::pbx, zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, zt_pvt::polaritydelaytv, zt_pvt::polarityonanswerdelay, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, ast_frame::samples, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), strdup, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::threewaycalling, zt_pvt::transfer, zt_pvt::transfertobusy, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_enable_ec(), ZT_EVENT_DTMFDOWN, ZT_EVENT_DTMFUP, zt_get_event(), zt_get_index(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().
Referenced by __zt_exception().
03519 { 03520 int res,x; 03521 int index; 03522 char *c; 03523 struct zt_pvt *p = ast->tech_pvt; 03524 pthread_t threadid; 03525 pthread_attr_t attr; 03526 struct ast_channel *chan; 03527 03528 pthread_attr_init(&attr); 03529 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 03530 03531 index = zt_get_index(ast, p, 0); 03532 p->subs[index].f.frametype = AST_FRAME_NULL; 03533 p->subs[index].f.datalen = 0; 03534 p->subs[index].f.samples = 0; 03535 p->subs[index].f.mallocd = 0; 03536 p->subs[index].f.offset = 0; 03537 p->subs[index].f.src = "zt_handle_event"; 03538 p->subs[index].f.data = NULL; 03539 if (index < 0) 03540 return &p->subs[index].f; 03541 if (p->fake_event) { 03542 res = p->fake_event; 03543 p->fake_event = 0; 03544 } else 03545 res = zt_get_event(p->subs[index].zfd); 03546 03547 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03548 03549 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03550 if (res & ZT_EVENT_PULSEDIGIT) 03551 p->pulsedial = 1; 03552 else 03553 p->pulsedial = 0; 03554 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03555 #ifdef ZAPATA_PRI 03556 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03557 p->subs[index].f.frametype = AST_FRAME_NULL; 03558 p->subs[index].f.subclass = 0; 03559 } else { 03560 #endif 03561 p->subs[index].f.frametype = AST_FRAME_DTMF; 03562 p->subs[index].f.subclass = res & 0xff; 03563 #ifdef ZAPATA_PRI 03564 } 03565 #endif 03566 /* Unmute conference, return the captured digit */ 03567 zt_confmute(p, 0); 03568 return &p->subs[index].f; 03569 } 03570 03571 if (res & ZT_EVENT_DTMFDOWN) { 03572 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03573 p->subs[index].f.frametype = AST_FRAME_NULL; 03574 p->subs[index].f.subclass = 0; 03575 zt_confmute(p, 1); 03576 /* Mute conference, return null frame */ 03577 return &p->subs[index].f; 03578 } 03579 03580 switch(res) { 03581 case ZT_EVENT_BITSCHANGED: 03582 if (p->sig == SIG_R2) { 03583 #ifdef ZAPATA_R2 03584 struct ast_frame *f = &p->subs[index].f; 03585 mfcr2_event_t *e; 03586 e = r2_get_event_bits(p); 03587 if (e) 03588 f = handle_r2_event(p, e, index); 03589 return f; 03590 #else 03591 break; 03592 #endif 03593 } 03594 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03595 case ZT_EVENT_PULSE_START: 03596 /* Stop tone if there's a pulse start and the PBX isn't started */ 03597 if (!ast->pbx) 03598 tone_zone_play_tone(p->subs[index].zfd, -1); 03599 break; 03600 case ZT_EVENT_DIALCOMPLETE: 03601 if (p->inalarm) break; 03602 if (p->radio) break; 03603 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03604 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03605 return NULL; 03606 } 03607 if (!x) { /* if not still dialing in driver */ 03608 zt_enable_ec(p); 03609 if (p->echobreak) { 03610 zt_train_ec(p); 03611 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03612 p->dop.op = ZT_DIAL_OP_REPLACE; 03613 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03614 p->echobreak = 0; 03615 } else { 03616 p->dialing = 0; 03617 if (p->sig == SIG_E911) { 03618 /* if thru with dialing after offhook */ 03619 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03620 ast_setstate(ast, AST_STATE_UP); 03621 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03622 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03623 break; 03624 } else { /* if to state wait for offhook to dial rest */ 03625 /* we now wait for off hook */ 03626 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03627 } 03628 } 03629 if (ast->_state == AST_STATE_DIALING) { 03630 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03631 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03632 } else if (p->confirmanswer || (!p->dialednone && ((p->sig == SIG_EM) || (p->sig == SIG_EM_E1) || (p->sig == SIG_EMWINK) || (p->sig == SIG_FEATD) || (p->sig == SIG_FEATDMF) || (p->sig == SIG_E911) || (p->sig == SIG_FEATB) || (p->sig == SIG_SF) || (p->sig == SIG_SFWINK) || (p->sig == SIG_SF_FEATD) || (p->sig == SIG_SF_FEATDMF) || (p->sig == SIG_SF_FEATB)))) { 03633 ast_setstate(ast, AST_STATE_RINGING); 03634 } else if (!p->answeronpolarityswitch) { 03635 ast_setstate(ast, AST_STATE_UP); 03636 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03637 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03638 } 03639 } 03640 } 03641 } 03642 break; 03643 case ZT_EVENT_ALARM: 03644 #ifdef ZAPATA_PRI 03645 if (p->call) { 03646 if (p->pri && p->pri->pri) { 03647 if (!pri_grab(p, p->pri)) { 03648 pri_hangup(p->pri->pri, p->call, -1); 03649 pri_destroycall(p->pri->pri, p->call); 03650 p->call = NULL; 03651 pri_rel(p->pri); 03652 } else 03653 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03654 } else 03655 ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n"); 03656 } 03657 if (p->owner) 03658 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03659 if (p->bearer) 03660 p->bearer->inalarm = 1; 03661 else 03662 #endif 03663 p->inalarm = 1; 03664 res = get_alarms(p); 03665 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res)); 03666 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 03667 "Alarm: %s\r\n" 03668 "Channel: %d\r\n", 03669 alarm2str(res), p->channel); 03670 /* fall through intentionally */ 03671 case ZT_EVENT_ONHOOK: 03672 if (p->radio) 03673 { 03674 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03675 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 03676 break; 03677 } 03678 switch(p->sig) { 03679 case SIG_FXOLS: 03680 case SIG_FXOGS: 03681 case SIG_FXOKS: 03682 p->onhooktime = time(NULL); 03683 p->msgstate = -1; 03684 /* Check for some special conditions regarding call waiting */ 03685 if (index == SUB_REAL) { 03686 /* The normal line was hung up */ 03687 if (p->subs[SUB_CALLWAIT].owner) { 03688 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 03689 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 03690 if (option_verbose > 2) 03691 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 03692 unalloc_sub(p, SUB_CALLWAIT); 03693 #if 0 03694 p->subs[index].needanswer = 0; 03695 p->subs[index].needringing = 0; 03696 #endif 03697 p->callwaitingrepeat = 0; 03698 p->cidcwexpire = 0; 03699 p->owner = NULL; 03700 /* Don't start streaming audio yet if the incoming call isn't up yet */ 03701 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 03702 p->dialing = 1; 03703 zt_ring_phone(p); 03704 } else if (p->subs[SUB_THREEWAY].owner) { 03705 unsigned int mssinceflash; 03706 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 03707 the private structure -- not especially easy or clean */ 03708 while(p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 03709 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 03710 ast_mutex_unlock(&p->lock); 03711 ast_mutex_unlock(&ast->lock); 03712 usleep(1); 03713 /* We can grab ast and p in that order, without worry. We should make sure 03714 nothing seriously bad has happened though like some sort of bizarre double 03715 masquerade! */ 03716 ast_mutex_lock(&ast->lock); 03717 ast_mutex_lock(&p->lock); 03718 if (p->owner != ast) { 03719 ast_log(LOG_WARNING, "This isn't good...\n"); 03720 return NULL; 03721 } 03722 } 03723 if (!p->subs[SUB_THREEWAY].owner) { 03724 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 03725 return NULL; 03726 } 03727 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 03728 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 03729 if (mssinceflash < MIN_MS_SINCE_FLASH) { 03730 /* It hasn't been long enough since the last flashook. This is probably a bounce on 03731 hanging up. Hangup both channels now */ 03732 if (p->subs[SUB_THREEWAY].owner) 03733 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 03734 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03735 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 03736 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03737 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 03738 if (p->transfer) { 03739 /* In any case this isn't a threeway call anymore */ 03740 p->subs[SUB_REAL].inthreeway = 0; 03741 p->subs[SUB_THREEWAY].inthreeway = 0; 03742 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 03743 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 03744 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03745 /* Swap subs and dis-own channel */ 03746 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03747 p->owner = NULL; 03748 /* Ring the phone */ 03749 zt_ring_phone(p); 03750 } else { 03751 if ((res = attempt_transfer(p)) < 0) { 03752 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03753 if (p->subs[SUB_THREEWAY].owner) 03754 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03755 } else if (res) { 03756 /* Don't actually hang up at this point */ 03757 if (p->subs[SUB_THREEWAY].owner) 03758 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03759 break; 03760 } 03761 } 03762 } else { 03763 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03764 if (p->subs[SUB_THREEWAY].owner) 03765 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03766 } 03767 } else { 03768 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03769 /* Swap subs and dis-own channel */ 03770 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03771 p->owner = NULL; 03772 /* Ring the phone */ 03773 zt_ring_phone(p); 03774 } 03775 } 03776 } else { 03777 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 03778 } 03779 /* Fall through */ 03780 default: 03781 zt_disable_ec(p); 03782 return NULL; 03783 } 03784 break; 03785 case ZT_EVENT_RINGOFFHOOK: 03786 if (p->inalarm) break; 03787 if (p->radio) 03788 { 03789 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03790 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 03791 break; 03792 } 03793 /* for E911, its supposed to wait for offhook then dial 03794 the second half of the dial string */ 03795 if ((p->sig == SIG_E911) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 03796 c = strchr(p->dialdest, '/'); 03797 if (c) 03798 c++; 03799 else 03800 c = p->dialdest; 03801 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 03802 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 03803 if (strlen(p->dop.dialstr) > 4) { 03804 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 03805 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 03806 p->echorest[sizeof(p->echorest) - 1] = '\0'; 03807 p->echobreak = 1; 03808 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 03809 } else 03810 p->echobreak = 0; 03811 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 03812 x = ZT_ONHOOK; 03813 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03814 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 03815 return NULL; 03816 } 03817 p->dialing = 1; 03818 return &p->subs[index].f; 03819 } 03820 switch(p->sig) { 03821 case SIG_FXOLS: 03822 case SIG_FXOGS: 03823 case SIG_FXOKS: 03824 switch(ast->_state) { 03825 case AST_STATE_RINGING: 03826 zt_enable_ec(p); 03827 zt_train_ec(p); 03828 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03829 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03830 /* Make sure it stops ringing */ 03831 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 03832 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 03833 if (p->cidspill) { 03834 /* Cancel any running CallerID spill */ 03835 free(p->cidspill); 03836 p->cidspill = NULL; 03837 } 03838 p->dialing = 0; 03839 p->callwaitcas = 0; 03840 if (p->confirmanswer) { 03841 /* Ignore answer if "confirm answer" is enabled */ 03842 p->subs[index].f.frametype = AST_FRAME_NULL; 03843 p->subs[index].f.subclass = 0; 03844 } else if (!ast_strlen_zero(p->dop.dialstr)) { 03845 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 03846 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03847 if (res < 0) { 03848 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 03849 p->dop.dialstr[0] = '\0'; 03850 return NULL; 03851 } else { 03852 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 03853 p->subs[index].f.frametype = AST_FRAME_NULL; 03854 p->subs[index].f.subclass = 0; 03855 p->dialing = 1; 03856 } 03857 p->dop.dialstr[0] = '\0'; 03858 ast_setstate(ast, AST_STATE_DIALING); 03859 } else 03860 ast_setstate(ast, AST_STATE_UP); 03861 return &p->subs[index].f; 03862 case AST_STATE_DOWN: 03863 ast_setstate(ast, AST_STATE_RING); 03864 ast->rings = 1; 03865 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03866 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 03867 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 03868 return &p->subs[index].f; 03869 case AST_STATE_UP: 03870 /* Make sure it stops ringing */ 03871 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 03872 /* Okay -- probably call waiting*/ 03873 if (ast_bridged_channel(p->owner)) 03874 ast_moh_stop(ast_bridged_channel(p->owner)); 03875 break; 03876 case AST_STATE_RESERVED: 03877 /* Start up dialtone */ 03878 if (has_voicemail(p)) 03879 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 03880 else 03881 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 03882 break; 03883 default: 03884 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 03885 } 03886 break; 03887 case SIG_FXSLS: 03888 case SIG_FXSGS: 03889 case SIG_FXSKS: 03890 if (ast->_state == AST_STATE_RING) { 03891 p->ringt = p->ringt_base; 03892 } 03893 03894 /* If we get a ring then we cannot be in 03895 * reversed polarity. So we reset to idle */ 03896 ast_log(LOG_DEBUG, "Setting IDLE polarity due " 03897 "to ring. Old polarity was %d\n", 03898 p->polarity); 03899 p->polarity = POLARITY_IDLE; 03900 03901 /* Fall through */ 03902 case SIG_EM: 03903 case SIG_EM_E1: 03904 case SIG_EMWINK: 03905 case SIG_FEATD: 03906 case SIG_FEATDMF: 03907 case SIG_FEATDMF_TA: 03908 case SIG_E911: 03909 case SIG_FEATB: 03910 case SIG_SF: 03911 case SIG_SFWINK: 03912 case SIG_SF_FEATD: 03913 case SIG_SF_FEATDMF: 03914 case SIG_SF_FEATB: 03915 if (ast->_state == AST_STATE_PRERING) 03916 ast_setstate(ast, AST_STATE_RING); 03917 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 03918 if (option_debug) 03919 ast_log(LOG_DEBUG, "Ring detected\n"); 03920 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03921 p->subs[index].f.subclass = AST_CONTROL_RING; 03922 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 03923 if (option_debug) 03924 ast_log(LOG_DEBUG, "Line answered\n"); 03925 if (p->confirmanswer) { 03926 p->subs[index].f.frametype = AST_FRAME_NULL; 03927 p->subs[index].f.subclass = 0; 03928 } else { 03929 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03930 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03931 ast_setstate(ast, AST_STATE_UP); 03932 } 03933 } else if (ast->_state != AST_STATE_RING) 03934 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 03935 break; 03936 default: 03937 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 03938 } 03939 break; 03940 #ifdef ZT_EVENT_RINGBEGIN 03941 case ZT_EVENT_RINGBEGIN: 03942 switch(p->sig) { 03943 case SIG_FXSLS: 03944 case SIG_FXSGS: 03945 case SIG_FXSKS: 03946 if (ast->_state == AST_STATE_RING) { 03947 p->ringt = p->ringt_base; 03948 } 03949 break; 03950 } 03951 break; 03952 #endif 03953 case ZT_EVENT_RINGEROFF: 03954 if (p->inalarm) break; 03955 if (p->radio) break; 03956 ast->rings++; 03957 if ((ast->rings > p->cidrings) && (p->cidspill)) { 03958 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 03959 free(p->cidspill); 03960 p->cidspill = NULL; 03961 p->callwaitcas = 0; 03962 } 03963 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03964 p->subs[index].f.subclass = AST_CONTROL_RINGING; 03965 break; 03966 case ZT_EVENT_RINGERON: 03967 break; 03968 case ZT_EVENT_NOALARM: 03969 p->inalarm = 0; 03970 #ifdef ZAPATA_PRI 03971 /* Extremely unlikely but just in case */ 03972 if (p->bearer) 03973 p->bearer->inalarm = 0; 03974 #endif 03975 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 03976 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 03977 "Channel: %d\r\n", p->channel); 03978 break; 03979 case ZT_EVENT_WINKFLASH: 03980 if (p->inalarm) break; 03981 if (p->radio) break; 03982 /* Remember last time we got a flash-hook */ 03983 gettimeofday(&p->flashtime, NULL); 03984 switch(p->sig) { 03985 case SIG_FXOLS: 03986 case SIG_FXOGS: 03987 case SIG_FXOKS: 03988 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 03989 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 03990 p->callwaitcas = 0; 03991 03992 if (index != SUB_REAL) { 03993 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 03994 goto winkflashdone; 03995 } 03996 03997 if (p->subs[SUB_CALLWAIT].owner) { 03998 /* Swap to call-wait */ 03999 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04000 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04001 p->owner = p->subs[SUB_REAL].owner; 04002 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04003 if (p->owner->_state == AST_STATE_RINGING) { 04004 ast_setstate(p->owner, AST_STATE_UP); 04005 p->subs[SUB_REAL].needanswer = 1; 04006 } 04007 p->callwaitingrepeat = 0; 04008 p->cidcwexpire = 0; 04009 /* Start music on hold if appropriate */ 04010 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) 04011 ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL); 04012 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 04013 ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner)); 04014 } else if (!p->subs[SUB_THREEWAY].owner) { 04015 char cid_num[256]; 04016 char cid_name[256]; 04017 04018 if (!p->threewaycalling) { 04019 /* Just send a flash if no 3-way calling */ 04020 p->subs[SUB_REAL].needflash = 1; 04021 goto winkflashdone; 04022 } else if (!check_for_conference(p)) { 04023 if (p->zaptrcallerid && p->owner) { 04024 if (p->owner->cid.cid_num) 04025 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04026 if (p->owner->cid.cid_name) 04027 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04028 } 04029 /* XXX This section needs much more error checking!!! XXX */ 04030 /* Start a 3-way call if feasible */ 04031 if (!((ast->pbx) || 04032 (ast->_state == AST_STATE_UP) || 04033 (ast->_state == AST_STATE_RING))) { 04034 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04035 goto winkflashdone; 04036 } 04037 if (alloc_sub(p, SUB_THREEWAY)) { 04038 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04039 goto winkflashdone; 04040 } 04041 /* Make new channel */ 04042 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04043 if (p->zaptrcallerid) { 04044 if (!p->origcid_num) 04045 p->origcid_num = strdup(p->cid_num); 04046 if (!p->origcid_name) 04047 p->origcid_name = strdup(p->cid_name); 04048 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04049 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04050 } 04051 /* Swap things around between the three-way and real call */ 04052 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04053 /* Disable echo canceller for better dialing */ 04054 zt_disable_ec(p); 04055 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04056 if (res) 04057 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04058 p->owner = chan; 04059 if (!chan) { 04060 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04061 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04062 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04063 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04064 zt_enable_ec(p); 04065 ast_hangup(chan); 04066 } else { 04067 if (option_verbose > 2) 04068 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04069 /* Start music on hold if appropriate */ 04070 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 04071 ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL); 04072 } 04073 } 04074 } else { 04075 /* Already have a 3 way call */ 04076 if (p->subs[SUB_THREEWAY].inthreeway) { 04077 /* Call is already up, drop the last person */ 04078 if (option_debug) 04079 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04080 /* If the primary call isn't answered yet, use it */ 04081 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04082 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04083 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04084 p->owner = p->subs[SUB_REAL].owner; 04085 } 04086 /* Drop the last call and stop the conference */ 04087 if (option_verbose > 2) 04088 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04089 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04090 p->subs[SUB_REAL].inthreeway = 0; 04091 p->subs[SUB_THREEWAY].inthreeway = 0; 04092 } else { 04093 /* Lets see what we're up to */ 04094 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04095 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04096 int otherindex = SUB_THREEWAY; 04097 04098 if (option_verbose > 2) 04099 ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name); 04100 /* Put them in the threeway, and flip */ 04101 p->subs[SUB_THREEWAY].inthreeway = 1; 04102 p->subs[SUB_REAL].inthreeway = 1; 04103 if (ast->_state == AST_STATE_UP) { 04104 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04105 otherindex = SUB_REAL; 04106 } 04107 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04108 ast_moh_stop(ast_bridged_channel(p->subs[otherindex].owner)); 04109 p->owner = p->subs[SUB_REAL].owner; 04110 if (ast->_state == AST_STATE_RINGING) { 04111 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04112 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04113 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04114 } 04115 } else { 04116 if (option_verbose > 2) 04117 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04118 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04119 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04120 p->owner = p->subs[SUB_REAL].owner; 04121 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04122 ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner)); 04123 zt_enable_ec(p); 04124 } 04125 04126 } 04127 } 04128 winkflashdone: 04129 update_conf(p); 04130 break; 04131 case SIG_EM: 04132 case SIG_EM_E1: 04133 case SIG_EMWINK: 04134 case SIG_FEATD: 04135 case SIG_SF: 04136 case SIG_SFWINK: 04137 case SIG_SF_FEATD: 04138 case SIG_FXSLS: 04139 case SIG_FXSGS: 04140 if (p->dialing) 04141 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04142 else 04143 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04144 break; 04145 case SIG_FEATDMF_TA: 04146 switch (p->whichwink) { 04147 case 0: 04148 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04149 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04150 break; 04151 case 1: 04152 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04153 break; 04154 case 2: 04155 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04156 return NULL; 04157 } 04158 p->whichwink++; 04159 /* Fall through */ 04160 case SIG_FEATDMF: 04161 case SIG_E911: 04162 case SIG_FEATB: 04163 case SIG_SF_FEATDMF: 04164 case SIG_SF_FEATB: 04165 /* FGD MF *Must* wait for wink */ 04166 if (!ast_strlen_zero(p->dop.dialstr)) 04167 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04168 else if (res < 0) { 04169 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04170 p->dop.dialstr[0] = '\0'; 04171 return NULL; 04172 } else 04173 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04174 p->dop.dialstr[0] = '\0'; 04175 break; 04176 default: 04177 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04178 } 04179 break; 04180 case ZT_EVENT_HOOKCOMPLETE: 04181 if (p->inalarm) break; 04182 if (p->radio) break; 04183 switch(p->sig) { 04184 case SIG_FXSLS: /* only interesting for FXS */ 04185 case SIG_FXSGS: 04186 case SIG_FXSKS: 04187 case SIG_EM: 04188 case SIG_EM_E1: 04189 case SIG_EMWINK: 04190 case SIG_FEATD: 04191 case SIG_SF: 04192 case SIG_SFWINK: 04193 case SIG_SF_FEATD: 04194 if (!ast_strlen_zero(p->dop.dialstr)) 04195 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04196 else if (res < 0) { 04197 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04198 p->dop.dialstr[0] = '\0'; 04199 return NULL; 04200 } else 04201 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04202 p->dop.dialstr[0] = '\0'; 04203 p->dop.op = ZT_DIAL_OP_REPLACE; 04204 break; 04205 case SIG_FEATDMF: 04206 case SIG_E911: 04207 case SIG_FEATB: 04208 case SIG_SF_FEATDMF: 04209 case SIG_SF_FEATB: 04210 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04211 break; 04212 default: 04213 break; 04214 } 04215 break; 04216 case ZT_EVENT_POLARITY: 04217 /* 04218 * If we get a Polarity Switch event, check to see 04219 * if we should change the polarity state and 04220 * mark the channel as UP or if this is an indication 04221 * of remote end disconnect. 04222 */ 04223 if (p->polarity == POLARITY_IDLE) { 04224 p->polarity = POLARITY_REV; 04225 if (p->answeronpolarityswitch && 04226 ((ast->_state == AST_STATE_DIALING) || 04227 (ast->_state == AST_STATE_RINGING))) { 04228 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04229 ast_setstate(p->owner, AST_STATE_UP); 04230 if(p->hanguponpolarityswitch) { 04231 gettimeofday(&p->polaritydelaytv, NULL); 04232 } 04233 break; 04234 } else 04235 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04236 } 04237 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04238 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04239 if(p->hanguponpolarityswitch && 04240 (p->polarityonanswerdelay > 0) && 04241 (p->polarity == POLARITY_REV) && 04242 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04243 /* Added log_debug information below to provide a better indication of what is going on */ 04244 ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 04245 04246 if(ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04247 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04248 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04249 p->polarity = POLARITY_IDLE; 04250 } else { 04251 ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state); 04252 } 04253 } else { 04254 p->polarity = POLARITY_IDLE; 04255 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04256 } 04257 /* Added more log_debug information below to provide a better indication of what is going on */ 04258 ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 04259 break; 04260 default: 04261 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04262 } 04263 return &p->subs[index].f; 04264 }
static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2306 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), ast_channel_setoption(), ast_dsp_digitmode(), ast_dsp_free(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_STATE_RESERVED, AST_STATE_UP, ast_update_use_count(), ast_verbose(), zt_pvt::callwaitcas, zt_pvt::callwaiting, zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, zt_pvt::destroy, destroy_channel(), zt_pvt::dialing, zt_pvt::didtdd, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::exten, zt_pvt::faxhandled, free, zt_pvt::guardtime, ast_channel::hangupcause, zt_pvt::hidecallerid, iflist, zt_pvt::ignoredtmf, zt_subchannel::inthreeway, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, zt_pvt::next, zt_pvt::onhooktime, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_getvar_helper(), zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::prev, zt_pvt::pulsedial, zt_pvt::radio, zt_pvt::rdnis, reset_conf(), restart_monitor(), restore_gains(), zt_pvt::ringt, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_R2, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), usecnt_lock, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().
02307 { 02308 int res; 02309 int index,x, law; 02310 /*static int restore_gains(struct zt_pvt *p);*/ 02311 struct zt_pvt *p = ast->tech_pvt; 02312 struct zt_pvt *tmp = NULL; 02313 struct zt_pvt *prev = NULL; 02314 ZT_PARAMS par; 02315 02316 if (option_debug) 02317 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02318 if (!ast->tech_pvt) { 02319 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02320 return 0; 02321 } 02322 02323 ast_mutex_lock(&p->lock); 02324 02325 index = zt_get_index(ast, p, 1); 02326 02327 if (p->sig == SIG_PRI) { 02328 x = 1; 02329 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02330 } 02331 02332 x = 0; 02333 zt_confmute(p, 0); 02334 restore_gains(p); 02335 if (p->origcid_num) { 02336 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02337 free(p->origcid_num); 02338 p->origcid_num = NULL; 02339 } 02340 if (p->origcid_name) { 02341 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02342 free(p->origcid_name); 02343 p->origcid_name = NULL; 02344 } 02345 if (p->dsp) 02346 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02347 if (p->exten) 02348 p->exten[0] = '\0'; 02349 02350 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02351 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02352 p->ignoredtmf = 0; 02353 02354 if (index > -1) { 02355 /* Real channel, do some fixup */ 02356 p->subs[index].owner = NULL; 02357 p->subs[index].needanswer = 0; 02358 p->subs[index].needflash = 0; 02359 p->subs[index].needringing = 0; 02360 p->subs[index].needbusy = 0; 02361 p->subs[index].needcongestion = 0; 02362 p->subs[index].linear = 0; 02363 p->subs[index].needcallerid = 0; 02364 p->polarity = POLARITY_IDLE; 02365 zt_setlinear(p->subs[index].zfd, 0); 02366 if (index == SUB_REAL) { 02367 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02368 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02369 if (p->subs[SUB_CALLWAIT].inthreeway) { 02370 /* We had flipped over to answer a callwait and now it's gone */ 02371 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02372 /* Move to the call-wait, but un-own us until they flip back. */ 02373 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02374 unalloc_sub(p, SUB_CALLWAIT); 02375 p->owner = NULL; 02376 } else { 02377 /* The three way hung up, but we still have a call wait */ 02378 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02379 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02380 unalloc_sub(p, SUB_THREEWAY); 02381 if (p->subs[SUB_REAL].inthreeway) { 02382 /* This was part of a three way call. Immediately make way for 02383 another call */ 02384 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02385 p->owner = p->subs[SUB_REAL].owner; 02386 } else { 02387 /* This call hasn't been completed yet... Set owner to NULL */ 02388 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02389 p->owner = NULL; 02390 } 02391 p->subs[SUB_REAL].inthreeway = 0; 02392 } 02393 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02394 /* Move to the call-wait and switch back to them. */ 02395 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02396 unalloc_sub(p, SUB_CALLWAIT); 02397 p->owner = p->subs[SUB_REAL].owner; 02398 if (p->owner->_state != AST_STATE_UP) 02399 p->subs[SUB_REAL].needanswer = 1; 02400 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02401 ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner)); 02402 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02403 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02404 unalloc_sub(p, SUB_THREEWAY); 02405 if (p->subs[SUB_REAL].inthreeway) { 02406 /* This was part of a three way call. Immediately make way for 02407 another call */ 02408 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02409 p->owner = p->subs[SUB_REAL].owner; 02410 } else { 02411 /* This call hasn't been completed yet... Set owner to NULL */ 02412 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02413 p->owner = NULL; 02414 } 02415 p->subs[SUB_REAL].inthreeway = 0; 02416 } 02417 } else if (index == SUB_CALLWAIT) { 02418 /* Ditch the holding callwait call, and immediately make it availabe */ 02419 if (p->subs[SUB_CALLWAIT].inthreeway) { 02420 /* This is actually part of a three way, placed on hold. Place the third part 02421 on music on hold now */ 02422 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 02423 ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL); 02424 p->subs[SUB_THREEWAY].inthreeway = 0; 02425 /* Make it the call wait now */ 02426 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02427 unalloc_sub(p, SUB_THREEWAY); 02428 } else 02429 unalloc_sub(p, SUB_CALLWAIT); 02430 } else if (index == SUB_THREEWAY) { 02431 if (p->subs[SUB_CALLWAIT].inthreeway) { 02432 /* The other party of the three way call is currently in a call-wait state. 02433 Start music on hold for them, and take the main guy out of the third call */ 02434 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) 02435 ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL); 02436 p->subs[SUB_CALLWAIT].inthreeway = 0; 02437 } 02438 p->subs[SUB_REAL].inthreeway = 0; 02439 /* If this was part of a three way call index, let us make 02440 another three way call */ 02441 unalloc_sub(p, SUB_THREEWAY); 02442 } else { 02443 /* This wasn't any sort of call, but how are we an index? */ 02444 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02445 } 02446 } 02447 02448 02449 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02450 p->owner = NULL; 02451 p->ringt = 0; 02452 p->distinctivering = 0; 02453 p->confirmanswer = 0; 02454 p->cidrings = 1; 02455 p->outgoing = 0; 02456 p->digital = 0; 02457 p->faxhandled = 0; 02458 p->pulsedial = 0; 02459 p->onhooktime = time(NULL); 02460 #ifdef ZAPATA_PRI 02461 p->proceeding = 0; 02462 p->progress = 0; 02463 p->alerting = 0; 02464 p->setup_ack = 0; 02465 #endif 02466 if (p->dsp) { 02467 ast_dsp_free(p->dsp); 02468 p->dsp = NULL; 02469 } 02470 02471 law = ZT_LAW_DEFAULT; 02472 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02473 if (res < 0) 02474 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02475 /* Perform low level hangup if no owner left */ 02476 #ifdef ZAPATA_PRI 02477 if (p->pri) { 02478 #ifdef SUPPORT_USERUSER 02479 char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02480 #endif 02481 02482 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02483 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02484 if (!pri_grab(p, p->pri)) { 02485 if (p->alreadyhungup) { 02486 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02487 02488 #ifdef SUPPORT_USERUSER 02489 pri_call_set_useruser(p->call, useruser); 02490 #endif 02491 02492 pri_hangup(p->pri->pri, p->call, -1); 02493 p->call = NULL; 02494 if (p->bearer) 02495 p->bearer->call = NULL; 02496 } else { 02497 char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02498 int icause = ast->hangupcause ? ast->hangupcause : -1; 02499 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02500 02501 #ifdef SUPPORT_USERUSER 02502 pri_call_set_useruser(p->call, useruser); 02503 #endif 02504 02505 p->alreadyhungup = 1; 02506 if (p->bearer) 02507 p->bearer->alreadyhungup = 1; 02508 if (cause) { 02509 if (atoi(cause)) 02510 icause = atoi(cause); 02511 } 02512 pri_hangup(p->pri->pri, p->call, icause); 02513 } 02514 if (res < 0) 02515 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02516 pri_rel(p->pri); 02517 } else { 02518 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02519 res = -1; 02520 } 02521 } else { 02522 if (p->bearer) 02523 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02524 p->call = NULL; 02525 res = 0; 02526 } 02527 } 02528 #endif 02529 #ifdef ZAPATA_R2 02530 if (p->sig == SIG_R2) { 02531 if (p->hasr2call) { 02532 mfcr2_DropCall(p->r2, NULL, UC_NORMAL_CLEARING); 02533 p->hasr2call = 0; 02534 res = 0; 02535 } else 02536 res = 0; 02537 02538 } 02539 #endif 02540 if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2)) 02541 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02542 if (res < 0) { 02543 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02544 } 02545 switch(p->sig) { 02546 case SIG_FXOGS: 02547 case SIG_FXOLS: 02548 case SIG_FXOKS: 02549 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02550 if (!res) { 02551 #if 0 02552 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02553 #endif 02554 /* If they're off hook, try playing congestion */ 02555 if ((par.rxisoffhook) && (!p->radio)) 02556 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02557 else 02558 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02559 } 02560 break; 02561 case SIG_FXSGS: 02562 case SIG_FXSLS: 02563 case SIG_FXSKS: 02564 /* Make sure we're not made available for at least two seconds assuming 02565 we were actually used for an inbound or outbound call. */ 02566 if (ast->_state != AST_STATE_RESERVED) { 02567 time(&p->guardtime); 02568 p->guardtime += 2; 02569 } 02570 break; 02571 default: 02572 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02573 } 02574 if (p->cidspill) 02575 free(p->cidspill); 02576 if (p->sig) 02577 zt_disable_ec(p); 02578 x = 0; 02579 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02580 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02581 p->didtdd = 0; 02582 p->cidspill = NULL; 02583 p->callwaitcas = 0; 02584 p->callwaiting = p->permcallwaiting; 02585 p->hidecallerid = p->permhidecallerid; 02586 p->dialing = 0; 02587 p->rdnis[0] = '\0'; 02588 update_conf(p); 02589 reset_conf(p); 02590 /* Restore data mode */ 02591 if (p->sig == SIG_PRI) { 02592 x = 0; 02593 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02594 } 02595 #ifdef ZAPATA_PRI 02596 if (p->bearer) { 02597 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02598 /* Free up the bearer channel as well, and 02599 don't use its file descriptor anymore */ 02600 update_conf(p->bearer); 02601 reset_conf(p->bearer); 02602 p->bearer->owner = NULL; 02603 p->bearer->realcall = NULL; 02604 p->bearer = NULL; 02605 p->subs[SUB_REAL].zfd = -1; 02606 p->pri = NULL; 02607 } 02608 #endif 02609 restart_monitor(); 02610 } 02611 02612 02613 p->callwaitingrepeat = 0; 02614 p->cidcwexpire = 0; 02615 ast->tech_pvt = NULL; 02616 ast_mutex_unlock(&p->lock); 02617 ast_mutex_lock(&usecnt_lock); 02618 usecnt--; 02619 if (usecnt < 0) 02620 ast_log(LOG_WARNING, "Usecnt < 0???\n"); 02621 ast_mutex_unlock(&usecnt_lock); 02622 ast_update_use_count(); 02623 if (option_verbose > 2) 02624 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02625 02626 ast_mutex_lock(&iflock); 02627 tmp = iflist; 02628 prev = NULL; 02629 if (p->destroy) { 02630 while (tmp) { 02631 if (tmp == p) { 02632 destroy_channel(prev, tmp, 0); 02633 break; 02634 } else { 02635 prev = tmp; 02636 tmp = tmp->next; 02637 } 02638 } 02639 } 02640 ast_mutex_unlock(&iflock); 02641 return 0; 02642 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition | |||
) | [static] |
Definition at line 4817 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, zt_pvt::digital, zt_pvt::dop, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, ast_channel::name, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().
04818 { 04819 struct zt_pvt *p = chan->tech_pvt; 04820 int res=-1; 04821 int index; 04822 int func = ZT_FLASH; 04823 ast_mutex_lock(&p->lock); 04824 index = zt_get_index(chan, p, 0); 04825 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 04826 if (index == SUB_REAL) { 04827 switch(condition) { 04828 case AST_CONTROL_BUSY: 04829 #ifdef ZAPATA_PRI 04830 if (p->priindication_oob && p->sig == SIG_PRI) { 04831 chan->hangupcause = AST_CAUSE_USER_BUSY; 04832 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04833 res = 0; 04834 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04835 if (p->pri->pri) { 04836 if (!pri_grab(p, p->pri)) { 04837 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 04838 pri_rel(p->pri); 04839 } 04840 else 04841 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04842 } 04843 p->progress = 1; 04844 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 04845 } else 04846 #endif 04847 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 04848 break; 04849 case AST_CONTROL_RINGING: 04850 #ifdef ZAPATA_PRI 04851 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 04852 if (p->pri->pri) { 04853 if (!pri_grab(p, p->pri)) { 04854 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04855 pri_rel(p->pri); 04856 } 04857 else 04858 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04859 } 04860 p->alerting = 1; 04861 } 04862 #endif 04863 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 04864 if (chan->_state != AST_STATE_UP) { 04865 if ((chan->_state != AST_STATE_RING) || 04866 ((p->sig != SIG_FXSKS) && 04867 (p->sig != SIG_FXSLS) && 04868 (p->sig != SIG_FXSGS))) 04869 ast_setstate(chan, AST_STATE_RINGING); 04870 } 04871 break; 04872 case AST_CONTROL_PROCEEDING: 04873 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 04874 #ifdef ZAPATA_PRI 04875 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04876 if (p->pri->pri) { 04877 if (!pri_grab(p, p->pri)) { 04878 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04879 pri_rel(p->pri); 04880 } 04881 else 04882 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04883 } 04884 p->proceeding = 1; 04885 } 04886 #endif 04887 /* don't continue in ast_indicate */ 04888 res = 0; 04889 break; 04890 case AST_CONTROL_PROGRESS: 04891 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 04892 #ifdef ZAPATA_PRI 04893 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 04894 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04895 if (p->pri->pri) { 04896 if (!pri_grab(p, p->pri)) { 04897 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 04898 pri_rel(p->pri); 04899 } 04900 else 04901 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04902 } 04903 p->progress = 1; 04904 } 04905 #endif 04906 /* don't continue in ast_indicate */ 04907 res = 0; 04908 break; 04909 case AST_CONTROL_CONGESTION: 04910 chan->hangupcause = AST_CAUSE_CONGESTION; 04911 #ifdef ZAPATA_PRI 04912 if (p->priindication_oob && p->sig == SIG_PRI) { 04913 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04914 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04915 res = 0; 04916 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04917 if (p->pri) { 04918 if (!pri_grab(p, p->pri)) { 04919 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 04920 pri_rel(p->pri); 04921 } else 04922 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04923 } 04924 p->progress = 1; 04925 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 04926 } else 04927 #endif 04928 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 04929 break; 04930 #ifdef ZAPATA_PRI 04931 case AST_CONTROL_HOLD: 04932 if (p->pri) { 04933 if (!pri_grab(p, p->pri)) { 04934 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 04935 pri_rel(p->pri); 04936 } else 04937 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04938 } 04939 break; 04940 case AST_CONTROL_UNHOLD: 04941 if (p->pri) { 04942 if (!pri_grab(p, p->pri)) { 04943 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 04944 pri_rel(p->pri); 04945 } else 04946 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04947 } 04948 break; 04949 #endif 04950 case AST_CONTROL_RADIO_KEY: 04951 if (p->radio) 04952 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04953 res = 0; 04954 break; 04955 case AST_CONTROL_RADIO_UNKEY: 04956 if (p->radio) 04957 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 04958 res = 0; 04959 break; 04960 case AST_CONTROL_FLASH: 04961 /* flash hookswitch */ 04962 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 04963 /* Clear out the dial buffer */ 04964 p->dop.dialstr[0] = '\0'; 04965 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 04966 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 04967 chan->name, strerror(errno)); 04968 } else 04969 res = 0; 04970 } else 04971 res = 0; 04972 break; 04973 case -1: 04974 res = tone_zone_play_tone(p->subs[index].zfd, -1); 04975 break; 04976 } 04977 } else 04978 res = 0; 04979 ast_mutex_unlock(&p->lock); 04980 return res; 04981 }
Definition at line 2939 of file chan_zap.c.
References ast_log(), LOG_WARNING, and master.
Referenced by zt_bridge().
02939 { 02940 int x; 02941 if (!slave || !master) { 02942 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 02943 return; 02944 } 02945 for (x=0;x<MAX_SLAVES;x++) { 02946 if (!master->slaves[x]) { 02947 master->slaves[x] = slave; 02948 break; 02949 } 02950 } 02951 if (x >= MAX_SLAVES) { 02952 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 02953 master->slaves[MAX_SLAVES - 1] = slave; 02954 } 02955 if (slave->master) 02956 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 02957 slave->master = master; 02958 02959 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 02960 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | , | |
int | , | |||
int | , | |||
int | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 4983 of file chan_zap.c.
References ast_channel::accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_STATE_RING, ast_strlen_zero(), ast_transfercapability2str(), ast_update_use_count(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::call_forward, ast_channel::call_forward, zt_pvt::callgroup, ast_channel::callgroup, zt_pvt::callingpres, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, zt_pvt::context, ast_channel::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, zt_pvt::dsp_features, DSP_PROGRESS_TALK, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, features, zt_pvt::hardwaredtmf, ast_channel::language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, ast_channel::musicclass, zt_pvt::musicclass, ast_channel::name, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, strdup, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::type, usecnt_lock, ast_channel::writeformat, zap_tech, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
04984 { 04985 struct ast_channel *tmp; 04986 int deflaw; 04987 int res; 04988 int x,y; 04989 int features; 04990 ZT_PARAMS ps; 04991 if (i->subs[index].owner) { 04992 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 04993 return NULL; 04994 } 04995 tmp = ast_channel_alloc(0); 04996 if (tmp) { 04997 tmp->tech = &zap_tech; 04998 ps.channo = i->channel; 04999 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05000 if (res) { 05001 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05002 ps.curlaw = ZT_LAW_MULAW; 05003 } 05004 if (ps.curlaw == ZT_LAW_ALAW) 05005 deflaw = AST_FORMAT_ALAW; 05006 else 05007 deflaw = AST_FORMAT_ULAW; 05008 if (law) { 05009 if (law == ZT_LAW_ALAW) 05010 deflaw = AST_FORMAT_ALAW; 05011 else 05012 deflaw = AST_FORMAT_ULAW; 05013 } 05014 y = 1; 05015 do { 05016 #ifdef ZAPATA_PRI 05017 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05018 snprintf(tmp->name, sizeof(tmp->name), "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05019 else 05020 #endif 05021 if (i->channel == CHAN_PSEUDO) 05022 snprintf(tmp->name, sizeof(tmp->name), "Zap/pseudo-%d", rand()); 05023 else 05024 snprintf(tmp->name, sizeof(tmp->name), "Zap/%d-%d", i->channel, y); 05025 for (x=0;x<3;x++) { 05026 if ((index != x) && i->subs[x].owner && !strcasecmp(tmp->name, i->subs[x].owner->name)) 05027 break; 05028 } 05029 y++; 05030 } while (x < 3); 05031 tmp->type = type; 05032 tmp->fds[0] = i->subs[index].zfd; 05033 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05034 /* Start out assuming ulaw since it's smaller :) */ 05035 tmp->rawreadformat = deflaw; 05036 tmp->readformat = deflaw; 05037 tmp->rawwriteformat = deflaw; 05038 tmp->writeformat = deflaw; 05039 i->subs[index].linear = 0; 05040 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05041 features = 0; 05042 if (i->busydetect && CANBUSYDETECT(i)) { 05043 features |= DSP_FEATURE_BUSY_DETECT; 05044 } 05045 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) { 05046 features |= DSP_FEATURE_CALL_PROGRESS; 05047 } 05048 if ((!i->outgoing && (i->callprogress & 4)) || 05049 (i->outgoing && (i->callprogress & 2))) { 05050 features |= DSP_FEATURE_FAX_DETECT; 05051 } 05052 #ifdef ZT_TONEDETECT 05053 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05054 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05055 #endif 05056 i->hardwaredtmf = 0; 05057 features |= DSP_FEATURE_DTMF_DETECT; 05058 #ifdef ZT_TONEDETECT 05059 } else if (NEED_MFDETECT(i)) { 05060 i->hardwaredtmf = 1; 05061 features |= DSP_FEATURE_DTMF_DETECT; 05062 } 05063 #endif 05064 if (features) { 05065 if (i->dsp) { 05066 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05067 } else { 05068 if (i->channel != CHAN_PSEUDO) 05069 i->dsp = ast_dsp_new(); 05070 else 05071 i->dsp = NULL; 05072 if (i->dsp) { 05073 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05074 #ifdef ZAPATA_PRI 05075 /* We cannot do progress detection until receives PROGRESS message */ 05076 if (i->outgoing && (i->sig == SIG_PRI)) { 05077 /* Remember requested DSP features, don't treat 05078 talking as ANSWER */ 05079 features = 0; 05080 } 05081 #endif 05082 ast_dsp_set_features(i->dsp, features); 05083 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05084 if (!ast_strlen_zero(progzone)) 05085 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05086 if (i->busydetect && CANBUSYDETECT(i)) { 05087 ast_dsp_set_busy_count(i->dsp, i->busycount); 05088 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05089 } 05090 } 05091 } 05092 } 05093 05094 if (state == AST_STATE_RING) 05095 tmp->rings = 1; 05096 tmp->tech_pvt = i; 05097 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05098 /* Only FXO signalled stuff can be picked up */ 05099 tmp->callgroup = i->callgroup; 05100 tmp->pickupgroup = i->pickupgroup; 05101 } 05102 if (!ast_strlen_zero(i->language)) 05103 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 05104 if (!ast_strlen_zero(i->musicclass)) 05105 ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass)); 05106 if (!i->owner) 05107 i->owner = tmp; 05108 if (!ast_strlen_zero(i->accountcode)) 05109 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 05110 if (i->amaflags) 05111 tmp->amaflags = i->amaflags; 05112 i->subs[index].owner = tmp; 05113 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05114 /* Copy call forward info */ 05115 ast_copy_string(tmp->call_forward, i->call_forward, sizeof(tmp->call_forward)); 05116 /* If we've been told "no ADSI" then enforce it */ 05117 if (!i->adsi) 05118 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05119 if (!ast_strlen_zero(i->exten)) 05120 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05121 if (!ast_strlen_zero(i->rdnis)) 05122 tmp->cid.cid_rdnis = strdup(i->rdnis); 05123 if (!ast_strlen_zero(i->dnid)) 05124 tmp->cid.cid_dnid = strdup(i->dnid); 05125 05126 #ifdef PRI_ANI 05127 if (!ast_strlen_zero(i->cid_num)) 05128 tmp->cid.cid_num = strdup(i->cid_num); 05129 if (!ast_strlen_zero(i->cid_name)) 05130 tmp->cid.cid_name = strdup(i->cid_name); 05131 if (!ast_strlen_zero(i->cid_ani)) 05132 tmp->cid.cid_ani = strdup(i->cid_num); 05133 else if (!ast_strlen_zero(i->cid_num)) 05134 tmp->cid.cid_ani = strdup(i->cid_num); 05135 #else 05136 if (!ast_strlen_zero(i->cid_num)) { 05137 tmp->cid.cid_num = strdup(i->cid_num); 05138 tmp->cid.cid_ani = strdup(i->cid_num); 05139 } 05140 if (!ast_strlen_zero(i->cid_name)) 05141 tmp->cid.cid_name = strdup(i->cid_name); 05142 #endif 05143 tmp->cid.cid_pres = i->callingpres; 05144 tmp->cid.cid_ton = i->cid_ton; 05145 #ifdef ZAPATA_PRI 05146 tmp->transfercapability = transfercapability; 05147 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05148 if (transfercapability & PRI_TRANS_CAP_DIGITAL) { 05149 i->digital = 1; 05150 } 05151 /* Assume calls are not idle calls unless we're told differently */ 05152 i->isidlecall = 0; 05153 i->alreadyhungup = 0; 05154 #endif 05155 /* clear the fake event in case we posted one before we had ast_channel */ 05156 i->fake_event = 0; 05157 /* Assure there is no confmute on this channel */ 05158 zt_confmute(i, 0); 05159 ast_setstate(tmp, state); 05160 ast_mutex_lock(&usecnt_lock); 05161 usecnt++; 05162 ast_mutex_unlock(&usecnt_lock); 05163 ast_update_use_count(); 05164 if (startpbx) { 05165 if (ast_pbx_start(tmp)) { 05166 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05167 ast_hangup(tmp); 05168 tmp = NULL; 05169 } 05170 } 05171 } else 05172 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 05173 return tmp; 05174 }
static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 889 of file chan_zap.c.
References ast_log(), LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
00890 { 00891 int fd; 00892 int isnum; 00893 int chan = 0; 00894 int bs; 00895 int x; 00896 isnum = 1; 00897 for (x=0;x<strlen(fn);x++) { 00898 if (!isdigit(fn[x])) { 00899 isnum = 0; 00900 break; 00901 } 00902 } 00903 if (isnum) { 00904 chan = atoi(fn); 00905 if (chan < 1) { 00906 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 00907 return -1; 00908 } 00909 fn = "/dev/zap/channel"; 00910 } 00911 fd = open(fn, O_RDWR | O_NONBLOCK); 00912 if (fd < 0) { 00913 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 00914 return -1; 00915 } 00916 if (chan) { 00917 if (ioctl(fd, ZT_SPECIFY, &chan)) { 00918 x = errno; 00919 close(fd); 00920 errno = x; 00921 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 00922 return -1; 00923 } 00924 } 00925 bs = READ_SIZE; 00926 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1; 00927 return fd; 00928 }
struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) |
Definition at line 4380 of file chan_zap.c.
References __zt_exception(), ast_channel::_state, ast_async_goto(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, ast_dsp_process(), ast_exists_extension(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_callerid(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), zt_subchannel::buffer, zt_pvt::busydetect, zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::channel, CHECK_BLOCKING, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, zt_pvt::dsp, ast_channel::exten, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::faxhandled, zt_pvt::firstradio, ast_frame::frametype, free, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::macrocontext, ast_frame::mallocd, ast_channel::name, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, ast_frame::offset, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, pbx_builtin_setvar_helper(), zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, ast_frame::samples, send_callerid(), send_cwcidspill(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_confmute(), zt_get_index(), and zt_setlinear().
04381 { 04382 struct zt_pvt *p = ast->tech_pvt; 04383 int res; 04384 int index; 04385 void *readbuf; 04386 struct ast_frame *f; 04387 04388 04389 ast_mutex_lock(&p->lock); 04390 04391 index = zt_get_index(ast, p, 0); 04392 04393 /* Hang up if we don't really exist */ 04394 if (index < 0) { 04395 ast_log(LOG_WARNING, "We dont exist?\n"); 04396 ast_mutex_unlock(&p->lock); 04397 return NULL; 04398 } 04399 04400 if (p->radio && p->inalarm) return NULL; 04401 04402 p->subs[index].f.frametype = AST_FRAME_NULL; 04403 p->subs[index].f.datalen = 0; 04404 p->subs[index].f.samples = 0; 04405 p->subs[index].f.mallocd = 0; 04406 p->subs[index].f.offset = 0; 04407 p->subs[index].f.subclass = 0; 04408 p->subs[index].f.delivery = ast_tv(0,0); 04409 p->subs[index].f.src = "zt_read"; 04410 p->subs[index].f.data = NULL; 04411 04412 /* make sure it sends initial key state as first frame */ 04413 if (p->radio && (!p->firstradio)) 04414 { 04415 ZT_PARAMS ps; 04416 04417 ps.channo = p->channel; 04418 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04419 ast_mutex_unlock(&p->lock); 04420 return NULL; 04421 } 04422 p->firstradio = 1; 04423 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04424 if (ps.rxisoffhook) 04425 { 04426 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04427 } 04428 else 04429 { 04430 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04431 } 04432 ast_mutex_unlock(&p->lock); 04433 return &p->subs[index].f; 04434 } 04435 if (p->ringt == 1) { 04436 ast_mutex_unlock(&p->lock); 04437 return NULL; 04438 } 04439 else if (p->ringt > 0) 04440 p->ringt--; 04441 04442 if (p->subs[index].needringing) { 04443 /* Send ringing frame if requested */ 04444 p->subs[index].needringing = 0; 04445 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04446 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04447 ast_setstate(ast, AST_STATE_RINGING); 04448 ast_mutex_unlock(&p->lock); 04449 return &p->subs[index].f; 04450 } 04451 04452 if (p->subs[index].needbusy) { 04453 /* Send busy frame if requested */ 04454 p->subs[index].needbusy = 0; 04455 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04456 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04457 ast_mutex_unlock(&p->lock); 04458 return &p->subs[index].f; 04459 } 04460 04461 if (p->subs[index].needcongestion) { 04462 /* Send congestion frame if requested */ 04463 p->subs[index].needcongestion = 0; 04464 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04465 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04466 ast_mutex_unlock(&p->lock); 04467 return &p->subs[index].f; 04468 } 04469 04470 if (p->subs[index].needcallerid) { 04471 ast_set_callerid(ast, !ast_strlen_zero(p->lastcid_num) ? p->lastcid_num : NULL, 04472 !ast_strlen_zero(p->lastcid_name) ? p->lastcid_name : NULL, 04473 !ast_strlen_zero(p->lastcid_num) ? p->lastcid_num : NULL 04474 ); 04475 p->subs[index].needcallerid = 0; 04476 } 04477 04478 if (p->subs[index].needanswer) { 04479 /* Send answer frame if requested */ 04480 p->subs[index].needanswer = 0; 04481 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04482 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04483 ast_mutex_unlock(&p->lock); 04484 return &p->subs[index].f; 04485 } 04486 04487 if (p->subs[index].needflash) { 04488 /* Send answer frame if requested */ 04489 p->subs[index].needflash = 0; 04490 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04491 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04492 ast_mutex_unlock(&p->lock); 04493 return &p->subs[index].f; 04494 } 04495 04496 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04497 if (!p->subs[index].linear) { 04498 p->subs[index].linear = 1; 04499 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04500 if (res) 04501 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04502 } 04503 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04504 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04505 if (p->subs[index].linear) { 04506 p->subs[index].linear = 0; 04507 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04508 if (res) 04509 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04510 } 04511 } else { 04512 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04513 ast_mutex_unlock(&p->lock); 04514 return NULL; 04515 } 04516 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04517 CHECK_BLOCKING(ast); 04518 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04519 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04520 /* Check for hangup */ 04521 if (res < 0) { 04522 f = NULL; 04523 if (res == -1) { 04524 if (errno == EAGAIN) { 04525 /* Return "NULL" frame if there is nobody there */ 04526 ast_mutex_unlock(&p->lock); 04527 return &p->subs[index].f; 04528 } else if (errno == ELAST) { 04529 f = __zt_exception(ast); 04530 } else 04531 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04532 } 04533 ast_mutex_unlock(&p->lock); 04534 return f; 04535 } 04536 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04537 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04538 f = __zt_exception(ast); 04539 ast_mutex_unlock(&p->lock); 04540 return f; 04541 } 04542 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04543 int c; 04544 04545 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04546 if (c < 0) { 04547 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04548 ast_mutex_unlock(&p->lock); 04549 return NULL; 04550 } 04551 if (c) { /* if a char to return */ 04552 p->subs[index].f.subclass = 0; 04553 p->subs[index].f.frametype = AST_FRAME_TEXT; 04554 p->subs[index].f.mallocd = 0; 04555 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04556 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04557 p->subs[index].f.datalen = 1; 04558 *((char *) p->subs[index].f.data) = c; 04559 ast_mutex_unlock(&p->lock); 04560 return &p->subs[index].f; 04561 } 04562 } 04563 if (p->callwaitingrepeat) 04564 p->callwaitingrepeat--; 04565 if (p->cidcwexpire) 04566 p->cidcwexpire--; 04567 /* Repeat callwaiting */ 04568 if (p->callwaitingrepeat == 1) { 04569 p->callwaitrings++; 04570 zt_callwait(ast); 04571 } 04572 /* Expire CID/CW */ 04573 if (p->cidcwexpire == 1) { 04574 if (option_verbose > 2) 04575 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 04576 restore_conference(p); 04577 } 04578 if (p->subs[index].linear) { 04579 p->subs[index].f.datalen = READ_SIZE * 2; 04580 } else 04581 p->subs[index].f.datalen = READ_SIZE; 04582 04583 /* Handle CallerID Transmission */ 04584 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 04585 send_callerid(p); 04586 } 04587 04588 p->subs[index].f.frametype = AST_FRAME_VOICE; 04589 p->subs[index].f.subclass = ast->rawreadformat; 04590 p->subs[index].f.samples = READ_SIZE; 04591 p->subs[index].f.mallocd = 0; 04592 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04593 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET/2; 04594 #if 0 04595 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 04596 #endif 04597 if (p->dialing || /* Transmitting something */ 04598 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 04599 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 04600 ) { 04601 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 04602 don't send anything */ 04603 p->subs[index].f.frametype = AST_FRAME_NULL; 04604 p->subs[index].f.subclass = 0; 04605 p->subs[index].f.samples = 0; 04606 p->subs[index].f.mallocd = 0; 04607 p->subs[index].f.offset = 0; 04608 p->subs[index].f.data = NULL; 04609 p->subs[index].f.datalen= 0; 04610 } 04611 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 04612 /* Perform busy detection. etc on the zap line */ 04613 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 04614 if (f) { 04615 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 04616 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 04617 /* Treat this as a "hangup" instead of a "busy" on the assumption that 04618 a busy */ 04619 f = NULL; 04620 } 04621 } else if (f->frametype == AST_FRAME_DTMF) { 04622 #ifdef ZAPATA_PRI 04623 if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { 04624 /* Don't accept in-band DTMF when in overlap dial mode */ 04625 f->frametype = AST_FRAME_NULL; 04626 f->subclass = 0; 04627 } 04628 #endif 04629 /* DSP clears us of being pulse */ 04630 p->pulsedial = 0; 04631 } 04632 } 04633 } else 04634 f = &p->subs[index].f; 04635 if (f && (f->frametype == AST_FRAME_DTMF)) { 04636 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 04637 if (p->confirmanswer) { 04638 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 04639 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 04640 of a DTMF digit */ 04641 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04642 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04643 f = &p->subs[index].f; 04644 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 04645 p->confirmanswer = 0; 04646 } else if (p->callwaitcas) { 04647 if ((f->subclass == 'A') || (f->subclass == 'D')) { 04648 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 04649 if (p->cidspill) 04650 free(p->cidspill); 04651 send_cwcidspill(p); 04652 } 04653 if ((f->subclass != 'm') && (f->subclass != 'u')) 04654 p->callwaitcas = 0; 04655 p->subs[index].f.frametype = AST_FRAME_NULL; 04656 p->subs[index].f.subclass = 0; 04657 f = &p->subs[index].f; 04658 } else if (f->subclass == 'f') { 04659 /* Fax tone -- Handle and return NULL */ 04660 if (!p->faxhandled) { 04661 p->faxhandled++; 04662 if (strcmp(ast->exten, "fax")) { 04663 const char *target_context = ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext; 04664 04665 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 04666 if (option_verbose > 2) 04667 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 04668 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 04669 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 04670 if (ast_async_goto(ast, target_context, "fax", 1)) 04671 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 04672 } else 04673 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 04674 } else 04675 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 04676 } else 04677 ast_log(LOG_DEBUG, "Fax already handled\n"); 04678 zt_confmute(p, 0); 04679 p->subs[index].f.frametype = AST_FRAME_NULL; 04680 p->subs[index].f.subclass = 0; 04681 f = &p->subs[index].f; 04682 } else if (f->subclass == 'm') { 04683 /* Confmute request */ 04684 zt_confmute(p, 1); 04685 p->subs[index].f.frametype = AST_FRAME_NULL; 04686 p->subs[index].f.subclass = 0; 04687 f = &p->subs[index].f; 04688 } else if (f->subclass == 'u') { 04689 /* Unmute */ 04690 zt_confmute(p, 0); 04691 p->subs[index].f.frametype = AST_FRAME_NULL; 04692 p->subs[index].f.subclass = 0; 04693 f = &p->subs[index].f; 04694 } else 04695 zt_confmute(p, 0); 04696 } 04697 04698 /* If we have a fake_event, trigger exception to handle it */ 04699 if (p->fake_event) 04700 ast_set_flag(ast, AST_FLAG_EXCEPTION); 04701 04702 ast_mutex_unlock(&p->lock); 04703 return f; 04704 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 7568 of file chan_zap.c.
References alloc_sub(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CDR_CALLWAIT, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), busy, ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::name, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), round_robin, s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, and zt_new().
07569 { 07570 int oldformat; 07571 int groupmatch = 0; 07572 int channelmatch = -1; 07573 int roundrobin = 0; 07574 int callwait = 0; 07575 int busy = 0; 07576 struct zt_pvt *p; 07577 struct ast_channel *tmp = NULL; 07578 char *dest=NULL; 07579 int x; 07580 char *s; 07581 char opt=0; 07582 int res=0, y=0; 07583 int backwards = 0; 07584 #ifdef ZAPATA_PRI 07585 int crv; 07586 int bearer = -1; 07587 int trunkgroup; 07588 struct zt_pri *pri=NULL; 07589 #endif 07590 struct zt_pvt *exit, *start, *end; 07591 ast_mutex_t *lock; 07592 int channelmatched = 0; 07593 int groupmatched = 0; 07594 07595 /* Assume we're locking the iflock */ 07596 lock = &iflock; 07597 start = iflist; 07598 end = ifend; 07599 /* We do signed linear */ 07600 oldformat = format; 07601 format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW); 07602 if (!format) { 07603 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat); 07604 return NULL; 07605 } 07606 if (data) { 07607 dest = ast_strdupa((char *)data); 07608 } else { 07609 ast_log(LOG_WARNING, "Channel requested with no data\n"); 07610 return NULL; 07611 } 07612 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 07613 /* Retrieve the group number */ 07614 char *stringp=NULL; 07615 stringp=dest + 1; 07616 s = strsep(&stringp, "/"); 07617 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07618 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 07619 return NULL; 07620 } 07621 groupmatch = 1 << x; 07622 if (toupper(dest[0]) == 'G') { 07623 if (dest[0] == 'G') { 07624 backwards = 1; 07625 p = ifend; 07626 } else 07627 p = iflist; 07628 } else { 07629 if (dest[0] == 'R') { 07630 backwards = 1; 07631 p = round_robin[x]?round_robin[x]->prev:ifend; 07632 if (!p) 07633 p = ifend; 07634 } else { 07635 p = round_robin[x]?round_robin[x]->next:iflist; 07636 if (!p) 07637 p = iflist; 07638 } 07639 roundrobin = 1; 07640 } 07641 } else { 07642 char *stringp=NULL; 07643 stringp=dest; 07644 s = strsep(&stringp, "/"); 07645 p = iflist; 07646 if (!strcasecmp(s, "pseudo")) { 07647 /* Special case for pseudo */ 07648 x = CHAN_PSEUDO; 07649 channelmatch = x; 07650 } 07651 #ifdef ZAPATA_PRI 07652 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 07653 if ((trunkgroup < 1) || (crv < 1)) { 07654 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 07655 return NULL; 07656 } 07657 res--; 07658 for (x=0;x<NUM_SPANS;x++) { 07659 if (pris[x].trunkgroup == trunkgroup) { 07660 pri = pris + x; 07661 lock = &pri->lock; 07662 start = pri->crvs; 07663 end = pri->crvend; 07664 break; 07665 } 07666 } 07667 if (!pri) { 07668 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 07669 return NULL; 07670 } 07671 channelmatch = crv; 07672 p = pris[x].crvs; 07673 } 07674 #endif 07675 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07676 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 07677 return NULL; 07678 } else { 07679 channelmatch = x; 07680 } 07681 } 07682 /* Search for an unowned channel */ 07683 if (ast_mutex_lock(lock)) { 07684 ast_log(LOG_ERROR, "Unable to lock interface list???\n"); 07685 return NULL; 07686 } 07687 exit = p; 07688 while(p && !tmp) { 07689 if (roundrobin) 07690 round_robin[x] = p; 07691 #if 0 07692 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 07693 #endif 07694 07695 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 07696 if (option_debug) 07697 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 07698 if (p->inalarm) 07699 goto next; 07700 07701 callwait = (p->owner != NULL); 07702 #ifdef ZAPATA_PRI 07703 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 07704 if (p->sig != SIG_FXSKS) { 07705 /* Gotta find an actual channel to use for this 07706 CRV if this isn't a callwait */ 07707 bearer = pri_find_empty_chan(pri, 0); 07708 if (bearer < 0) { 07709 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 07710 p = NULL; 07711 break; 07712 } 07713 pri_assign_bearer(p, pri, pri->pvts[bearer]); 07714 } else { 07715 if (alloc_sub(p, 0)) { 07716 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 07717 p = NULL; 07718 break; 07719 } else 07720 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 07721 p->pri = pri; 07722 } 07723 } 07724 #endif 07725 if (p->channel == CHAN_PSEUDO) { 07726 p = chandup(p); 07727 if (!p) { 07728 break; 07729 } 07730 } 07731 if (p->owner) { 07732 if (alloc_sub(p, SUB_CALLWAIT)) { 07733 p = NULL; 07734 break; 07735 } 07736 } 07737 p->outgoing = 1; 07738 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 07739 #ifdef ZAPATA_PRI 07740 if (p->bearer) { 07741 /* Log owner to bearer channel, too */ 07742 p->bearer->owner = tmp; 07743 } 07744 #endif 07745 /* Make special notes */ 07746 if (res > 1) { 07747 if (opt == 'c') { 07748 /* Confirm answer */ 07749 p->confirmanswer = 1; 07750 } else if (opt == 'r') { 07751 /* Distinctive ring */ 07752 if (res < 3) 07753 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 07754 else 07755 p->distinctivering = y; 07756 } else if (opt == 'd') { 07757 /* If this is an ISDN call, make it digital */ 07758 p->digital = 1; 07759 if (tmp) 07760 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 07761 } else { 07762 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 07763 } 07764 } 07765 /* Note if the call is a call waiting call */ 07766 if (tmp && callwait) 07767 tmp->cdrflags |= AST_CDR_CALLWAIT; 07768 break; 07769 } 07770 next: 07771 if (backwards) { 07772 p = p->prev; 07773 if (!p) 07774 p = end; 07775 } else { 07776 p = p->next; 07777 if (!p) 07778 p = start; 07779 } 07780 /* stop when you roll to the one that we started from */ 07781 if (p == exit) 07782 break; 07783 } 07784 ast_mutex_unlock(lock); 07785 restart_monitor(); 07786 if (callwait) 07787 *cause = AST_CAUSE_BUSY; 07788 else if (!tmp) { 07789 if (channelmatched) { 07790 if (busy) 07791 *cause = AST_CAUSE_BUSY; 07792 } else if (groupmatched) { 07793 *cause = AST_CAUSE_CONGESTION; 07794 } 07795 } 07796 07797 return tmp; 07798 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3306 of file chan_zap.c.
References ast_log(), SUB_REAL, and zt_pvt::subs.
Referenced by __zt_exception(), and zt_handle_event().
03307 { 03308 int x; 03309 int res; 03310 /* Make sure our transmit state is on hook */ 03311 x = 0; 03312 x = ZT_ONHOOK; 03313 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03314 do { 03315 x = ZT_RING; 03316 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03317 if (res) { 03318 switch(errno) { 03319 case EBUSY: 03320 case EINTR: 03321 /* Wait just in case */ 03322 usleep(10000); 03323 continue; 03324 case EINPROGRESS: 03325 res = 0; 03326 break; 03327 default: 03328 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03329 res = 0; 03330 } 03331 } 03332 } while (res); 03333 return res; 03334 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 11131 of file chan_zap.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), AST_LAW, ast_log(), zt_pvt::channel, END_SILENCE_LEN, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_ERROR, malloc, zt_pvt::mate, option_debug, poll(), POLLOUT, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, TRAILER_MS, zt_subchannel::zfd, and zt_get_index().
11132 { 11133 #define END_SILENCE_LEN 400 11134 #define HEADER_MS 50 11135 #define TRAILER_MS 5 11136 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 11137 #define ASCII_BYTES_PER_CHAR 80 11138 11139 unsigned char *buf,*mybuf; 11140 struct zt_pvt *p = c->tech_pvt; 11141 struct pollfd fds[1]; 11142 int size,res,fd,len,x; 11143 int bytes=0; 11144 /* Initial carrier (imaginary) */ 11145 float cr = 1.0; 11146 float ci = 0.0; 11147 float scont = 0.0; 11148 int index; 11149 11150 index = zt_get_index(c, p, 0); 11151 if (index < 0) { 11152 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 11153 return -1; 11154 } 11155 if (!text[0]) return(0); /* if nothing to send, dont */ 11156 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 11157 if (p->mate) 11158 buf = malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 11159 else 11160 buf = malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 11161 if (!buf) { 11162 ast_log(LOG_ERROR, "MALLOC FAILED\n"); 11163 return -1; 11164 } 11165 mybuf = buf; 11166 if (p->mate) { 11167 int codec = AST_LAW(p); 11168 for (x=0;x<HEADER_MS;x++) { /* 50 ms of Mark */ 11169 PUT_CLID_MARKMS; 11170 } 11171 /* Put actual message */ 11172 for (x=0;text[x];x++) { 11173 PUT_CLID(text[x]); 11174 } 11175 for (x=0;x<TRAILER_MS;x++) { /* 5 ms of Mark */ 11176 PUT_CLID_MARKMS; 11177 } 11178 len = bytes; 11179 buf = mybuf; 11180 } 11181 else { 11182 len = tdd_generate(p->tdd,buf,text); 11183 if (len < 1) { 11184 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n",(int)strlen(text)); 11185 free(mybuf); 11186 return -1; 11187 } 11188 } 11189 memset(buf + len,0x7f,END_SILENCE_LEN); 11190 len += END_SILENCE_LEN; 11191 fd = p->subs[index].zfd; 11192 while(len) { 11193 if (ast_check_hangup(c)) { 11194 free(mybuf); 11195 return -1; 11196 } 11197 size = len; 11198 if (size > READ_SIZE) 11199 size = READ_SIZE; 11200 fds[0].fd = fd; 11201 fds[0].events = POLLOUT | POLLPRI; 11202 fds[0].revents = 0; 11203 res = poll(fds, 1, -1); 11204 if (!res) { 11205 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 11206 continue; 11207 } 11208 /* if got exception */ 11209 if (fds[0].revents & POLLPRI) return -1; 11210 if (!(fds[0].revents & POLLOUT)) { 11211 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 11212 continue; 11213 } 11214 res = write(fd, buf, size); 11215 if (res != size) { 11216 if (res == -1) { 11217 free(mybuf); 11218 return -1; 11219 } 11220 if (option_debug) 11221 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 11222 break; 11223 } 11224 len -= size; 11225 buf += size; 11226 } 11227 free(mybuf); 11228 return(0); 11229 }
static int zt_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 1584 of file chan_zap.c.
References ast_log(), and LOG_WARNING.
Referenced by __zt_exception(), handle_init_event(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().
01585 { 01586 int x, res; 01587 x = hs; 01588 res = ioctl(fd, ZT_HOOK, &x); 01589 if (res < 0) 01590 { 01591 if (errno == EINPROGRESS) return 0; 01592 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01593 } 01594 return res; 01595 }
int zt_setlaw | ( | int | zfd, | |
int | law | |||
) |
Definition at line 946 of file chan_zap.c.
00947 { 00948 int res; 00949 res = ioctl(zfd, ZT_SETLAW, &law); 00950 if (res) 00951 return res; 00952 return 0; 00953 }
int zt_setlinear | ( | int | zfd, | |
int | linear | |||
) |
Definition at line 936 of file chan_zap.c.
Referenced by send_callerid(), zt_hangup(), zt_new(), zt_read(), and zt_write().
00937 { 00938 int res; 00939 res = ioctl(zfd, ZT_SETLINEAR, &linear); 00940 if (res) 00941 return res; 00942 return 0; 00943 }
static int zt_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2733 of file chan_zap.c.
References ast_check_hangup(), ast_dsp_digitmode(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), zt_pvt::channel, zt_pvt::didtdd, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, pollfd::events, pollfd::fd, zt_pvt::law, LOG_DEBUG, LOG_WARNING, zt_pvt::mate, ast_channel::name, poll(), POLLOUT, POLLPRI, READ_SIZE, pollfd::revents, zt_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, zt_pvt::subs, zt_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech_pvt, zt_pvt::txgain, zt_subchannel::zfd, zt_disable_ec(), and zt_get_index().
02734 { 02735 char *cp; 02736 signed char *scp; 02737 int x; 02738 int index; 02739 struct zt_pvt *p = chan->tech_pvt; 02740 02741 /* all supported options require data */ 02742 if (!data || (datalen < 1)) { 02743 errno = EINVAL; 02744 return -1; 02745 } 02746 02747 switch(option) { 02748 case AST_OPTION_TXGAIN: 02749 scp = (signed char *) data; 02750 index = zt_get_index(chan, p, 0); 02751 if (index < 0) { 02752 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02753 return -1; 02754 } 02755 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02756 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02757 case AST_OPTION_RXGAIN: 02758 scp = (signed char *) data; 02759 index = zt_get_index(chan, p, 0); 02760 if (index < 0) { 02761 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 02762 return -1; 02763 } 02764 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 02765 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 02766 case AST_OPTION_TONE_VERIFY: 02767 if (!p->dsp) 02768 break; 02769 cp = (char *) data; 02770 switch (*cp) { 02771 case 1: 02772 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 02773 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 02774 break; 02775 case 2: 02776 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 02777 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 02778 break; 02779 default: 02780 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 02781 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 02782 break; 02783 } 02784 break; 02785 case AST_OPTION_TDD: 02786 /* turn on or off TDD */ 02787 cp = (char *) data; 02788 p->mate = 0; 02789 if (!*cp) { /* turn it off */ 02790 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 02791 if (p->tdd) tdd_free(p->tdd); 02792 p->tdd = 0; 02793 break; 02794 } 02795 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 02796 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 02797 zt_disable_ec(p); 02798 /* otherwise, turn it on */ 02799 if (!p->didtdd) { /* if havent done it yet */ 02800 unsigned char mybuf[41000],*buf; 02801 int size,res,fd,len; 02802 struct pollfd fds[1]; 02803 02804 buf = mybuf; 02805 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 02806 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 02807 len = 40000; 02808 index = zt_get_index(chan, p, 0); 02809 if (index < 0) { 02810 ast_log(LOG_WARNING, "No index in TDD?\n"); 02811 return -1; 02812 } 02813 fd = p->subs[index].zfd; 02814 while(len) { 02815 if (ast_check_hangup(chan)) return -1; 02816 size = len; 02817 if (size > READ_SIZE) 02818 size = READ_SIZE; 02819 fds[0].fd = fd; 02820 fds[0].events = POLLPRI | POLLOUT; 02821 fds[0].revents = 0; 02822 res = poll(fds, 1, -1); 02823 if (!res) { 02824 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 02825 continue; 02826 } 02827 /* if got exception */ 02828 if (fds[0].revents & POLLPRI) return -1; 02829 if (!(fds[0].revents & POLLOUT)) { 02830 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 02831 continue; 02832 } 02833 res = write(fd, buf, size); 02834 if (res != size) { 02835 if (res == -1) return -1; 02836 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 02837 break; 02838 } 02839 len -= size; 02840 buf += size; 02841 } 02842 p->didtdd = 1; /* set to have done it now */ 02843 } 02844 if (*cp == 2) { /* Mate mode */ 02845 if (p->tdd) tdd_free(p->tdd); 02846 p->tdd = 0; 02847 p->mate = 1; 02848 break; 02849 } 02850 if (!p->tdd) { /* if we dont have one yet */ 02851 p->tdd = tdd_new(); /* allocate one */ 02852 } 02853 break; 02854 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 02855 if (!p->dsp) 02856 break; 02857 cp = (char *) data; 02858 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 02859 *cp ? "ON" : "OFF", (int) *cp, chan->name); 02860 ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax); 02861 break; 02862 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 02863 cp = (char *) data; 02864 if (!*cp) { 02865 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 02866 x = 0; 02867 zt_disable_ec(p); 02868 } else { 02869 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 02870 x = 1; 02871 } 02872 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 02873 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 02874 break; 02875 } 02876 errno = 0; 02877 02878 return 0; 02879 }
static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1417 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echotraining, LOG_DEBUG, LOG_WARNING, SUB_REAL, and zt_pvt::subs.
Referenced by zt_answer(), and zt_handle_event().
01418 { 01419 int x; 01420 int res; 01421 if (p && p->echocancel && p->echotraining) { 01422 x = p->echotraining; 01423 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01424 if (res) 01425 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01426 else { 01427 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01428 } 01429 } else 01430 ast_log(LOG_DEBUG, "No echo training requested\n"); 01431 }
Definition at line 2881 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), conf_del(), zt_pvt::lock, LOG_DEBUG, master, and SUB_REAL.
Referenced by zt_bridge(), and zt_fixup().
02882 { 02883 /* Unlink a specific slave or all slaves/masters from a given master */ 02884 int x; 02885 int hasslaves; 02886 if (!master) 02887 return; 02888 if (needlock) { 02889 ast_mutex_lock(&master->lock); 02890 if (slave) { 02891 while(ast_mutex_trylock(&slave->lock)) { 02892 ast_mutex_unlock(&master->lock); 02893 usleep(1); 02894 ast_mutex_lock(&master->lock); 02895 } 02896 } 02897 } 02898 hasslaves = 0; 02899 for (x=0;x<MAX_SLAVES;x++) { 02900 if (master->slaves[x]) { 02901 if (!slave || (master->slaves[x] == slave)) { 02902 /* Take slave out of the conference */ 02903 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 02904 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 02905 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 02906 master->slaves[x]->master = NULL; 02907 master->slaves[x] = NULL; 02908 } else 02909 hasslaves = 1; 02910 } 02911 if (!hasslaves) 02912 master->inconference = 0; 02913 } 02914 if (!slave) { 02915 if (master->master) { 02916 /* Take master out of the conference */ 02917 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 02918 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 02919 hasslaves = 0; 02920 for (x=0;x<MAX_SLAVES;x++) { 02921 if (master->master->slaves[x] == master) 02922 master->master->slaves[x] = NULL; 02923 else if (master->master->slaves[x]) 02924 hasslaves = 1; 02925 } 02926 if (!hasslaves) 02927 master->master->inconference = 0; 02928 } 02929 master->master = NULL; 02930 } 02931 update_conf(master); 02932 if (needlock) { 02933 if (slave) 02934 ast_mutex_unlock(&slave->lock); 02935 ast_mutex_unlock(&master->lock); 02936 } 02937 }
static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 369 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00370 { 00371 int i,j=0; 00372 i = ZT_IOMUX_SIGEVENT; 00373 if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1; 00374 if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1; 00375 return j; 00376 }
static int zt_wink | ( | struct zt_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 5196 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05197 { 05198 int j; 05199 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05200 for(;;) 05201 { 05202 /* set bits of interest */ 05203 j = ZT_IOMUX_SIGEVENT; 05204 /* wait for some happening */ 05205 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05206 /* exit loop if we have it */ 05207 if (j & ZT_IOMUX_SIGEVENT) break; 05208 } 05209 /* get the event info */ 05210 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05211 return 0; 05212 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4729 of file chan_zap.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, zt_pvt::dialing, zt_pvt::digital, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, my_zt_write(), ast_channel::name, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_setlinear().
04730 { 04731 struct zt_pvt *p = ast->tech_pvt; 04732 int res; 04733 unsigned char outbuf[4096]; 04734 int index; 04735 index = zt_get_index(ast, p, 0); 04736 if (index < 0) { 04737 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 04738 return -1; 04739 } 04740 04741 #if 0 04742 #ifdef ZAPATA_PRI 04743 ast_mutex_lock(&p->lock); 04744 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04745 if (p->pri->pri) { 04746 if (!pri_grab(p, p->pri)) { 04747 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04748 pri_rel(p->pri); 04749 } else 04750 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04751 } 04752 p->proceeding=1; 04753 } 04754 ast_mutex_unlock(&p->lock); 04755 #endif 04756 #endif 04757 /* Write a frame of (presumably voice) data */ 04758 if (frame->frametype != AST_FRAME_VOICE) { 04759 if (frame->frametype != AST_FRAME_IMAGE) 04760 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 04761 return 0; 04762 } 04763 if ((frame->subclass != AST_FORMAT_SLINEAR) && 04764 (frame->subclass != AST_FORMAT_ULAW) && 04765 (frame->subclass != AST_FORMAT_ALAW)) { 04766 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 04767 return -1; 04768 } 04769 if (p->dialing) { 04770 if (option_debug) 04771 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 04772 return 0; 04773 } 04774 if (!p->owner) { 04775 if (option_debug) 04776 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 04777 return 0; 04778 } 04779 if (p->cidspill) { 04780 if (option_debug) 04781 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 04782 return 0; 04783 } 04784 /* Return if it's not valid data */ 04785 if (!frame->data || !frame->datalen) 04786 return 0; 04787 if (frame->datalen > sizeof(outbuf) * 2) { 04788 ast_log(LOG_WARNING, "Frame too large\n"); 04789 return 0; 04790 } 04791 04792 if (frame->subclass == AST_FORMAT_SLINEAR) { 04793 if (!p->subs[index].linear) { 04794 p->subs[index].linear = 1; 04795 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04796 if (res) 04797 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 04798 } 04799 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 04800 } else { 04801 /* x-law already */ 04802 if (p->subs[index].linear) { 04803 p->subs[index].linear = 0; 04804 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04805 if (res) 04806 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 04807 } 04808 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 04809 } 04810 if (res < 0) { 04811 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 04812 return -1; 04813 } 04814 return 0; 04815 }
char accountcode[AST_MAX_ACCOUNT_CODE] = "" [static] |
Definition at line 269 of file chan_zap.c.
int adsi = 0 [static] |
Definition at line 275 of file chan_zap.c.
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
int amaflags = 0 [static] |
Definition at line 273 of file chan_zap.c.
int answeronpolarityswitch = 0 [static] |
int busy_quietlength = 0 [static] |
Definition at line 265 of file chan_zap.c.
int busy_tonelength = 0 [static] |
Definition at line 264 of file chan_zap.c.
int busycount = 3 [static] |
Definition at line 263 of file chan_zap.c.
int busydetect = 0 [static] |
Definition at line 261 of file chan_zap.c.
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 756 of file chan_zap.c.
int callprogress = 0 [static] |
Definition at line 267 of file chan_zap.c.
int callreturn = 0 [static] |
Definition at line 237 of file chan_zap.c.
int callwaiting = 0 [static] |
Definition at line 227 of file chan_zap.c.
int callwaitingcallerid = 0 [static] |
Definition at line 229 of file chan_zap.c.
int cancallforward = 0 [static] |
Definition at line 245 of file chan_zap.c.
int canpark = 0 [static] |
Definition at line 243 of file chan_zap.c.
char cid_name[256] = "" [static] |
Definition at line 200 of file chan_zap.c.
char cid_num[256] = "" [static] |
Definition at line 199 of file chan_zap.c.
int cid_signalling = CID_SIG_BELL [static] |
Definition at line 213 of file chan_zap.c.
int cid_start = CID_START_RING [static] |
Definition at line 214 of file chan_zap.c.
int cidrings[NUM_CADENCE_MAX] [static] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.
Definition at line 767 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 160 of file chan_zap.c.
char context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 198 of file chan_zap.c.
ast_group_t cur_callergroup = 0 [static] |
Definition at line 219 of file chan_zap.c.
int cur_debounce = -1 [static] |
Definition at line 286 of file chan_zap.c.
int cur_flash = -1 [static] |
Definition at line 282 of file chan_zap.c.
ast_group_t cur_group = 0 [static] |
Definition at line 218 of file chan_zap.c.
ast_group_t cur_pickupgroup = 0 [static] |
Definition at line 220 of file chan_zap.c.
int cur_preflash = -1 [static] |
Definition at line 280 of file chan_zap.c.
int cur_prewink = -1 [static] |
Definition at line 279 of file chan_zap.c.
int cur_priexclusive = 0 [static] |
Definition at line 287 of file chan_zap.c.
int cur_rxflash = -1 [static] |
Definition at line 285 of file chan_zap.c.
int cur_rxwink = -1 [static] |
Definition at line 284 of file chan_zap.c.
int cur_signalling = -1 [static] |
Definition at line 216 of file chan_zap.c.
int cur_start = -1 [static] |
Definition at line 283 of file chan_zap.c.
int cur_wink = -1 [static] |
Definition at line 281 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 201 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 202 of file chan_zap.c.
const char desc[] = "Zapata Telephony" [static] |
Definition at line 141 of file chan_zap.c.
char destroy_channel_usage[] [static] |
Initial value:
"Usage: zap destroy channel <chan num>\n" " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"
Definition at line 9997 of file chan_zap.c.
struct zt_distRings drings [static] |
int echocanbridged = 0 [static] |
Definition at line 259 of file chan_zap.c.
int echocancel [static] |
Definition at line 253 of file chan_zap.c.
int echotraining [static] |
Definition at line 255 of file chan_zap.c.
char* events[] [static] |
int firstdigittimeout = 16000 [static] |
int gendigittimeout = 8000 [static] |
int hanguponpolarityswitch = 0 [static] |
int hidecallerid = 0 [static] |
Definition at line 231 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 328 of file chan_zap.c.
Referenced by __build_step().
int immediate = 0 [static] |
Definition at line 223 of file chan_zap.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 204 of file chan_zap.c.
char mailbox[AST_MAX_EXTENSION] [static] |
Definition at line 271 of file chan_zap.c.
int matchdigittimeout = 3000 [static] |
How long to wait for an extra digit, if there is an ambiguous match.
Definition at line 319 of file chan_zap.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 352 of file chan_zap.c.
char musicclass[MAX_MUSICCLASS] = "" [static] |
Definition at line 205 of file chan_zap.c.
char* name |
Definition at line 1084 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 753 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 277 of file chan_zap.c.
int polarityonanswerdelay = 600 [static] |
How long (ms) to ignore Polarity Switch events after we answer a call.
Definition at line 341 of file chan_zap.c.
int priindication_oob = 0 [static] |
Definition at line 289 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 206 of file chan_zap.c.
int pulse [static] |
Definition at line 257 of file chan_zap.c.
int relaxdtmf = 0 [static] |
Definition at line 221 of file chan_zap.c.
int restrictcid = 0 [static] |
Definition at line 233 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 397 of file chan_zap.c.
struct zt_pvt* round_robin[32] |
float rxgain = 0.0 [static] |
int sendcalleridafter = DEFAULT_CIDRINGS [static] |
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 9989 of file chan_zap.c.
char show_channels_usage[] [static] |
Initial value:
"Usage: zap show channels\n" " Shows a list of available channels\n"
Definition at line 9985 of file chan_zap.c.
int stripmsd = 0 [static] |
Definition at line 225 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 150 of file chan_zap.c.
int threewaycalling = 0 [static] |
Definition at line 239 of file chan_zap.c.
int tonezone = -1 [static] |
Definition at line 251 of file chan_zap.c.
int transfer = 0 [static] |
Definition at line 241 of file chan_zap.c.
int transfertobusy = 1 [static] |
Definition at line 210 of file chan_zap.c.
float txgain = 0.0 [static] |
const char type[] = "Zap" [static] |
Definition at line 159 of file chan_zap.c.
int use_callerid = 1 [static] |
Definition at line 212 of file chan_zap.c.
int use_callingpres = 0 [static] |
Definition at line 235 of file chan_zap.c.
int usecnt = 0 [static] |
Definition at line 321 of file chan_zap.c.
int usedistinctiveringdetection = 0 [static] |
Definition at line 208 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 754 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
char zap_restart_usage[] [static] |
Initial value:
"Usage: zap restart\n" " fully restarts the zaptel channels: destroys them all and then re-reads from config.\n"
Definition at line 10001 of file chan_zap.c.
char zap_show_cadences_help[] [static] |
Initial value:
"Usage: zap show cadences\n" " Shows all cadences currently defined\n"
Definition at line 9893 of file chan_zap.c.
char zap_show_status_usage[] [static] |
Initial value:
"Usage: zap show status\n" " Shows a list of Zaptel cards with status\n"
Definition at line 9993 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 705 of file chan_zap.c.
Referenced by __unload_module(), load_module(), and zt_new().
int zaptrcallerid = 0 [static] |
Definition at line 215 of file chan_zap.c.