#include "asterisk.h"
#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <math.h>
#include <ctype.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj.h"
Include dependency graph for chan_zap.c:
Go to the source code of this file.
Data Structures | |
struct | distRingData |
struct | ringContextData |
struct | zt_chan_conf |
Channel configuration from zapata.conf . This struct is used for parsing the [channels] section of zapata.conf. Generally there is a field here for every possible configuration item. More... | |
struct | zt_distRings |
struct | zt_pvt |
struct | zt_subchannel |
Defines | |
#define | ASCII_BYTES_PER_CHAR 80 |
#define | AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
#define | CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define | CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
#define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CHAN_PSEUDO -2 |
#define | CHANNEL_PSEUDO -12 |
#define | CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define | CONF_USER_REAL (1 << 0) |
#define | CONF_USER_THIRDCALL (1 << 1) |
#define | DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 1) |
#define | DCHAN_PROVISIONED (1 << 0) |
#define | DCHAN_UP (1 << 2) |
#define | DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID. | |
#define | DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
#define | END_SILENCE_LEN 400 |
#define | FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\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_CHANLIST_LEN 80 |
#define | MAX_CHANNELS 672 |
#define | MAX_SLAVES 4 |
#define | MIN_MS_SINCE_FLASH ( (2000) ) |
#define | NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro. | |
#define | NUM_CADENCE_MAX 25 |
#define | NUM_DCHANS 4 |
#define | NUM_SPANS 32 |
#define | POLARITY_IDLE 0 |
#define | POLARITY_REV 1 |
#define | READ_SIZE 160 |
#define | sig2str zap_sig2str |
#define | SIG_E911 (0x1000000 | ZT_SIG_EM) |
#define | SIG_EM ZT_SIG_EM |
#define | SIG_EM_E1 ZT_SIG_EM_E1 |
#define | SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
#define | SIG_FEATB (0x0800000 | ZT_SIG_EM) |
#define | SIG_FEATD (0x0200000 | ZT_SIG_EM) |
#define | SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
#define | SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
#define | SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
#define | SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
#define | SIG_FXOGS ZT_SIG_FXOGS |
#define | SIG_FXOKS ZT_SIG_FXOKS |
#define | SIG_FXOLS ZT_SIG_FXOLS |
#define | SIG_FXSGS ZT_SIG_FXSGS |
#define | SIG_FXSKS ZT_SIG_FXSKS |
#define | SIG_FXSLS ZT_SIG_FXSLS |
#define | SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
#define | SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
#define | SIG_PRI ZT_SIG_CLEAR |
#define | SIG_SF ZT_SIG_SF |
#define | SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
#define | SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
#define | SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
#define | SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
#define | SMDI_MD_WAIT_TIMEOUT 1500 |
#define | SUB_CALLWAIT 1 |
#define | SUB_REAL 0 |
#define | SUB_THREEWAY 2 |
#define | tdesc "Zapata Telephony" |
#define | TRAILER_MS 5 |
#define | TRANSFER 0 |
#define | ZT_EVENT_DTMFDOWN 0 |
#define | ZT_EVENT_DTMFUP 0 |
Functions | |
static int | __unload_module (void) |
static struct ast_frame * | __zt_exception (struct ast_channel *ast) |
static int | action_transfer (struct mansession *s, const struct message *m) |
static int | action_transferhangup (struct mansession *s, const struct message *m) |
static int | action_zapdialoffhook (struct mansession *s, const struct message *m) |
static int | action_zapdndoff (struct mansession *s, const struct message *m) |
static int | action_zapdndon (struct mansession *s, const struct message *m) |
static int | action_zaprestart (struct mansession *s, const struct message *m) |
static int | action_zapshowchannels (struct mansession *s, const struct message *m) |
static char * | alarm2str (int alarm) |
static int | alloc_sub (struct zt_pvt *p, int x) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the interface list (of zt_pvt's). | |
static int | attempt_transfer (struct zt_pvt *p) |
static int | available (struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched) |
static int | build_channels (struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo) |
static int | bump_gains (struct zt_pvt *p) |
static struct zt_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) |
static int | destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now) |
static void | destroy_zt_pvt (struct zt_pvt **pvt) |
static int | digit_to_dtmfindex (char digit) |
static void | disable_dtmf_detect (struct zt_pvt *p) |
static void * | do_monitor (void *data) |
static void | enable_dtmf_detect (struct zt_pvt *p) |
static char * | event2str (int event) |
static void | fill_rxgain (struct zt_gains *g, float gain, int law) |
static void | fill_txgain (struct zt_gains *g, float gain, int law) |
static struct zt_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) |
static int | load_module (void) |
static struct zt_pvt * | mkintf (int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading) |
static int | my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
static int | my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear) |
static int | process_zap (struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels) |
static int | reload (void) |
static int | reset_conf (struct zt_pvt *p) |
static int | restart_monitor (void) |
static int | restore_conference (struct zt_pvt *p) |
static int | restore_gains (struct zt_pvt *p) |
static int | save_conference (struct zt_pvt *p) |
static int | send_callerid (struct zt_pvt *p) |
static int | send_cwcidspill (struct zt_pvt *p) |
static int | set_actual_gain (int fd, int chan, float rxgain, float txgain, int law) |
static int | set_actual_rxgain (int fd, int chan, float gain, int law) |
static int | set_actual_txgain (int fd, int chan, float gain, int law) |
static int | setup_zap (int reload) |
static void * | ss_thread (void *data) |
static void | swap_subs (struct zt_pvt *p, int a, int b) |
static int | unalloc_sub (struct zt_pvt *p, int x) |
static int | unload_module (void) |
static int | update_conf (struct zt_pvt *p) |
static void | wakeup_sub (struct zt_pvt *p, int a, void *pri) |
static int | zap_destroy_channel (int fd, int argc, char **argv) |
static int | zap_destroy_channel_bynum (int channel) |
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 struct zt_chan_conf | zt_chan_conf_default (void) |
static void | zt_close (int fd) |
static int | zt_confmute (struct zt_pvt *p, int muted) |
static int | zt_digit_begin (struct ast_channel *ast, char digit) |
static int | zt_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static void | zt_disable_ec (struct zt_pvt *p) |
static void | zt_enable_ec (struct zt_pvt *p) |
static struct ast_frame * | zt_exception (struct ast_channel *ast) |
static int | zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | zt_func_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
static int | zt_get_event (int fd) |
Avoid the silly zt_getevent which ignores a bunch of events. | |
static int | zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok) |
static void | zt_handle_dtmfup (struct ast_channel *ast, int index, struct ast_frame **dest) |
static struct ast_frame * | zt_handle_event (struct ast_channel *ast) |
static int | zt_hangup (struct ast_channel *ast) |
static int | zt_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen) |
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) |
static struct ast_frame * | zt_read (struct ast_channel *ast) |
static struct ast_channel * | zt_request (const char *type, int format, void *data, int *cause) |
static int | zt_ring_phone (struct zt_pvt *p) |
static int | zt_sendtext (struct ast_channel *c, const char *text) |
static int | zt_set_hook (int fd, int hs) |
static int | zt_setlinear (int zfd, int linear) |
static int | zt_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
static void | zt_train_ec (struct zt_pvt *p) |
static void | zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock) |
static int | zt_wait_event (int fd) |
Avoid the silly zt_waitevent which ignores a bunch of events. | |
static int | zt_wink (struct zt_pvt *p, int index) |
static int | zt_write (struct ast_channel *ast, struct ast_frame *frame) |
Variables | |
struct { | |
int alarm | |
char * name | |
} | alarms [] |
static struct zt_ring_cadence | cadences [NUM_CADENCE_MAX] |
static int | cidrings [NUM_CADENCE_MAX] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
static const char | config [] = "zapata.conf" |
static struct ast_jb_conf | default_jbconf |
static char | defaultcic [64] = "" |
static char | defaultozz [64] = "" |
static char | destroy_channel_usage [] |
static int | distinctiveringaftercid = 0 |
static struct zt_distRings | drings |
static char * | events [] |
static int | firstdigittimeout = 16000 |
Wait up to 16 seconds for first digit (FXO logic). | |
static int | gendigittimeout = 8000 |
How long to wait for following digits (FXO logic). | |
static struct ast_jb_conf | global_jbconf |
static int | ifcount = 0 |
static struct zt_pvt * | ifend |
static struct zt_pvt * | iflist |
static int | matchdigittimeout = 3000 |
How long to wait for an extra digit, if there is an ambiguous match. | |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static int | num_cadence = 4 |
static int | numbufs = 4 |
static char | progzone [10] = "" |
static int | ringt_base = DEFAULT_RINGT |
zt_pvt * | round_robin [32] |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char * | subnames [] |
static const char | tdesc [] = "Zapata Telephony Driver" |
static 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 |
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 154 of file chan_zap.c.
Referenced by send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_sendtext().
#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 282 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 196 of file chan_zap.c.
Referenced by build_channels(), enable_dtmf_detect(), mkintf(), zt_new(), and zt_request().
#define CHANNEL_PSEUDO -12 |
Definition at line 152 of file chan_zap.c.
#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 406 of file chan_zap.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 407 of file chan_zap.c.
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
Definition at line 202 of file chan_zap.c.
#define DCHAN_NOTINALARM (1 << 1) |
Definition at line 199 of file chan_zap.c.
#define DCHAN_PROVISIONED (1 << 0) |
Definition at line 198 of file chan_zap.c.
#define DCHAN_UP (1 << 2) |
Definition at line 200 of file chan_zap.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 150 of file chan_zap.c.
Referenced by zt_chan_conf_default().
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
Definition at line 286 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 711 of file chan_zap.c.
#define HANGUP 1 |
Definition at line 10238 of file chan_zap.c.
Referenced by action_transferhangup(), and zap_fake_event().
#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_information(), build_notify(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_status(), build_status_enquiry(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_timeout(), build_user_information(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_information(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), parse_setup_acknowledge(), parse_status(), and 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 279 of file chan_zap.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 280 of file chan_zap.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'zapchan'.
Definition at line 10593 of file chan_zap.c.
Referenced by process_zap().
#define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 194 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_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro.
Definition at line 157 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
#define NUM_CADENCE_MAX 25 |
Definition at line 736 of file chan_zap.c.
#define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 193 of file chan_zap.c.
#define NUM_SPANS 32 |
Definition at line 192 of file chan_zap.c.
#define POLARITY_IDLE 0 |
Definition at line 364 of file chan_zap.c.
Referenced by unalloc_sub(), zt_handle_event(), and zt_hangup().
#define POLARITY_REV 1 |
Definition at line 365 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 277 of file chan_zap.c.
Referenced by my_zt_write(), process_zap(), send_cwcidspill(), zt_callwait(), zt_open(), zt_read(), zt_sendtext(), and zt_setoption().
#define sig2str zap_sig2str |
Definition at line 1226 of file chan_zap.c.
Referenced by action_zapshowchannels(), build_channels(), handle_init_event(), mkintf(), zap_show_channel(), and zt_handle_event().
#define SIG_E911 (0x1000000 | ZT_SIG_EM) |
Definition at line 172 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM ZT_SIG_EM |
Definition at line 167 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM_E1 ZT_SIG_EM_E1 |
Definition at line 188 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
Definition at line 168 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 171 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 169 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 170 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
Definition at line 173 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
Definition at line 174 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
Definition at line 175 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FXOGS ZT_SIG_FXOGS |
Definition at line 180 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_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 181 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_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 179 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_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 177 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_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 178 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_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 176 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_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 189 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
Definition at line 190 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_PRI ZT_SIG_CLEAR |
Definition at line 182 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit_begin(), zt_digit_end(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().
#define SIG_SF ZT_SIG_SF |
Definition at line 183 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
Definition at line 187 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
Definition at line 185 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 186 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 184 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SMDI_MD_WAIT_TIMEOUT 1500 |
#define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 360 of file chan_zap.c.
#define SUB_REAL 0 |
Active call
Definition at line 359 of file chan_zap.c.
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 361 of file chan_zap.c.
#define tdesc "Zapata Telephony" |
#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 10419 of file chan_zap.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_verbose(), zt_pvt::channel, 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, zt_subchannel::zfd, and zt_close().
10420 { 10421 int x; 10422 struct zt_pvt *p, *pl; 10423 10424 #ifdef HAVE_PRI 10425 int i; 10426 for (i = 0; i < NUM_SPANS; i++) { 10427 if (pris[i].master != AST_PTHREADT_NULL) 10428 pthread_cancel(pris[i].master); 10429 } 10430 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 10431 ast_unregister_application(zap_send_keypad_facility_app); 10432 #endif 10433 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 10434 ast_manager_unregister( "ZapDialOffhook" ); 10435 ast_manager_unregister( "ZapHangup" ); 10436 ast_manager_unregister( "ZapTransfer" ); 10437 ast_manager_unregister( "ZapDNDoff" ); 10438 ast_manager_unregister( "ZapDNDon" ); 10439 ast_manager_unregister("ZapShowChannels"); 10440 ast_manager_unregister("ZapRestart"); 10441 ast_channel_unregister(&zap_tech); 10442 ast_mutex_lock(&iflock); 10443 /* Hangup all interfaces if they have an owner */ 10444 p = iflist; 10445 while (p) { 10446 if (p->owner) 10447 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 10448 p = p->next; 10449 } 10450 ast_mutex_unlock(&iflock); 10451 ast_mutex_lock(&monlock); 10452 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 10453 pthread_cancel(monitor_thread); 10454 pthread_kill(monitor_thread, SIGURG); 10455 pthread_join(monitor_thread, NULL); 10456 } 10457 monitor_thread = AST_PTHREADT_STOP; 10458 ast_mutex_unlock(&monlock); 10459 10460 ast_mutex_lock(&iflock); 10461 /* Destroy all the interfaces and free their memory */ 10462 p = iflist; 10463 while (p) { 10464 /* Free any callerid */ 10465 if (p->cidspill) 10466 free(p->cidspill); 10467 /* Close the zapata thingy */ 10468 if (p->subs[SUB_REAL].zfd > -1) 10469 zt_close(p->subs[SUB_REAL].zfd); 10470 pl = p; 10471 p = p->next; 10472 x = pl->channel; 10473 /* Free associated memory */ 10474 if (pl) 10475 destroy_zt_pvt(&pl); 10476 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 10477 } 10478 iflist = NULL; 10479 ifcount = 0; 10480 ast_mutex_unlock(&iflock); 10481 #ifdef HAVE_PRI 10482 for (i = 0; i < NUM_SPANS; i++) { 10483 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 10484 pthread_join(pris[i].master, NULL); 10485 zt_close(pris[i].fds[i]); 10486 } 10487 #endif 10488 return 0; 10489 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4517 of file chan_zap.c.
References ast_bridged_channel(), AST_CONTROL_UNHOLD, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, event2str(), zt_subchannel::f, f, zt_pvt::fake_event, ast_channel::fds, ast_frame::frametype, LOG_DEBUG, ast_frame::mallocd, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_debug, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().
Referenced by zt_exception(), and zt_read().
04518 { 04519 struct zt_pvt *p = ast->tech_pvt; 04520 int res; 04521 int usedindex=-1; 04522 int index; 04523 struct ast_frame *f; 04524 04525 04526 index = zt_get_index(ast, p, 1); 04527 04528 p->subs[index].f.frametype = AST_FRAME_NULL; 04529 p->subs[index].f.datalen = 0; 04530 p->subs[index].f.samples = 0; 04531 p->subs[index].f.mallocd = 0; 04532 p->subs[index].f.offset = 0; 04533 p->subs[index].f.subclass = 0; 04534 p->subs[index].f.delivery = ast_tv(0,0); 04535 p->subs[index].f.src = "zt_exception"; 04536 p->subs[index].f.data = NULL; 04537 04538 04539 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04540 /* If nobody owns us, absorb the event appropriately, otherwise 04541 we loop indefinitely. This occurs when, during call waiting, the 04542 other end hangs up our channel so that it no longer exists, but we 04543 have neither FLASH'd nor ONHOOK'd to signify our desire to 04544 change to the other channel. */ 04545 if (p->fake_event) { 04546 res = p->fake_event; 04547 p->fake_event = 0; 04548 } else 04549 res = zt_get_event(p->subs[SUB_REAL].zfd); 04550 /* Switch to real if there is one and this isn't something really silly... */ 04551 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04552 (res != ZT_EVENT_HOOKCOMPLETE)) { 04553 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04554 p->owner = p->subs[SUB_REAL].owner; 04555 if (p->owner && ast_bridged_channel(p->owner)) 04556 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04557 p->subs[SUB_REAL].needunhold = 1; 04558 } 04559 switch (res) { 04560 case ZT_EVENT_ONHOOK: 04561 zt_disable_ec(p); 04562 if (p->owner) { 04563 if (option_verbose > 2) 04564 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04565 zt_ring_phone(p); 04566 p->callwaitingrepeat = 0; 04567 p->cidcwexpire = 0; 04568 } else 04569 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04570 update_conf(p); 04571 break; 04572 case ZT_EVENT_RINGOFFHOOK: 04573 zt_enable_ec(p); 04574 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04575 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04576 p->subs[SUB_REAL].needanswer = 1; 04577 p->dialing = 0; 04578 } 04579 break; 04580 case ZT_EVENT_HOOKCOMPLETE: 04581 case ZT_EVENT_RINGERON: 04582 case ZT_EVENT_RINGEROFF: 04583 /* Do nothing */ 04584 break; 04585 case ZT_EVENT_WINKFLASH: 04586 gettimeofday(&p->flashtime, NULL); 04587 if (p->owner) { 04588 if (option_verbose > 2) 04589 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04590 if (p->owner->_state != AST_STATE_UP) { 04591 /* Answer if necessary */ 04592 usedindex = zt_get_index(p->owner, p, 0); 04593 if (usedindex > -1) { 04594 p->subs[usedindex].needanswer = 1; 04595 } 04596 ast_setstate(p->owner, AST_STATE_UP); 04597 } 04598 p->callwaitingrepeat = 0; 04599 p->cidcwexpire = 0; 04600 if (ast_bridged_channel(p->owner)) 04601 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04602 p->subs[SUB_REAL].needunhold = 1; 04603 } else 04604 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04605 update_conf(p); 04606 break; 04607 default: 04608 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04609 } 04610 f = &p->subs[index].f; 04611 return f; 04612 } 04613 if (!(p->radio || (p->oprmode < 0)) && option_debug) 04614 ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04615 /* If it's not us, return NULL immediately */ 04616 if (ast != p->owner) { 04617 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04618 f = &p->subs[index].f; 04619 return f; 04620 } 04621 f = zt_handle_event(ast); 04622 return f; 04623 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10306 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().
10307 { 10308 struct zt_pvt *p = NULL; 10309 const char *channel = astman_get_header(m, "ZapChannel"); 10310 10311 if (ast_strlen_zero(channel)) { 10312 astman_send_error(s, m, "No channel specified"); 10313 return 0; 10314 } 10315 p = find_channel(atoi(channel)); 10316 if (!p) { 10317 astman_send_error(s, m, "No such channel"); 10318 return 0; 10319 } 10320 zap_fake_event(p,TRANSFER); 10321 astman_send_ack(s, m, "ZapTransfer"); 10322 return 0; 10323 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10325 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().
10326 { 10327 struct zt_pvt *p = NULL; 10328 const char *channel = astman_get_header(m, "ZapChannel"); 10329 10330 if (ast_strlen_zero(channel)) { 10331 astman_send_error(s, m, "No channel specified"); 10332 return 0; 10333 } 10334 p = find_channel(atoi(channel)); 10335 if (!p) { 10336 astman_send_error(s, m, "No such channel"); 10337 return 0; 10338 } 10339 zap_fake_event(p,HANGUP); 10340 astman_send_ack(s, m, "ZapHangup"); 10341 return 0; 10342 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10344 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), f, find_channel(), zt_pvt::owner, s, and zap_queue_frame().
Referenced by load_module().
10345 { 10346 struct zt_pvt *p = NULL; 10347 const char *channel = astman_get_header(m, "ZapChannel"); 10348 const char *number = astman_get_header(m, "Number"); 10349 int i; 10350 10351 if (ast_strlen_zero(channel)) { 10352 astman_send_error(s, m, "No channel specified"); 10353 return 0; 10354 } 10355 if (ast_strlen_zero(number)) { 10356 astman_send_error(s, m, "No number specified"); 10357 return 0; 10358 } 10359 p = find_channel(atoi(channel)); 10360 if (!p) { 10361 astman_send_error(s, m, "No such channel"); 10362 return 0; 10363 } 10364 if (!p->owner) { 10365 astman_send_error(s, m, "Channel does not have it's owner"); 10366 return 0; 10367 } 10368 for (i = 0; i < strlen(number); i++) { 10369 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 10370 zap_queue_frame(p, &f, NULL); 10371 } 10372 astman_send_ack(s, m, "ZapDialOffhook"); 10373 return 0; 10374 }
static int action_zapdndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10287 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().
10288 { 10289 struct zt_pvt *p = NULL; 10290 const char *channel = astman_get_header(m, "ZapChannel"); 10291 10292 if (ast_strlen_zero(channel)) { 10293 astman_send_error(s, m, "No channel specified"); 10294 return 0; 10295 } 10296 p = find_channel(atoi(channel)); 10297 if (!p) { 10298 astman_send_error(s, m, "No such channel"); 10299 return 0; 10300 } 10301 p->dnd = 0; 10302 astman_send_ack(s, m, "DND Disabled"); 10303 return 0; 10304 }
static int action_zapdndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10268 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().
10269 { 10270 struct zt_pvt *p = NULL; 10271 const char *channel = astman_get_header(m, "ZapChannel"); 10272 10273 if (ast_strlen_zero(channel)) { 10274 astman_send_error(s, m, "No channel specified"); 10275 return 0; 10276 } 10277 p = find_channel(atoi(channel)); 10278 if (!p) { 10279 astman_send_error(s, m, "No such channel"); 10280 return 0; 10281 } 10282 p->dnd = 1; 10283 astman_send_ack(s, m, "DND Enabled"); 10284 return 0; 10285 }
static int action_zaprestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 9895 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), s, and zap_restart().
Referenced by load_module().
09896 { 09897 if (zap_restart() != 0) { 09898 astman_send_error(s, m, "Failed rereading zaptel configuration"); 09899 return 1; 09900 } 09901 astman_send_ack(s, m, "ZapRestart: Success"); 09902 return 0; 09903 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10376 of file chan_zap.c.
References alarm, alarm2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, s, zt_pvt::sig, and sig2str.
Referenced by load_module().
10377 { 10378 struct zt_pvt *tmp = NULL; 10379 const char *id = astman_get_header(m, "ActionID"); 10380 char idText[256] = ""; 10381 10382 astman_send_ack(s, m, "Zapata channel status will follow"); 10383 if (!ast_strlen_zero(id)) 10384 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 10385 10386 ast_mutex_lock(&iflock); 10387 10388 tmp = iflist; 10389 while (tmp) { 10390 if (tmp->channel > 0) { 10391 int alarm = get_alarms(tmp); 10392 astman_append(s, 10393 "Event: ZapShowChannels\r\n" 10394 "Channel: %d\r\n" 10395 "Signalling: %s\r\n" 10396 "Context: %s\r\n" 10397 "DND: %s\r\n" 10398 "Alarm: %s\r\n" 10399 "%s" 10400 "\r\n", 10401 tmp->channel, sig2str(tmp->sig), tmp->context, 10402 tmp->dnd ? "Enabled" : "Disabled", 10403 alarm2str(alarm), idText); 10404 } 10405 10406 tmp = tmp->next; 10407 } 10408 10409 ast_mutex_unlock(&iflock); 10410 10411 astman_append(s, 10412 "Event: ZapShowChannelsComplete\r\n" 10413 "%s" 10414 "\r\n", 10415 idText); 10416 return 0; 10417 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1137 of file chan_zap.c.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01138 { 01139 int x; 01140 for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) { 01141 if (alarms[x].alarm & alarm) 01142 return alarms[x].name; 01143 } 01144 return alarm ? "Unknown Alarm" : "No Alarm"; 01145 }
static int alloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 935 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, errno, 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().
00936 { 00937 ZT_BUFFERINFO bi; 00938 int res; 00939 if (p->subs[x].zfd < 0) { 00940 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 00941 if (p->subs[x].zfd > -1) { 00942 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 00943 if (!res) { 00944 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 00945 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 00946 bi.numbufs = numbufs; 00947 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 00948 if (res < 0) { 00949 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 00950 } 00951 } else 00952 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 00953 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 00954 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd); 00955 zt_close(p->subs[x].zfd); 00956 p->subs[x].zfd = -1; 00957 return -1; 00958 } 00959 if (option_debug) 00960 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 00961 return 0; 00962 } else 00963 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00964 return -1; 00965 } 00966 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 00967 return -1; 00968 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
tdesc | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the interface list (of zt_pvt's).
static int attempt_transfer | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3500 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_indicate(), ast_log(), ast_mutex_unlock(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.
03501 { 03502 /* In order to transfer, we need at least one of the channels to 03503 actually be in a call bridge. We can't conference two applications 03504 together (but then, why would we want to?) */ 03505 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03506 /* The three-way person we're about to transfer to could still be in MOH, so 03507 stop if now if appropriate */ 03508 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03509 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03510 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03511 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03512 } 03513 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03514 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03515 } 03516 if (p->subs[SUB_REAL].owner->cdr) { 03517 /* Move CDR from second channel to current one */ 03518 p->subs[SUB_THREEWAY].owner->cdr = 03519 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03520 p->subs[SUB_REAL].owner->cdr = NULL; 03521 } 03522 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03523 /* Move CDR from second channel's bridge to current one */ 03524 p->subs[SUB_THREEWAY].owner->cdr = 03525 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03526 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03527 } 03528 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03529 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03530 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03531 return -1; 03532 } 03533 /* Orphan the channel after releasing the lock */ 03534 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03535 unalloc_sub(p, SUB_THREEWAY); 03536 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03537 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03538 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03539 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03540 } 03541 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03542 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03543 } 03544 if (p->subs[SUB_THREEWAY].owner->cdr) { 03545 /* Move CDR from second channel to current one */ 03546 p->subs[SUB_REAL].owner->cdr = 03547 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03548 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03549 } 03550 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03551 /* Move CDR from second channel's bridge to current one */ 03552 p->subs[SUB_REAL].owner->cdr = 03553 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03554 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03555 } 03556 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03557 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03558 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03559 return -1; 03560 } 03561 /* Three-way is now the REAL */ 03562 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03563 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03564 unalloc_sub(p, SUB_THREEWAY); 03565 /* Tell the caller not to hangup */ 03566 return 1; 03567 } else { 03568 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03569 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03570 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03571 return -1; 03572 } 03573 return 0; 03574 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
ast_group_t | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7613 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, zt_pvt::oprmode, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_request().
07614 { 07615 int res; 07616 ZT_PARAMS par; 07617 07618 /* First, check group matching */ 07619 if (groupmatch) { 07620 if ((p->group & groupmatch) != groupmatch) 07621 return 0; 07622 *groupmatched = 1; 07623 } 07624 /* Check to see if we have a channel match */ 07625 if (channelmatch != -1) { 07626 if (p->channel != channelmatch) 07627 return 0; 07628 *channelmatched = 1; 07629 } 07630 /* We're at least busy at this point */ 07631 if (busy) { 07632 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07633 *busy = 1; 07634 } 07635 /* If do not disturb, definitely not */ 07636 if (p->dnd) 07637 return 0; 07638 /* If guard time, definitely not */ 07639 if (p->guardtime && (time(NULL) < p->guardtime)) 07640 return 0; 07641 07642 /* If no owner definitely available */ 07643 if (!p->owner) { 07644 #ifdef HAVE_PRI 07645 /* Trust PRI */ 07646 if (p->pri) { 07647 if (p->resetting || p->call) 07648 return 0; 07649 else 07650 return 1; 07651 } 07652 #endif 07653 if (!(p->radio || (p->oprmode < 0))) 07654 { 07655 if (!p->sig || (p->sig == SIG_FXSLS)) 07656 return 1; 07657 /* Check hook state */ 07658 if (p->subs[SUB_REAL].zfd > -1) 07659 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07660 else { 07661 /* Assume not off hook on CVRS */ 07662 res = 0; 07663 par.rxisoffhook = 0; 07664 } 07665 if (res) { 07666 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07667 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07668 /* When "onhook" that means no battery on the line, and thus 07669 it is out of service..., if it's on a TDM card... If it's a channel 07670 bank, there is no telling... */ 07671 if (par.rxbits > -1) 07672 return 1; 07673 if (par.rxisoffhook) 07674 return 1; 07675 else 07676 #ifdef ZAP_CHECK_HOOKSTATE 07677 return 0; 07678 #else 07679 return 1; 07680 #endif 07681 } else if (par.rxisoffhook) { 07682 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07683 /* Not available when the other end is off hook */ 07684 return 0; 07685 } 07686 } 07687 return 1; 07688 } 07689 07690 /* If it's not an FXO, forget about call wait */ 07691 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07692 return 0; 07693 07694 if (!p->callwaiting) { 07695 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07696 return 0; 07697 } 07698 07699 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07700 /* If there is already a call waiting call, then we can't take a second one */ 07701 return 0; 07702 } 07703 07704 if ((p->owner->_state != AST_STATE_UP) && 07705 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07706 /* If the current call is not up, then don't allow the call */ 07707 return 0; 07708 } 07709 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07710 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07711 return 0; 07712 } 07713 /* We're cool */ 07714 return 1; 07715 }
static int build_channels | ( | struct zt_chan_conf | conf, | |
int | iscrv, | |||
const char * | value, | |||
int | reload, | |||
int | lineno, | |||
int * | found_pseudo | |||
) | [static] |
Definition at line 10501 of file chan_zap.c.
References ast_log(), ast_strdupa, ast_verbose(), zt_chan_conf::chan, CHAN_PSEUDO, HAVE_PRI, LOG_ERROR, mkintf(), option_verbose, zt_pvt::sig, sig2str, strsep(), and VERBOSE_PREFIX_3.
Referenced by process_zap().
10502 { 10503 char *c, *chan; 10504 int x, start, finish; 10505 struct zt_pvt *tmp; 10506 #ifdef HAVE_PRI 10507 struct zt_pri *pri; 10508 int trunkgroup, y; 10509 #endif 10510 10511 if ((reload == 0) && (conf.chan.sig < 0)) { 10512 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 10513 return -1; 10514 } 10515 10516 c = ast_strdupa(value); 10517 10518 #ifdef HAVE_PRI 10519 pri = NULL; 10520 if (iscrv) { 10521 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 10522 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 10523 return -1; 10524 } 10525 if (trunkgroup < 1) { 10526 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 10527 return -1; 10528 } 10529 c += y; 10530 for (y = 0; y < NUM_SPANS; y++) { 10531 if (pris[y].trunkgroup == trunkgroup) { 10532 pri = pris + y; 10533 break; 10534 } 10535 } 10536 if (!pri) { 10537 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 10538 return -1; 10539 } 10540 } 10541 #endif 10542 10543 while ((chan = strsep(&c, ","))) { 10544 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 10545 /* Range */ 10546 } else if (sscanf(chan, "%d", &start)) { 10547 /* Just one */ 10548 finish = start; 10549 } else if (!strcasecmp(chan, "pseudo")) { 10550 finish = start = CHAN_PSEUDO; 10551 if (found_pseudo) 10552 *found_pseudo = 1; 10553 } else { 10554 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 10555 return -1; 10556 } 10557 if (finish < start) { 10558 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 10559 x = finish; 10560 finish = start; 10561 start = x; 10562 } 10563 10564 for (x = start; x <= finish; x++) { 10565 #ifdef HAVE_PRI 10566 tmp = mkintf(x, conf, pri, reload); 10567 #else 10568 tmp = mkintf(x, conf, NULL, reload); 10569 #endif 10570 10571 if (tmp) { 10572 if (option_verbose > 2) { 10573 #ifdef HAVE_PRI 10574 if (pri) 10575 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 10576 else 10577 #endif 10578 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 10579 } 10580 } else { 10581 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 10582 (reload == 1) ? "reconfigure" : "register", value); 10583 return -1; 10584 } 10585 } 10586 } 10587 10588 return 0; 10589 }
static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1588 of file chan_zap.c.
References ast_log(), errno, zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread().
01589 { 01590 int res; 01591 01592 /* Bump receive gain by 5.0db */ 01593 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01594 if (res) { 01595 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01596 return -1; 01597 } 01598 01599 return 0; 01600 }
Definition at line 7717 of file chan_zap.c.
References ast_log(), ast_malloc, ast_mutex_init(), destroy_zt_pvt(), errno, iflist, LOG_ERROR, oh323_pvt::next, SUB_REAL, and zt_open().
Referenced by zt_request().
07718 { 07719 struct zt_pvt *p; 07720 ZT_BUFFERINFO bi; 07721 int res; 07722 07723 if ((p = ast_malloc(sizeof(*p)))) { 07724 memcpy(p, src, sizeof(struct zt_pvt)); 07725 ast_mutex_init(&p->lock); 07726 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07727 /* Allocate a zapata structure */ 07728 if (p->subs[SUB_REAL].zfd < 0) { 07729 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07730 destroy_zt_pvt(&p); 07731 return NULL; 07732 } 07733 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07734 if (!res) { 07735 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07736 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07737 bi.numbufs = numbufs; 07738 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07739 if (res < 0) { 07740 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 07741 } 07742 } else 07743 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 07744 } 07745 p->destroy = 1; 07746 p->next = iflist; 07747 p->prev = NULL; 07748 iflist = p; 07749 if (iflist->next) 07750 iflist->next->prev = p; 07751 return p; 07752 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3576 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_subchannel::zfd.
Referenced by zt_handle_event().
03577 { 03578 ZT_CONFINFO ci; 03579 /* Fine if we already have a master, etc */ 03580 if (p->master || (p->confno > -1)) 03581 return 0; 03582 memset(&ci, 0, sizeof(ci)); 03583 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03584 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03585 return 0; 03586 } 03587 /* If we have no master and don't have a confno, then 03588 if we're in a conference, it's probably a MeetMe room or 03589 some such, so don't let us 3-way out! */ 03590 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03591 if (option_verbose > 2) 03592 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03593 return 1; 03594 } 03595 return 0; 03596 }
static int conf_add | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 1228 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().
01229 { 01230 /* If the conference already exists, and we're already in it 01231 don't bother doing anything */ 01232 ZT_CONFINFO zi; 01233 01234 memset(&zi, 0, sizeof(zi)); 01235 zi.chan = 0; 01236 01237 if (slavechannel > 0) { 01238 /* If we have only one slave, do a digital mon */ 01239 zi.confmode = ZT_CONF_DIGITALMON; 01240 zi.confno = slavechannel; 01241 } else { 01242 if (!index) { 01243 /* Real-side and pseudo-side both participate in conference */ 01244 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01245 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01246 } else 01247 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01248 zi.confno = p->confno; 01249 } 01250 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01251 return 0; 01252 if (c->zfd < 0) 01253 return 0; 01254 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01255 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01256 return -1; 01257 } 01258 if (slavechannel < 1) { 01259 p->confno = zi.confno; 01260 } 01261 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01262 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01263 return 0; 01264 }
static int conf_del | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 1277 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().
01278 { 01279 ZT_CONFINFO zi; 01280 if (/* Can't delete if there's no zfd */ 01281 (c->zfd < 0) || 01282 /* Don't delete from the conference if it's not our conference */ 01283 !isourconf(p, c) 01284 /* Don't delete if we don't think it's conferenced at all (implied) */ 01285 ) return 0; 01286 memset(&zi, 0, sizeof(zi)); 01287 zi.chan = 0; 01288 zi.confno = 0; 01289 zi.confmode = 0; 01290 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01291 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01292 return -1; 01293 } 01294 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01295 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01296 return 0; 01297 }
Definition at line 2228 of file chan_zap.c.
References destroy_zt_pvt(), iflist, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::prev, SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_close().
Referenced by zap_destroy_channel_bynum(), zap_restart(), and zt_hangup().
02229 { 02230 int owned = 0; 02231 int i = 0; 02232 02233 if (!now) { 02234 if (cur->owner) { 02235 owned = 1; 02236 } 02237 02238 for (i = 0; i < 3; i++) { 02239 if (cur->subs[i].owner) { 02240 owned = 1; 02241 } 02242 } 02243 if (!owned) { 02244 if (prev) { 02245 prev->next = cur->next; 02246 if (prev->next) 02247 prev->next->prev = prev; 02248 else 02249 ifend = prev; 02250 } else { 02251 iflist = cur->next; 02252 if (iflist) 02253 iflist->prev = NULL; 02254 else 02255 ifend = NULL; 02256 } 02257 if (cur->subs[SUB_REAL].zfd > -1) { 02258 zt_close(cur->subs[SUB_REAL].zfd); 02259 } 02260 destroy_zt_pvt(&cur); 02261 } 02262 } else { 02263 if (prev) { 02264 prev->next = cur->next; 02265 if (prev->next) 02266 prev->next->prev = prev; 02267 else 02268 ifend = prev; 02269 } else { 02270 iflist = cur->next; 02271 if (iflist) 02272 iflist->prev = NULL; 02273 else 02274 ifend = NULL; 02275 } 02276 if (cur->subs[SUB_REAL].zfd > -1) { 02277 zt_close(cur->subs[SUB_REAL].zfd); 02278 } 02279 destroy_zt_pvt(&cur); 02280 } 02281 return 0; 02282 }
static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2213 of file chan_zap.c.
References ast_mutex_destroy(), ast_smdi_interface_unref(), free, zt_pvt::lock, zt_pvt::next, zt_pvt::prev, zt_pvt::smdi_iface, and zt_pvt::use_smdi.
Referenced by __unload_module(), chandup(), destroy_channel(), and mkintf().
02214 { 02215 struct zt_pvt *p = *pvt; 02216 /* Remove channel from the list */ 02217 if (p->prev) 02218 p->prev->next = p->next; 02219 if (p->next) 02220 p->next->prev = p->prev; 02221 if (p->use_smdi) 02222 ast_smdi_interface_unref(p->smdi_iface); 02223 ast_mutex_destroy(&p->lock); 02224 free(p); 02225 *pvt = NULL; 02226 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 990 of file chan_zap.c.
Referenced by zt_digit_begin().
00991 { 00992 if (isdigit(digit)) 00993 return ZT_TONE_DTMF_BASE + (digit - '0'); 00994 else if (digit >= 'A' && digit <= 'D') 00995 return ZT_TONE_DTMF_A + (digit - 'A'); 00996 else if (digit >= 'a' && digit <= 'd') 00997 return ZT_TONE_DTMF_A + (digit - 'a'); 00998 else if (digit == '*') 00999 return ZT_TONE_DTMF_s; 01000 else if (digit == '#') 01001 return ZT_TONE_DTMF_p; 01002 else 01003 return -1; 01004 }
static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3110 of file chan_zap.c.
References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge().
03111 { 03112 #ifdef ZT_TONEDETECT 03113 int val; 03114 #endif 03115 03116 p->ignoredtmf = 1; 03117 03118 #ifdef ZT_TONEDETECT 03119 val = 0; 03120 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03121 #endif 03122 if (!p->hardwaredtmf && p->dsp) { 03123 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03124 ast_dsp_set_features(p->dsp, p->dsp_features); 03125 } 03126 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6820 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::cidspill, pollfd::events, pollfd::fd, free, iflist, last, LOG_DEBUG, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
06821 { 06822 int count, res, res2, spoint, pollres=0; 06823 struct zt_pvt *i; 06824 struct zt_pvt *last = NULL; 06825 time_t thispass = 0, lastpass = 0; 06826 int found; 06827 char buf[1024]; 06828 struct pollfd *pfds=NULL; 06829 int lastalloc = -1; 06830 /* This thread monitors all the frame relay interfaces which are not yet in use 06831 (and thus do not have a separate thread) indefinitely */ 06832 /* From here on out, we die whenever asked */ 06833 #if 0 06834 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 06835 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 06836 return NULL; 06837 } 06838 ast_log(LOG_DEBUG, "Monitor starting...\n"); 06839 #endif 06840 for (;;) { 06841 /* Lock the interface list */ 06842 ast_mutex_lock(&iflock); 06843 if (!pfds || (lastalloc != ifcount)) { 06844 if (pfds) { 06845 free(pfds); 06846 pfds = NULL; 06847 } 06848 if (ifcount) { 06849 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 06850 ast_mutex_unlock(&iflock); 06851 return NULL; 06852 } 06853 } 06854 lastalloc = ifcount; 06855 } 06856 /* Build the stuff we're going to poll on, that is the socket of every 06857 zt_pvt that does not have an associated owner channel */ 06858 count = 0; 06859 i = iflist; 06860 while (i) { 06861 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 06862 if (!i->owner && !i->subs[SUB_REAL].owner) { 06863 /* This needs to be watched, as it lacks an owner */ 06864 pfds[count].fd = i->subs[SUB_REAL].zfd; 06865 pfds[count].events = POLLPRI; 06866 pfds[count].revents = 0; 06867 /* Message waiting or r2 channels also get watched for reading */ 06868 if (i->cidspill) 06869 pfds[count].events |= POLLIN; 06870 count++; 06871 } 06872 } 06873 i = i->next; 06874 } 06875 /* Okay, now that we know what to do, release the interface lock */ 06876 ast_mutex_unlock(&iflock); 06877 06878 pthread_testcancel(); 06879 /* Wait at least a second for something to happen */ 06880 res = poll(pfds, count, 1000); 06881 pthread_testcancel(); 06882 /* Okay, poll has finished. Let's see what happened. */ 06883 if (res < 0) { 06884 if ((errno != EAGAIN) && (errno != EINTR)) 06885 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 06886 continue; 06887 } 06888 /* Alright, lock the interface list again, and let's look and see what has 06889 happened */ 06890 ast_mutex_lock(&iflock); 06891 found = 0; 06892 spoint = 0; 06893 lastpass = thispass; 06894 thispass = time(NULL); 06895 i = iflist; 06896 while (i) { 06897 if (thispass != lastpass) { 06898 if (!found && ((i == last) || ((i == iflist) && !last))) { 06899 last = i; 06900 if (last) { 06901 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 06902 (last->sig & __ZT_SIG_FXO)) { 06903 res = ast_app_has_voicemail(last->mailbox, NULL); 06904 if (last->msgstate != res) { 06905 int x; 06906 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 06907 x = ZT_FLUSH_BOTH; 06908 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 06909 if (res2) 06910 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 06911 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 06912 /* Turn on on hook transfer for 4 seconds */ 06913 x = 4000; 06914 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 06915 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 06916 last->cidpos = 0; 06917 last->msgstate = res; 06918 last->onhooktime = thispass; 06919 } 06920 found ++; 06921 } 06922 } 06923 last = last->next; 06924 } 06925 } 06926 } 06927 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 06928 if (i->radio && !i->owner) 06929 { 06930 res = zt_get_event(i->subs[SUB_REAL].zfd); 06931 if (res) 06932 { 06933 if (option_debug) 06934 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 06935 /* Don't hold iflock while handling init events */ 06936 ast_mutex_unlock(&iflock); 06937 handle_init_event(i, res); 06938 ast_mutex_lock(&iflock); 06939 } 06940 i = i->next; 06941 continue; 06942 } 06943 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 06944 if (pollres & POLLIN) { 06945 if (i->owner || i->subs[SUB_REAL].owner) { 06946 #ifdef HAVE_PRI 06947 if (!i->pri) 06948 #endif 06949 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 06950 i = i->next; 06951 continue; 06952 } 06953 if (!i->cidspill) { 06954 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 06955 i = i->next; 06956 continue; 06957 } 06958 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 06959 if (res > 0) { 06960 /* We read some number of bytes. Write an equal amount of data */ 06961 if (res > i->cidlen - i->cidpos) 06962 res = i->cidlen - i->cidpos; 06963 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 06964 if (res2 > 0) { 06965 i->cidpos += res2; 06966 if (i->cidpos >= i->cidlen) { 06967 free(i->cidspill); 06968 i->cidspill = 0; 06969 i->cidpos = 0; 06970 i->cidlen = 0; 06971 } 06972 } else { 06973 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 06974 i->msgstate = -1; 06975 } 06976 } else { 06977 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 06978 } 06979 } 06980 if (pollres & POLLPRI) { 06981 if (i->owner || i->subs[SUB_REAL].owner) { 06982 #ifdef HAVE_PRI 06983 if (!i->pri) 06984 #endif 06985 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 06986 i = i->next; 06987 continue; 06988 } 06989 res = zt_get_event(i->subs[SUB_REAL].zfd); 06990 if (option_debug) 06991 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06992 /* Don't hold iflock while handling init events */ 06993 ast_mutex_unlock(&iflock); 06994 handle_init_event(i, res); 06995 ast_mutex_lock(&iflock); 06996 } 06997 } 06998 i=i->next; 06999 } 07000 ast_mutex_unlock(&iflock); 07001 } 07002 /* Never reached */ 07003 return NULL; 07004 07005 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3128 of file chan_zap.c.
References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge().
03129 { 03130 #ifdef ZT_TONEDETECT 03131 int val; 03132 #endif 03133 03134 if (p->channel == CHAN_PSEUDO) 03135 return; 03136 03137 p->ignoredtmf = 0; 03138 03139 #ifdef ZT_TONEDETECT 03140 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03141 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03142 #endif 03143 if (!p->hardwaredtmf && p->dsp) { 03144 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03145 ast_dsp_set_features(p->dsp, p->dsp_features); 03146 } 03147 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1147 of file chan_zap.c.
Referenced by __zt_exception(), ss_thread(), and zt_handle_event().
01148 { 01149 static char buf[256]; 01150 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01151 return events[event]; 01152 sprintf(buf, "Event %d", event); /* safe */ 01153 return buf; 01154 }
static void fill_rxgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1512 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01513 { 01514 int j; 01515 int k; 01516 float linear_gain = pow(10.0, gain / 20.0); 01517 01518 switch (law) { 01519 case ZT_LAW_ALAW: 01520 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01521 if (gain) { 01522 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01523 if (k > 32767) k = 32767; 01524 if (k < -32767) k = -32767; 01525 g->rxgain[j] = AST_LIN2A(k); 01526 } else { 01527 g->rxgain[j] = j; 01528 } 01529 } 01530 break; 01531 case ZT_LAW_MULAW: 01532 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01533 if (gain) { 01534 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01535 if (k > 32767) k = 32767; 01536 if (k < -32767) k = -32767; 01537 g->rxgain[j] = AST_LIN2MU(k); 01538 } else { 01539 g->rxgain[j] = j; 01540 } 01541 } 01542 break; 01543 } 01544 }
static void fill_txgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1478 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01479 { 01480 int j; 01481 int k; 01482 float linear_gain = pow(10.0, gain / 20.0); 01483 01484 switch (law) { 01485 case ZT_LAW_ALAW: 01486 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01487 if (gain) { 01488 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01489 if (k > 32767) k = 32767; 01490 if (k < -32767) k = -32767; 01491 g->txgain[j] = AST_LIN2A(k); 01492 } else { 01493 g->txgain[j] = j; 01494 } 01495 } 01496 break; 01497 case ZT_LAW_MULAW: 01498 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01499 if (gain) { 01500 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01501 if (k > 32767) k = 32767; 01502 if (k < -32767) k = -32767; 01503 g->txgain[j] = AST_LIN2MU(k); 01504 } else { 01505 g->txgain[j] = j; 01506 } 01507 } 01508 break; 01509 } 01510 }
static struct zt_pvt* find_channel | ( | int | channel | ) | [static] |
Definition at line 10256 of file chan_zap.c.
References zt_pvt::channel, iflist, and zt_pvt::next.
Referenced by action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), and action_zapdndon().
10257 { 10258 struct zt_pvt *p = iflist; 10259 while (p) { 10260 if (p->channel == channel) { 10261 break; 10262 } 10263 p = p->next; 10264 } 10265 return p; 10266 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3598 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::span, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03599 { 03600 int res; 03601 ZT_SPANINFO zi; 03602 memset(&zi, 0, sizeof(zi)); 03603 zi.spanno = p->span; 03604 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03605 if (res < 0) { 03606 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03607 return 0; 03608 } 03609 return zi.alarms; 03610 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6595 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, errno, EVENT_FLAG_SYSTEM, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, zt_pvt::unknown_alarm, VERBOSE_PREFIX_2, zap_destroy_channel_bynum(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
06596 { 06597 int res; 06598 pthread_t threadid; 06599 pthread_attr_t attr; 06600 struct ast_channel *chan; 06601 pthread_attr_init(&attr); 06602 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06603 /* Handle an event on a given channel for the monitor thread. */ 06604 switch (event) { 06605 case ZT_EVENT_NONE: 06606 case ZT_EVENT_BITSCHANGED: 06607 break; 06608 case ZT_EVENT_WINKFLASH: 06609 case ZT_EVENT_RINGOFFHOOK: 06610 if (i->inalarm) break; 06611 if (i->radio) break; 06612 /* Got a ring/answer. What kind of channel are we? */ 06613 switch (i->sig) { 06614 case SIG_FXOLS: 06615 case SIG_FXOGS: 06616 case SIG_FXOKS: 06617 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06618 if (res && (errno == EBUSY)) 06619 break; 06620 if (i->cidspill) { 06621 /* Cancel VMWI spill */ 06622 free(i->cidspill); 06623 i->cidspill = NULL; 06624 } 06625 if (i->immediate) { 06626 zt_enable_ec(i); 06627 /* The channel is immediately up. Start right away */ 06628 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06629 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06630 if (!chan) { 06631 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06632 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06633 if (res < 0) 06634 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06635 } 06636 } else { 06637 /* Check for callerid, digits, etc */ 06638 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06639 if (chan) { 06640 if (has_voicemail(i)) 06641 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06642 else 06643 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06644 if (res < 0) 06645 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 06646 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06647 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06648 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06649 if (res < 0) 06650 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06651 ast_hangup(chan); 06652 } 06653 } else 06654 ast_log(LOG_WARNING, "Unable to create channel\n"); 06655 } 06656 break; 06657 case SIG_FXSLS: 06658 case SIG_FXSGS: 06659 case SIG_FXSKS: 06660 i->ringt = i->ringt_base; 06661 /* Fall through */ 06662 case SIG_EMWINK: 06663 case SIG_FEATD: 06664 case SIG_FEATDMF: 06665 case SIG_FEATDMF_TA: 06666 case SIG_E911: 06667 case SIG_FGC_CAMA: 06668 case SIG_FGC_CAMAMF: 06669 case SIG_FEATB: 06670 case SIG_EM: 06671 case SIG_EM_E1: 06672 case SIG_SFWINK: 06673 case SIG_SF_FEATD: 06674 case SIG_SF_FEATDMF: 06675 case SIG_SF_FEATB: 06676 case SIG_SF: 06677 /* Check for callerid, digits, etc */ 06678 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06679 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06680 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06681 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06682 if (res < 0) 06683 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06684 ast_hangup(chan); 06685 } else if (!chan) { 06686 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06687 } 06688 break; 06689 default: 06690 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06691 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06692 if (res < 0) 06693 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06694 return -1; 06695 } 06696 break; 06697 case ZT_EVENT_NOALARM: 06698 i->inalarm = 0; 06699 if (!i->unknown_alarm) { 06700 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06701 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06702 "Channel: %d\r\n", i->channel); 06703 } else { 06704 i->unknown_alarm = 0; 06705 } 06706 break; 06707 case ZT_EVENT_ALARM: 06708 i->inalarm = 1; 06709 res = get_alarms(i); 06710 do { 06711 const char *alarm_str = alarm2str(res); 06712 06713 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 06714 * doesn't know what to do with it. Don't confuse users with log messages. */ 06715 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 06716 i->unknown_alarm = 1; 06717 break; 06718 } else { 06719 i->unknown_alarm = 0; 06720 } 06721 06722 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str); 06723 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06724 "Alarm: %s\r\n" 06725 "Channel: %d\r\n", 06726 alarm_str, i->channel); 06727 } while (0); 06728 /* fall thru intentionally */ 06729 case ZT_EVENT_ONHOOK: 06730 if (i->radio) 06731 break; 06732 /* Back on hook. Hang up. */ 06733 switch (i->sig) { 06734 case SIG_FXOLS: 06735 case SIG_FXOGS: 06736 case SIG_FEATD: 06737 case SIG_FEATDMF: 06738 case SIG_FEATDMF_TA: 06739 case SIG_E911: 06740 case SIG_FGC_CAMA: 06741 case SIG_FGC_CAMAMF: 06742 case SIG_FEATB: 06743 case SIG_EM: 06744 case SIG_EM_E1: 06745 case SIG_EMWINK: 06746 case SIG_SF_FEATD: 06747 case SIG_SF_FEATDMF: 06748 case SIG_SF_FEATB: 06749 case SIG_SF: 06750 case SIG_SFWINK: 06751 case SIG_FXSLS: 06752 case SIG_FXSGS: 06753 case SIG_FXSKS: 06754 case SIG_GR303FXSKS: 06755 zt_disable_ec(i); 06756 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06757 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06758 break; 06759 case SIG_GR303FXOKS: 06760 case SIG_FXOKS: 06761 zt_disable_ec(i); 06762 /* Diddle the battery for the zhone */ 06763 #ifdef ZHONE_HACK 06764 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06765 usleep(1); 06766 #endif 06767 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06768 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06769 break; 06770 case SIG_PRI: 06771 zt_disable_ec(i); 06772 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06773 break; 06774 default: 06775 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06776 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06777 return -1; 06778 } 06779 break; 06780 case ZT_EVENT_POLARITY: 06781 switch (i->sig) { 06782 case SIG_FXSLS: 06783 case SIG_FXSKS: 06784 case SIG_FXSGS: 06785 /* We have already got a PR before the channel was 06786 created, but it wasn't handled. We need polarity 06787 to be REV for remote hangup detection to work. 06788 At least in Spain */ 06789 if (i->hanguponpolarityswitch) 06790 i->polarity = POLARITY_REV; 06791 06792 if (i->cid_start == CID_START_POLARITY) { 06793 i->polarity = POLARITY_REV; 06794 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06795 "CID detection on channel %d\n", 06796 i->channel); 06797 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06798 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06799 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06800 } 06801 } 06802 break; 06803 default: 06804 ast_log(LOG_WARNING, "handle_init_event detected " 06805 "polarity reversal on non-FXO (SIG_FXS) " 06806 "interface %d\n", i->channel); 06807 } 06808 break; 06809 case ZT_EVENT_REMOVED: /* destroy channel */ 06810 ast_log(LOG_NOTICE, 06811 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 06812 i->channel); 06813 zap_destroy_channel_bynum(i->channel); 06814 break; 06815 } 06816 pthread_attr_destroy(&attr); 06817 return 0; 06818 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10100 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
10101 { 10102 int i, j; 10103 for (i = 0; i < num_cadence; i++) { 10104 char output[1024]; 10105 char tmp[16], tmp2[64]; 10106 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 10107 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 10108 10109 for (j = 0; j < 16; j++) { 10110 if (cadences[i].ringcadence[j] == 0) 10111 break; 10112 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 10113 if (cidrings[i] * 2 - 1 == j) 10114 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 10115 else 10116 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 10117 if (j != 0) 10118 strncat(output, ",", sizeof(output) - strlen(output) - 1); 10119 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 10120 } 10121 ast_cli(fd,"%s\n",output); 10122 } 10123 return 0; 10124 }
static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1709 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01710 { 01711 01712 return ast_app_has_voicemail(p->mailbox, NULL); 01713 }
static int isourconf | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c | |||
) | [static] |
Definition at line 1266 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01267 { 01268 /* If they're listening to our channel, they're ours */ 01269 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01270 return 1; 01271 /* If they're a talker on our (allocated) conference, they're ours */ 01272 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01273 return 1; 01274 return 0; 01275 }
Definition at line 1299 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().
01300 { 01301 int x; 01302 int useslavenative; 01303 struct zt_pvt *slave = NULL; 01304 /* Start out optimistic */ 01305 useslavenative = 1; 01306 /* Update conference state in a stateless fashion */ 01307 for (x = 0; x < 3; x++) { 01308 /* Any three-way calling makes slave native mode *definitely* out 01309 of the question */ 01310 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01311 useslavenative = 0; 01312 } 01313 /* If we don't have any 3-way calls, check to see if we have 01314 precisely one slave */ 01315 if (useslavenative) { 01316 for (x = 0; x < MAX_SLAVES; x++) { 01317 if (p->slaves[x]) { 01318 if (slave) { 01319 /* Whoops already have a slave! No 01320 slave native and stop right away */ 01321 slave = NULL; 01322 useslavenative = 0; 01323 break; 01324 } else { 01325 /* We have one slave so far */ 01326 slave = p->slaves[x]; 01327 } 01328 } 01329 } 01330 } 01331 /* If no slave, slave native definitely out */ 01332 if (!slave) 01333 useslavenative = 0; 01334 else if (slave->law != p->law) { 01335 useslavenative = 0; 01336 slave = NULL; 01337 } 01338 if (out) 01339 *out = slave; 01340 return useslavenative; 01341 }
static int load_module | ( | void | ) | [static] |
Definition at line 11394 of file chan_zap.c.
References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, ast_mutex_init(), AST_PTHREADT_NULL, ast_register_application(), ast_string_field_init, ast_string_field_set, inuse, lock, LOG_ERROR, name, round_robin, setup_zap(), zap_cli, and zap_tech.
11395 { 11396 int res; 11397 11398 #ifdef HAVE_PRI 11399 int y,i; 11400 memset(pris, 0, sizeof(pris)); 11401 for (y = 0; y < NUM_SPANS; y++) { 11402 ast_mutex_init(&pris[y].lock); 11403 pris[y].offset = -1; 11404 pris[y].master = AST_PTHREADT_NULL; 11405 for (i = 0; i < NUM_DCHANS; i++) 11406 pris[y].fds[i] = -1; 11407 } 11408 pri_set_error(zt_pri_error); 11409 pri_set_message(zt_pri_message); 11410 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 11411 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 11412 #endif 11413 res = setup_zap(0); 11414 /* Make sure we can register our Zap channel type */ 11415 if (res) 11416 return AST_MODULE_LOAD_DECLINE; 11417 if (ast_channel_register(&zap_tech)) { 11418 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 11419 __unload_module(); 11420 return -1; 11421 } 11422 #ifdef HAVE_PRI 11423 ast_string_field_init(&inuse, 16); 11424 ast_string_field_set(&inuse, name, "GR-303InUse"); 11425 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 11426 #endif 11427 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 11428 11429 memset(round_robin, 0, sizeof(round_robin)); 11430 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 11431 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 11432 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 11433 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 11434 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 11435 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 11436 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 11437 11438 return res; 11439 }
static struct zt_pvt* mkintf | ( | int | channel, | |
struct zt_chan_conf | conf, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static] |
Definition at line 7152 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_init(), ast_strlen_zero(), zt_chan_conf::chan, CHAN_PSEUDO, destroy_zt_pvt(), errno, iflist, LOG_ERROR, MAX_CHANNELS, zt_pvt::next, zt_pvt::prev, zt_pvt::sig, sig2str, SIG_FXOKS, SIG_FXSKS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SUB_REAL, and zt_open().
Referenced by build_channels().
07153 { 07154 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07155 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07156 char fn[80]; 07157 #if 1 07158 struct zt_bufferinfo bi; 07159 #endif 07160 struct zt_spaninfo si; 07161 int res; 07162 int span=0; 07163 int here = 0; 07164 int x; 07165 struct zt_pvt **wlist; 07166 struct zt_pvt **wend; 07167 ZT_PARAMS p; 07168 07169 wlist = &iflist; 07170 wend = &ifend; 07171 07172 #ifdef HAVE_PRI 07173 if (pri) { 07174 wlist = &pri->crvs; 07175 wend = &pri->crvend; 07176 } 07177 #endif 07178 07179 tmp2 = *wlist; 07180 prev = NULL; 07181 07182 while (tmp2) { 07183 if (!tmp2->destroy) { 07184 if (tmp2->channel == channel) { 07185 tmp = tmp2; 07186 here = 1; 07187 break; 07188 } 07189 if (tmp2->channel > channel) { 07190 break; 07191 } 07192 } 07193 prev = tmp2; 07194 tmp2 = tmp2->next; 07195 } 07196 07197 if (!here && !reloading) { 07198 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07199 destroy_zt_pvt(&tmp); 07200 return NULL; 07201 } 07202 ast_mutex_init(&tmp->lock); 07203 ifcount++; 07204 for (x = 0; x < 3; x++) 07205 tmp->subs[x].zfd = -1; 07206 tmp->channel = channel; 07207 } 07208 07209 if (tmp) { 07210 if (!here) { 07211 if ((channel != CHAN_PSEUDO) && !pri) { 07212 snprintf(fn, sizeof(fn), "%d", channel); 07213 /* Open non-blocking */ 07214 if (!here) 07215 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07216 /* Allocate a zapata structure */ 07217 if (tmp->subs[SUB_REAL].zfd < 0) { 07218 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); 07219 destroy_zt_pvt(&tmp); 07220 return NULL; 07221 } 07222 memset(&p, 0, sizeof(p)); 07223 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07224 if (res < 0) { 07225 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07226 destroy_zt_pvt(&tmp); 07227 return NULL; 07228 } 07229 if (p.sigtype != (conf.chan.sig & 0x3ffff)) { 07230 ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(conf.chan.sig), sig2str(p.sigtype)); 07231 destroy_zt_pvt(&tmp); 07232 return NULL; 07233 } 07234 tmp->law = p.curlaw; 07235 tmp->span = p.spanno; 07236 span = p.spanno - 1; 07237 } else { 07238 if (channel == CHAN_PSEUDO) 07239 conf.chan.sig = 0; 07240 else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) { 07241 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07242 return NULL; 07243 } 07244 } 07245 #ifdef HAVE_PRI 07246 if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) { 07247 int offset; 07248 int myswitchtype; 07249 int matchesdchan; 07250 int x,y; 07251 offset = 0; 07252 if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07253 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07254 destroy_zt_pvt(&tmp); 07255 return NULL; 07256 } 07257 if (span >= NUM_SPANS) { 07258 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07259 destroy_zt_pvt(&tmp); 07260 return NULL; 07261 } else { 07262 si.spanno = 0; 07263 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07264 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07265 destroy_zt_pvt(&tmp); 07266 return NULL; 07267 } 07268 /* Store the logical span first based upon the real span */ 07269 tmp->logicalspan = pris[span].prilogicalspan; 07270 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07271 if (span < 0) { 07272 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07273 destroy_zt_pvt(&tmp); 07274 return NULL; 07275 } 07276 if (conf.chan.sig == SIG_PRI) 07277 myswitchtype = conf.pri.switchtype; 07278 else 07279 myswitchtype = PRI_SWITCH_GR303_TMC; 07280 /* Make sure this isn't a d-channel */ 07281 matchesdchan=0; 07282 for (x = 0; x < NUM_SPANS; x++) { 07283 for (y = 0; y < NUM_DCHANS; y++) { 07284 if (pris[x].dchannels[y] == tmp->channel) { 07285 matchesdchan = 1; 07286 break; 07287 } 07288 } 07289 } 07290 offset = p.chanpos; 07291 if (!matchesdchan) { 07292 if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) { 07293 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07294 destroy_zt_pvt(&tmp); 07295 return NULL; 07296 } 07297 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07298 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07299 destroy_zt_pvt(&tmp); 07300 return NULL; 07301 } 07302 if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) { 07303 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07304 destroy_zt_pvt(&tmp); 07305 return NULL; 07306 } 07307 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) { 07308 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial); 07309 destroy_zt_pvt(&tmp); 07310 return NULL; 07311 } 07312 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) { 07313 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext); 07314 destroy_zt_pvt(&tmp); 07315 return NULL; 07316 } 07317 if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) { 07318 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused); 07319 destroy_zt_pvt(&tmp); 07320 return NULL; 07321 } 07322 if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) { 07323 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle); 07324 destroy_zt_pvt(&tmp); 07325 return NULL; 07326 } 07327 if (pris[span].numchans >= MAX_CHANNELS) { 07328 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07329 pris[span].trunkgroup); 07330 destroy_zt_pvt(&tmp); 07331 return NULL; 07332 } 07333 pris[span].nodetype = conf.pri.nodetype; 07334 pris[span].switchtype = myswitchtype; 07335 pris[span].nsf = conf.pri.nsf; 07336 pris[span].dialplan = conf.pri.dialplan; 07337 pris[span].localdialplan = conf.pri.localdialplan; 07338 pris[span].pvts[pris[span].numchans++] = tmp; 07339 pris[span].minunused = conf.pri.minunused; 07340 pris[span].minidle = conf.pri.minidle; 07341 pris[span].overlapdial = conf.pri.overlapdial; 07342 pris[span].facilityenable = conf.pri.facilityenable; 07343 ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial)); 07344 ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext)); 07345 ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07346 ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07347 ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix)); 07348 ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix)); 07349 ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07350 pris[span].resetinterval = conf.pri.resetinterval; 07351 07352 tmp->pri = &pris[span]; 07353 tmp->prioffset = offset; 07354 tmp->call = NULL; 07355 } else { 07356 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07357 destroy_zt_pvt(&tmp); 07358 return NULL; 07359 } 07360 } 07361 } else { 07362 tmp->prioffset = 0; 07363 } 07364 #endif 07365 } else { 07366 conf.chan.sig = tmp->sig; 07367 conf.chan.radio = tmp->radio; 07368 memset(&p, 0, sizeof(p)); 07369 if (tmp->subs[SUB_REAL].zfd > -1) 07370 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07371 } 07372 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07373 if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) || 07374 (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) || (conf.chan.sig == SIG_EMWINK) || 07375 (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) || 07376 (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) || 07377 (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) || 07378 (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) || 07379 (conf.chan.sig == SIG_SF_FEATB)) { 07380 p.starttime = 250; 07381 } 07382 if (conf.chan.radio) { 07383 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07384 p.channo = channel; 07385 p.rxwinktime = 1; 07386 p.rxflashtime = 1; 07387 p.starttime = 1; 07388 p.debouncetime = 5; 07389 } 07390 if (!conf.chan.radio) { 07391 p.channo = channel; 07392 /* Override timing settings based on config file */ 07393 if (conf.timing.prewinktime >= 0) 07394 p.prewinktime = conf.timing.prewinktime; 07395 if (conf.timing.preflashtime >= 0) 07396 p.preflashtime = conf.timing.preflashtime; 07397 if (conf.timing.winktime >= 0) 07398 p.winktime = conf.timing.winktime; 07399 if (conf.timing.flashtime >= 0) 07400 p.flashtime = conf.timing.flashtime; 07401 if (conf.timing.starttime >= 0) 07402 p.starttime = conf.timing.starttime; 07403 if (conf.timing.rxwinktime >= 0) 07404 p.rxwinktime = conf.timing.rxwinktime; 07405 if (conf.timing.rxflashtime >= 0) 07406 p.rxflashtime = conf.timing.rxflashtime; 07407 if (conf.timing.debouncetime >= 0) 07408 p.debouncetime = conf.timing.debouncetime; 07409 } 07410 07411 /* dont set parms on a pseudo-channel (or CRV) */ 07412 if (tmp->subs[SUB_REAL].zfd >= 0) 07413 { 07414 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07415 if (res < 0) { 07416 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07417 destroy_zt_pvt(&tmp); 07418 return NULL; 07419 } 07420 } 07421 #if 1 07422 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07423 memset(&bi, 0, sizeof(bi)); 07424 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07425 if (!res) { 07426 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07427 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07428 bi.numbufs = numbufs; 07429 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07430 if (res < 0) { 07431 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07432 } 07433 } else 07434 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07435 } 07436 #endif 07437 tmp->immediate = conf.chan.immediate; 07438 tmp->transfertobusy = conf.chan.transfertobusy; 07439 tmp->sig = conf.chan.sig; 07440 tmp->outsigmod = conf.chan.outsigmod; 07441 tmp->radio = conf.chan.radio; 07442 tmp->ringt_base = ringt_base; 07443 tmp->firstradio = 0; 07444 if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS)) 07445 tmp->permcallwaiting = conf.chan.callwaiting; 07446 else 07447 tmp->permcallwaiting = 0; 07448 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07449 tmp->destroy = 0; 07450 tmp->drings = drings; 07451 tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection; 07452 tmp->callwaitingcallerid = conf.chan.callwaitingcallerid; 07453 tmp->threewaycalling = conf.chan.threewaycalling; 07454 tmp->adsi = conf.chan.adsi; 07455 tmp->use_smdi = conf.chan.use_smdi; 07456 tmp->permhidecallerid = conf.chan.hidecallerid; 07457 tmp->callreturn = conf.chan.callreturn; 07458 tmp->echocancel = conf.chan.echocancel; 07459 tmp->echotraining = conf.chan.echotraining; 07460 tmp->pulse = conf.chan.pulse; 07461 if (tmp->echocancel) 07462 tmp->echocanbridged = conf.chan.echocanbridged; 07463 else { 07464 if (conf.chan.echocanbridged) 07465 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 07466 tmp->echocanbridged = 0; 07467 } 07468 tmp->busydetect = conf.chan.busydetect; 07469 tmp->busycount = conf.chan.busycount; 07470 tmp->busy_tonelength = conf.chan.busy_tonelength; 07471 tmp->busy_quietlength = conf.chan.busy_quietlength; 07472 tmp->callprogress = conf.chan.callprogress; 07473 tmp->cancallforward = conf.chan.cancallforward; 07474 tmp->dtmfrelax = conf.chan.dtmfrelax; 07475 tmp->callwaiting = tmp->permcallwaiting; 07476 tmp->hidecallerid = tmp->permhidecallerid; 07477 tmp->channel = channel; 07478 tmp->stripmsd = conf.chan.stripmsd; 07479 tmp->use_callerid = conf.chan.use_callerid; 07480 tmp->cid_signalling = conf.chan.cid_signalling; 07481 tmp->cid_start = conf.chan.cid_start; 07482 tmp->zaptrcallerid = conf.chan.zaptrcallerid; 07483 tmp->restrictcid = conf.chan.restrictcid; 07484 tmp->use_callingpres = conf.chan.use_callingpres; 07485 tmp->priindication_oob = conf.chan.priindication_oob; 07486 tmp->priexclusive = conf.chan.priexclusive; 07487 if (tmp->usedistinctiveringdetection) { 07488 if (!tmp->use_callerid) { 07489 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07490 tmp->use_callerid = 1; 07491 } 07492 } 07493 07494 if (tmp->cid_signalling == CID_SIG_SMDI) { 07495 if (!tmp->use_smdi) { 07496 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07497 tmp->use_smdi = 1; 07498 } 07499 } 07500 if (tmp->use_smdi) { 07501 tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port); 07502 if (!(tmp->smdi_iface)) { 07503 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07504 tmp->use_smdi = 0; 07505 } 07506 } 07507 07508 ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode)); 07509 tmp->amaflags = conf.chan.amaflags; 07510 if (!here) { 07511 tmp->confno = -1; 07512 tmp->propconfno = -1; 07513 } 07514 tmp->canpark = conf.chan.canpark; 07515 tmp->transfer = conf.chan.transfer; 07516 ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext)); 07517 ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language)); 07518 ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret)); 07519 ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest)); 07520 ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context)); 07521 ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num)); 07522 tmp->cid_ton = 0; 07523 ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name)); 07524 ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox)); 07525 tmp->msgstate = -1; 07526 tmp->group = conf.chan.group; 07527 tmp->callgroup = conf.chan.callgroup; 07528 tmp->pickupgroup= conf.chan.pickupgroup; 07529 tmp->rxgain = conf.chan.rxgain; 07530 tmp->txgain = conf.chan.txgain; 07531 tmp->tonezone = conf.chan.tonezone; 07532 tmp->onhooktime = time(NULL); 07533 if (tmp->subs[SUB_REAL].zfd > -1) { 07534 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07535 if (tmp->dsp) 07536 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07537 update_conf(tmp); 07538 if (!here) { 07539 if (conf.chan.sig != SIG_PRI) 07540 /* Hang it up to be sure it's good */ 07541 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07542 } 07543 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07544 #ifdef HAVE_PRI 07545 /* the dchannel is down so put the channel in alarm */ 07546 if (tmp->pri && !pri_is_up(tmp->pri)) 07547 tmp->inalarm = 1; 07548 else 07549 tmp->inalarm = 0; 07550 #endif 07551 memset(&si, 0, sizeof(si)); 07552 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07553 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07554 destroy_zt_pvt(&tmp); 07555 return NULL; 07556 } 07557 if (si.alarms) tmp->inalarm = 1; 07558 } 07559 07560 tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay; 07561 tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch; 07562 tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch; 07563 tmp->sendcalleridafter = conf.chan.sendcalleridafter; 07564 07565 } 07566 if (tmp && !here) { 07567 /* nothing on the iflist */ 07568 if (!*wlist) { 07569 *wlist = tmp; 07570 tmp->prev = NULL; 07571 tmp->next = NULL; 07572 *wend = tmp; 07573 } else { 07574 /* at least one member on the iflist */ 07575 struct zt_pvt *working = *wlist; 07576 07577 /* check if we maybe have to put it on the begining */ 07578 if (working->channel > tmp->channel) { 07579 tmp->next = *wlist; 07580 tmp->prev = NULL; 07581 (*wlist)->prev = tmp; 07582 *wlist = tmp; 07583 } else { 07584 /* go through all the members and put the member in the right place */ 07585 while (working) { 07586 /* in the middle */ 07587 if (working->next) { 07588 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07589 tmp->next = working->next; 07590 tmp->prev = working; 07591 working->next->prev = tmp; 07592 working->next = tmp; 07593 break; 07594 } 07595 } else { 07596 /* the last */ 07597 if (working->channel < tmp->channel) { 07598 working->next = tmp; 07599 tmp->next = NULL; 07600 tmp->prev = working; 07601 *wend = tmp; 07602 break; 07603 } 07604 } 07605 working = working->next; 07606 } 07607 } 07608 } 07609 } 07610 return tmp; 07611 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5389 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05390 { 05391 char c; 05392 05393 *str = 0; /* start with empty output buffer */ 05394 for (;;) 05395 { 05396 /* Wait for the first digit (up to specified ms). */ 05397 c = ast_waitfordigit(chan, ms); 05398 /* if timeout, hangup or error, return as such */ 05399 if (c < 1) 05400 return c; 05401 *str++ = c; 05402 *str = 0; 05403 if (strchr(term, c)) 05404 return 1; 05405 } 05406 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 4922 of file chan_zap.c.
References ast_log(), zt_pvt::channel, errno, LOG_DEBUG, option_debug, READ_SIZE, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_write().
04923 { 04924 int sent=0; 04925 int size; 04926 int res; 04927 int fd; 04928 fd = p->subs[index].zfd; 04929 while (len) { 04930 size = len; 04931 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 04932 size = (linear ? READ_SIZE * 2 : READ_SIZE); 04933 res = write(fd, buf, size); 04934 if (res != size) { 04935 if (option_debug) 04936 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 04937 return sent; 04938 } 04939 len -= size; 04940 buf += size; 04941 } 04942 return sent; 04943 }
static int process_zap | ( | struct zt_chan_conf * | confp, | |
struct ast_variable * | v, | |||
int | reload, | |||
int | skipchannels | |||
) | [static] |
Definition at line 10594 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_jb_read_conf(), ast_log(), ast_strlen_zero(), ast_true(), ast_verbose(), build_channels(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, global_jbconf, zt_pvt::group, zt_pvt::hanguponpolarityswitch, HAVE_PRI, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, zt_pvt::immediate, zt_pvt::language, ast_variable::lineno, LOG_ERROR, zt_pvt::mailbox, MAX_CHANLIST_LEN, zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pulse, zt_pvt::radio, READ_SIZE, zt_pvt::restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::rxgain, zt_pvt::sendcalleridafter, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, zt_chan_conf::smdi_port, zt_pvt::stripmsd, strsep(), zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, ast_variable::value, VERBOSE_PREFIX_3, and zt_pvt::zaptrcallerid.
Referenced by setup_zap().
10595 { 10596 struct zt_pvt *tmp; 10597 char *ringc; /* temporary string for parsing the dring number. */ 10598 int y; 10599 int found_pseudo = 0; 10600 char zapchan[MAX_CHANLIST_LEN] = {}; 10601 10602 for (; v; v = v->next) { 10603 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 10604 continue; 10605 10606 /* Create the interface list */ 10607 if (!strcasecmp(v->name, "channel") 10608 #ifdef HAVE_PRI 10609 || !strcasecmp(v->name, "crv") 10610 #endif 10611 ) { 10612 int iscrv; 10613 if (skipchannels) 10614 continue; 10615 iscrv = !strcasecmp(v->name, "crv"); 10616 if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 10617 return -1; 10618 } else if (!strcasecmp(v->name, "zapchan")) { 10619 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 10620 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 10621 if (ast_true(v->value)) 10622 confp->chan.usedistinctiveringdetection = 1; 10623 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 10624 if (ast_true(v->value)) 10625 distinctiveringaftercid = 1; 10626 } else if (!strcasecmp(v->name, "dring1context")) { 10627 ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData)); 10628 } else if (!strcasecmp(v->name, "dring2context")) { 10629 ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData)); 10630 } else if (!strcasecmp(v->name, "dring3context")) { 10631 ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData)); 10632 } else if (!strcasecmp(v->name, "dring1")) { 10633 ringc = v->value; 10634 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 10635 } else if (!strcasecmp(v->name, "dring2")) { 10636 ringc = v->value; 10637 sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 10638 } else if (!strcasecmp(v->name, "dring3")) { 10639 ringc = v->value; 10640 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 10641 } else if (!strcasecmp(v->name, "usecallerid")) { 10642 confp->chan.use_callerid = ast_true(v->value); 10643 } else if (!strcasecmp(v->name, "cidsignalling")) { 10644 if (!strcasecmp(v->value, "bell")) 10645 confp->chan.cid_signalling = CID_SIG_BELL; 10646 else if (!strcasecmp(v->value, "v23")) 10647 confp->chan.cid_signalling = CID_SIG_V23; 10648 else if (!strcasecmp(v->value, "dtmf")) 10649 confp->chan.cid_signalling = CID_SIG_DTMF; 10650 else if (!strcasecmp(v->value, "smdi")) 10651 confp->chan.cid_signalling = CID_SIG_SMDI; 10652 else if (!strcasecmp(v->value, "v23_jp")) 10653 confp->chan.cid_signalling = CID_SIG_V23_JP; 10654 else if (ast_true(v->value)) 10655 confp->chan.cid_signalling = CID_SIG_BELL; 10656 } else if (!strcasecmp(v->name, "cidstart")) { 10657 if (!strcasecmp(v->value, "ring")) 10658 confp->chan.cid_start = CID_START_RING; 10659 else if (!strcasecmp(v->value, "polarity")) 10660 confp->chan.cid_start = CID_START_POLARITY; 10661 else if (ast_true(v->value)) 10662 confp->chan.cid_start = CID_START_RING; 10663 } else if (!strcasecmp(v->name, "threewaycalling")) { 10664 confp->chan.threewaycalling = ast_true(v->value); 10665 } else if (!strcasecmp(v->name, "cancallforward")) { 10666 confp->chan.cancallforward = ast_true(v->value); 10667 } else if (!strcasecmp(v->name, "relaxdtmf")) { 10668 if (ast_true(v->value)) 10669 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 10670 else 10671 confp->chan.dtmfrelax = 0; 10672 } else if (!strcasecmp(v->name, "mailbox")) { 10673 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 10674 } else if (!strcasecmp(v->name, "adsi")) { 10675 confp->chan.adsi = ast_true(v->value); 10676 } else if (!strcasecmp(v->name, "usesmdi")) { 10677 confp->chan.use_smdi = ast_true(v->value); 10678 } else if (!strcasecmp(v->name, "smdiport")) { 10679 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 10680 } else if (!strcasecmp(v->name, "transfer")) { 10681 confp->chan.transfer = ast_true(v->value); 10682 } else if (!strcasecmp(v->name, "canpark")) { 10683 confp->chan.canpark = ast_true(v->value); 10684 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 10685 confp->chan.echocanbridged = ast_true(v->value); 10686 } else if (!strcasecmp(v->name, "busydetect")) { 10687 confp->chan.busydetect = ast_true(v->value); 10688 } else if (!strcasecmp(v->name, "busycount")) { 10689 confp->chan.busycount = atoi(v->value); 10690 } else if (!strcasecmp(v->name, "busypattern")) { 10691 if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 10692 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 10693 } 10694 } else if (!strcasecmp(v->name, "callprogress")) { 10695 if (ast_true(v->value)) 10696 confp->chan.callprogress |= 1; 10697 else 10698 confp->chan.callprogress &= ~1; 10699 } else if (!strcasecmp(v->name, "faxdetect")) { 10700 if (!strcasecmp(v->value, "incoming")) { 10701 confp->chan.callprogress |= 4; 10702 confp->chan.callprogress &= ~2; 10703 } else if (!strcasecmp(v->value, "outgoing")) { 10704 confp->chan.callprogress &= ~4; 10705 confp->chan.callprogress |= 2; 10706 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 10707 confp->chan.callprogress |= 6; 10708 else 10709 confp->chan.callprogress &= ~6; 10710 } else if (!strcasecmp(v->name, "echocancel")) { 10711 if (!ast_strlen_zero(v->value)) { 10712 y = atoi(v->value); 10713 } else 10714 y = 0; 10715 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 10716 confp->chan.echocancel = y; 10717 else { 10718 confp->chan.echocancel = ast_true(v->value); 10719 if (confp->chan.echocancel) 10720 confp->chan.echocancel=128; 10721 } 10722 } else if (!strcasecmp(v->name, "echotraining")) { 10723 if (sscanf(v->value, "%d", &y) == 1) { 10724 if ((y < 10) || (y > 4000)) { 10725 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 10726 } else { 10727 confp->chan.echotraining = y; 10728 } 10729 } else if (ast_true(v->value)) { 10730 confp->chan.echotraining = 400; 10731 } else 10732 confp->chan.echotraining = 0; 10733 } else if (!strcasecmp(v->name, "hidecallerid")) { 10734 confp->chan.hidecallerid = ast_true(v->value); 10735 } else if (!strcasecmp(v->name, "hidecalleridname")) { 10736 confp->chan.hidecalleridname = ast_true(v->value); 10737 } else if (!strcasecmp(v->name, "pulsedial")) { 10738 confp->chan.pulse = ast_true(v->value); 10739 } else if (!strcasecmp(v->name, "callreturn")) { 10740 confp->chan.callreturn = ast_true(v->value); 10741 } else if (!strcasecmp(v->name, "callwaiting")) { 10742 confp->chan.callwaiting = ast_true(v->value); 10743 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 10744 confp->chan.callwaitingcallerid = ast_true(v->value); 10745 } else if (!strcasecmp(v->name, "context")) { 10746 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 10747 } else if (!strcasecmp(v->name, "language")) { 10748 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 10749 } else if (!strcasecmp(v->name, "progzone")) { 10750 ast_copy_string(progzone, v->value, sizeof(progzone)); 10751 } else if (!strcasecmp(v->name, "mohinterpret") 10752 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 10753 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 10754 } else if (!strcasecmp(v->name, "mohsuggest")) { 10755 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 10756 } else if (!strcasecmp(v->name, "stripmsd")) { 10757 confp->chan.stripmsd = atoi(v->value); 10758 } else if (!strcasecmp(v->name, "jitterbuffers")) { 10759 numbufs = atoi(v->value); 10760 } else if (!strcasecmp(v->name, "group")) { 10761 confp->chan.group = ast_get_group(v->value); 10762 } else if (!strcasecmp(v->name, "callgroup")) { 10763 confp->chan.callgroup = ast_get_group(v->value); 10764 } else if (!strcasecmp(v->name, "pickupgroup")) { 10765 confp->chan.pickupgroup = ast_get_group(v->value); 10766 } else if (!strcasecmp(v->name, "immediate")) { 10767 confp->chan.immediate = ast_true(v->value); 10768 } else if (!strcasecmp(v->name, "transfertobusy")) { 10769 confp->chan.transfertobusy = ast_true(v->value); 10770 } else if (!strcasecmp(v->name, "rxgain")) { 10771 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 10772 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 10773 } 10774 } else if (!strcasecmp(v->name, "txgain")) { 10775 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 10776 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 10777 } 10778 } else if (!strcasecmp(v->name, "tonezone")) { 10779 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 10780 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 10781 } 10782 } else if (!strcasecmp(v->name, "callerid")) { 10783 if (!strcasecmp(v->value, "asreceived")) { 10784 confp->chan.cid_num[0] = '\0'; 10785 confp->chan.cid_name[0] = '\0'; 10786 } else { 10787 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 10788 } 10789 } else if (!strcasecmp(v->name, "fullname")) { 10790 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 10791 } else if (!strcasecmp(v->name, "cid_number")) { 10792 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 10793 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 10794 confp->chan.zaptrcallerid = ast_true(v->value); 10795 } else if (!strcasecmp(v->name, "restrictcid")) { 10796 confp->chan.restrictcid = ast_true(v->value); 10797 } else if (!strcasecmp(v->name, "usecallingpres")) { 10798 confp->chan.use_callingpres = ast_true(v->value); 10799 } else if (!strcasecmp(v->name, "accountcode")) { 10800 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 10801 } else if (!strcasecmp(v->name, "amaflags")) { 10802 y = ast_cdr_amaflags2int(v->value); 10803 if (y < 0) 10804 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 10805 else 10806 confp->chan.amaflags = y; 10807 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 10808 confp->chan.polarityonanswerdelay = atoi(v->value); 10809 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 10810 confp->chan.answeronpolarityswitch = ast_true(v->value); 10811 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 10812 confp->chan.hanguponpolarityswitch = ast_true(v->value); 10813 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 10814 confp->chan.sendcalleridafter = atoi(v->value); 10815 } else if (!reload){ 10816 if (!strcasecmp(v->name, "signalling")) { 10817 confp->chan.outsigmod = -1; 10818 if (!strcasecmp(v->value, "em")) { 10819 confp->chan.sig = SIG_EM; 10820 } else if (!strcasecmp(v->value, "em_e1")) { 10821 confp->chan.sig = SIG_EM_E1; 10822 } else if (!strcasecmp(v->value, "em_w")) { 10823 confp->chan.sig = SIG_EMWINK; 10824 confp->chan.radio = 0; 10825 } else if (!strcasecmp(v->value, "fxs_ls")) { 10826 confp->chan.sig = SIG_FXSLS; 10827 confp->chan.radio = 0; 10828 } else if (!strcasecmp(v->value, "fxs_gs")) { 10829 confp->chan.sig = SIG_FXSGS; 10830 confp->chan.radio = 0; 10831 } else if (!strcasecmp(v->value, "fxs_ks")) { 10832 confp->chan.sig = SIG_FXSKS; 10833 confp->chan.radio = 0; 10834 } else if (!strcasecmp(v->value, "fxo_ls")) { 10835 confp->chan.sig = SIG_FXOLS; 10836 confp->chan.radio = 0; 10837 } else if (!strcasecmp(v->value, "fxo_gs")) { 10838 confp->chan.sig = SIG_FXOGS; 10839 confp->chan.radio = 0; 10840 } else if (!strcasecmp(v->value, "fxo_ks")) { 10841 confp->chan.sig = SIG_FXOKS; 10842 confp->chan.radio = 0; 10843 } else if (!strcasecmp(v->value, "fxs_rx")) { 10844 confp->chan.sig = SIG_FXSKS; 10845 confp->chan.radio = 1; 10846 } else if (!strcasecmp(v->value, "fxo_rx")) { 10847 confp->chan.sig = SIG_FXOLS; 10848 confp->chan.radio = 1; 10849 } else if (!strcasecmp(v->value, "fxs_tx")) { 10850 confp->chan.sig = SIG_FXSLS; 10851 confp->chan.radio = 1; 10852 } else if (!strcasecmp(v->value, "fxo_tx")) { 10853 confp->chan.sig = SIG_FXOGS; 10854 confp->chan.radio = 1; 10855 } else if (!strcasecmp(v->value, "em_rx")) { 10856 confp->chan.sig = SIG_EM; 10857 confp->chan.radio = 1; 10858 } else if (!strcasecmp(v->value, "em_tx")) { 10859 confp->chan.sig = SIG_EM; 10860 confp->chan.radio = 1; 10861 } else if (!strcasecmp(v->value, "em_rxtx")) { 10862 confp->chan.sig = SIG_EM; 10863 confp->chan.radio = 2; 10864 } else if (!strcasecmp(v->value, "em_txrx")) { 10865 confp->chan.sig = SIG_EM; 10866 confp->chan.radio = 2; 10867 } else if (!strcasecmp(v->value, "sf")) { 10868 confp->chan.sig = SIG_SF; 10869 confp->chan.radio = 0; 10870 } else if (!strcasecmp(v->value, "sf_w")) { 10871 confp->chan.sig = SIG_SFWINK; 10872 confp->chan.radio = 0; 10873 } else if (!strcasecmp(v->value, "sf_featd")) { 10874 confp->chan.sig = SIG_FEATD; 10875 confp->chan.radio = 0; 10876 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10877 confp->chan.sig = SIG_FEATDMF; 10878 confp->chan.radio = 0; 10879 } else if (!strcasecmp(v->value, "sf_featb")) { 10880 confp->chan.sig = SIG_SF_FEATB; 10881 confp->chan.radio = 0; 10882 } else if (!strcasecmp(v->value, "sf")) { 10883 confp->chan.sig = SIG_SF; 10884 confp->chan.radio = 0; 10885 } else if (!strcasecmp(v->value, "sf_rx")) { 10886 confp->chan.sig = SIG_SF; 10887 confp->chan.radio = 1; 10888 } else if (!strcasecmp(v->value, "sf_tx")) { 10889 confp->chan.sig = SIG_SF; 10890 confp->chan.radio = 1; 10891 } else if (!strcasecmp(v->value, "sf_rxtx")) { 10892 confp->chan.sig = SIG_SF; 10893 confp->chan.radio = 2; 10894 } else if (!strcasecmp(v->value, "sf_txrx")) { 10895 confp->chan.sig = SIG_SF; 10896 confp->chan.radio = 2; 10897 } else if (!strcasecmp(v->value, "featd")) { 10898 confp->chan.sig = SIG_FEATD; 10899 confp->chan.radio = 0; 10900 } else if (!strcasecmp(v->value, "featdmf")) { 10901 confp->chan.sig = SIG_FEATDMF; 10902 confp->chan.radio = 0; 10903 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10904 confp->chan.sig = SIG_FEATDMF_TA; 10905 confp->chan.radio = 0; 10906 } else if (!strcasecmp(v->value, "e911")) { 10907 confp->chan.sig = SIG_E911; 10908 confp->chan.radio = 0; 10909 } else if (!strcasecmp(v->value, "fgccama")) { 10910 confp->chan.sig = SIG_FGC_CAMA; 10911 confp->chan.radio = 0; 10912 } else if (!strcasecmp(v->value, "fgccamamf")) { 10913 confp->chan.sig = SIG_FGC_CAMAMF; 10914 confp->chan.radio = 0; 10915 } else if (!strcasecmp(v->value, "featb")) { 10916 confp->chan.sig = SIG_FEATB; 10917 confp->chan.radio = 0; 10918 #ifdef HAVE_PRI 10919 } else if (!strcasecmp(v->value, "pri_net")) { 10920 confp->chan.radio = 0; 10921 confp->chan.sig = SIG_PRI; 10922 confp->pri.nodetype = PRI_NETWORK; 10923 } else if (!strcasecmp(v->value, "pri_cpe")) { 10924 confp->chan.sig = SIG_PRI; 10925 confp->chan.radio = 0; 10926 confp->pri.nodetype = PRI_CPE; 10927 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 10928 confp->chan.sig = SIG_GR303FXOKS; 10929 confp->chan.radio = 0; 10930 confp->pri.nodetype = PRI_NETWORK; 10931 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 10932 confp->chan.sig = SIG_GR303FXSKS; 10933 confp->chan.radio = 0; 10934 confp->pri.nodetype = PRI_CPE; 10935 #endif 10936 } else { 10937 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10938 } 10939 } else if (!strcasecmp(v->name, "outsignalling")) { 10940 if (!strcasecmp(v->value, "em")) { 10941 confp->chan.outsigmod = SIG_EM; 10942 } else if (!strcasecmp(v->value, "em_e1")) { 10943 confp->chan.outsigmod = SIG_EM_E1; 10944 } else if (!strcasecmp(v->value, "em_w")) { 10945 confp->chan.outsigmod = SIG_EMWINK; 10946 } else if (!strcasecmp(v->value, "sf")) { 10947 confp->chan.outsigmod = SIG_SF; 10948 } else if (!strcasecmp(v->value, "sf_w")) { 10949 confp->chan.outsigmod = SIG_SFWINK; 10950 } else if (!strcasecmp(v->value, "sf_featd")) { 10951 confp->chan.outsigmod = SIG_FEATD; 10952 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10953 confp->chan.outsigmod = SIG_FEATDMF; 10954 } else if (!strcasecmp(v->value, "sf_featb")) { 10955 confp->chan.outsigmod = SIG_SF_FEATB; 10956 } else if (!strcasecmp(v->value, "sf")) { 10957 confp->chan.outsigmod = SIG_SF; 10958 } else if (!strcasecmp(v->value, "featd")) { 10959 confp->chan.outsigmod = SIG_FEATD; 10960 } else if (!strcasecmp(v->value, "featdmf")) { 10961 confp->chan.outsigmod = SIG_FEATDMF; 10962 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10963 confp->chan.outsigmod = SIG_FEATDMF_TA; 10964 } else if (!strcasecmp(v->value, "e911")) { 10965 confp->chan.outsigmod = SIG_E911; 10966 } else if (!strcasecmp(v->value, "fgccama")) { 10967 confp->chan.outsigmod = SIG_FGC_CAMA; 10968 } else if (!strcasecmp(v->value, "fgccamamf")) { 10969 confp->chan.outsigmod = SIG_FGC_CAMAMF; 10970 } else if (!strcasecmp(v->value, "featb")) { 10971 confp->chan.outsigmod = SIG_FEATB; 10972 } else { 10973 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10974 } 10975 #ifdef HAVE_PRI 10976 } else if (!strcasecmp(v->name, "pridialplan")) { 10977 if (!strcasecmp(v->value, "national")) { 10978 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 10979 } else if (!strcasecmp(v->value, "unknown")) { 10980 confp->pri.dialplan = PRI_UNKNOWN + 1; 10981 } else if (!strcasecmp(v->value, "private")) { 10982 confp->pri.dialplan = PRI_PRIVATE + 1; 10983 } else if (!strcasecmp(v->value, "international")) { 10984 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 10985 } else if (!strcasecmp(v->value, "local")) { 10986 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 10987 } else if (!strcasecmp(v->value, "dynamic")) { 10988 confp->pri.dialplan = -1; 10989 } else { 10990 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10991 } 10992 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 10993 if (!strcasecmp(v->value, "national")) { 10994 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 10995 } else if (!strcasecmp(v->value, "unknown")) { 10996 confp->pri.localdialplan = PRI_UNKNOWN + 1; 10997 } else if (!strcasecmp(v->value, "private")) { 10998 confp->pri.localdialplan = PRI_PRIVATE + 1; 10999 } else if (!strcasecmp(v->value, "international")) { 11000 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 11001 } else if (!strcasecmp(v->value, "local")) { 11002 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 11003 } else if (!strcasecmp(v->value, "dynamic")) { 11004 confp->pri.localdialplan = -1; 11005 } else { 11006 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 11007 } 11008 } else if (!strcasecmp(v->name, "switchtype")) { 11009 if (!strcasecmp(v->value, "national")) 11010 confp->pri.switchtype = PRI_SWITCH_NI2; 11011 else if (!strcasecmp(v->value, "ni1")) 11012 confp->pri.switchtype = PRI_SWITCH_NI1; 11013 else if (!strcasecmp(v->value, "dms100")) 11014 confp->pri.switchtype = PRI_SWITCH_DMS100; 11015 else if (!strcasecmp(v->value, "4ess")) 11016 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 11017 else if (!strcasecmp(v->value, "5ess")) 11018 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 11019 else if (!strcasecmp(v->value, "euroisdn")) 11020 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 11021 else if (!strcasecmp(v->value, "qsig")) 11022 confp->pri.switchtype = PRI_SWITCH_QSIG; 11023 else { 11024 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 11025 return -1; 11026 } 11027 } else if (!strcasecmp(v->name, "nsf")) { 11028 if (!strcasecmp(v->value, "sdn")) 11029 confp->pri.nsf = PRI_NSF_SDN; 11030 else if (!strcasecmp(v->value, "megacom")) 11031 confp->pri.nsf = PRI_NSF_MEGACOM; 11032 else if (!strcasecmp(v->value, "tollfreemegacom")) 11033 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 11034 else if (!strcasecmp(v->value, "accunet")) 11035 confp->pri.nsf = PRI_NSF_ACCUNET; 11036 else if (!strcasecmp(v->value, "none")) 11037 confp->pri.nsf = PRI_NSF_NONE; 11038 else { 11039 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 11040 confp->pri.nsf = PRI_NSF_NONE; 11041 } 11042 } else if (!strcasecmp(v->name, "priindication")) { 11043 if (!strcasecmp(v->value, "outofband")) 11044 confp->chan.priindication_oob = 1; 11045 else if (!strcasecmp(v->value, "inband")) 11046 confp->chan.priindication_oob = 0; 11047 else 11048 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n", 11049 v->value, v->lineno); 11050 } else if (!strcasecmp(v->name, "priexclusive")) { 11051 confp->chan.priexclusive = ast_true(v->value); 11052 } else if (!strcasecmp(v->name, "internationalprefix")) { 11053 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 11054 } else if (!strcasecmp(v->name, "nationalprefix")) { 11055 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 11056 } else if (!strcasecmp(v->name, "localprefix")) { 11057 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 11058 } else if (!strcasecmp(v->name, "privateprefix")) { 11059 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 11060 } else if (!strcasecmp(v->name, "unknownprefix")) { 11061 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 11062 } else if (!strcasecmp(v->name, "resetinterval")) { 11063 if (!strcasecmp(v->value, "never")) 11064 confp->pri.resetinterval = -1; 11065 else if (atoi(v->value) >= 60) 11066 confp->pri.resetinterval = atoi(v->value); 11067 else 11068 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 11069 v->value, v->lineno); 11070 } else if (!strcasecmp(v->name, "minunused")) { 11071 confp->pri.minunused = atoi(v->value); 11072 } else if (!strcasecmp(v->name, "minidle")) { 11073 confp->pri.minidle = atoi(v->value); 11074 } else if (!strcasecmp(v->name, "idleext")) { 11075 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 11076 } else if (!strcasecmp(v->name, "idledial")) { 11077 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 11078 } else if (!strcasecmp(v->name, "overlapdial")) { 11079 confp->pri.overlapdial = ast_true(v->value); 11080 } else if (!strcasecmp(v->name, "pritimer")) { 11081 #ifdef PRI_GETSET_TIMERS 11082 char *timerc, *c; 11083 int timer, timeridx; 11084 c = v->value; 11085 timerc = strsep(&c, ","); 11086 if (timerc) { 11087 timer = atoi(c); 11088 if (!timer) 11089 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 11090 else { 11091 if ((timeridx = pri_timer2idx(timerc)) >= 0) 11092 pritimers[timeridx] = timer; 11093 else 11094 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 11095 } 11096 } else 11097 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 11098 11099 } else if (!strcasecmp(v->name, "facilityenable")) { 11100 confp->pri.facilityenable = ast_true(v->value); 11101 #endif /* PRI_GETSET_TIMERS */ 11102 #endif /* HAVE_PRI */ 11103 } else if (!strcasecmp(v->name, "cadence")) { 11104 /* setup to scan our argument */ 11105 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 11106 int i; 11107 struct zt_ring_cadence new_cadence; 11108 int cid_location = -1; 11109 int firstcadencepos = 0; 11110 char original_args[80]; 11111 int cadence_is_ok = 1; 11112 11113 ast_copy_string(original_args, v->value, sizeof(original_args)); 11114 /* 16 cadences allowed (8 pairs) */ 11115 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]); 11116 11117 /* Cadence must be even (on/off) */ 11118 if (element_count % 2 == 1) { 11119 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 11120 cadence_is_ok = 0; 11121 } 11122 11123 /* Ring cadences cannot be negative */ 11124 for (i = 0; i < element_count; i++) { 11125 if (c[i] == 0) { 11126 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 11127 cadence_is_ok = 0; 11128 break; 11129 } else if (c[i] < 0) { 11130 if (i % 2 == 1) { 11131 /* Silence duration, negative possibly okay */ 11132 if (cid_location == -1) { 11133 cid_location = i; 11134 c[i] *= -1; 11135 } else { 11136 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 11137 cadence_is_ok = 0; 11138 break; 11139 } 11140 } else { 11141 if (firstcadencepos == 0) { 11142 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 11143 /* duration will be passed negative to the zaptel driver */ 11144 } else { 11145 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 11146 cadence_is_ok = 0; 11147 break; 11148 } 11149 } 11150 } 11151 } 11152 11153 /* Substitute our scanned cadence */ 11154 for (i = 0; i < 16; i++) { 11155 new_cadence.ringcadence[i] = c[i]; 11156 } 11157 11158 if (cadence_is_ok) { 11159 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 11160 if (element_count < 2) { 11161 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 11162 } else { 11163 if (cid_location == -1) { 11164 /* user didn't say; default to first pause */ 11165 cid_location = 1; 11166 } else { 11167 /* convert element_index to cidrings value */ 11168 cid_location = (cid_location + 1) / 2; 11169 } 11170 /* ---we like their cadence; try to install it--- */ 11171 if (!user_has_defined_cadences++) 11172 /* this is the first user-defined cadence; clear the default user cadences */ 11173 num_cadence = 0; 11174 if ((num_cadence+1) >= NUM_CADENCE_MAX) 11175 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 11176 else { 11177 cadences[num_cadence] = new_cadence; 11178 cidrings[num_cadence++] = cid_location; 11179 if (option_verbose > 2) 11180 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 11181 } 11182 } 11183 } 11184 } else if (!strcasecmp(v->name, "ringtimeout")) { 11185 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 11186 } else if (!strcasecmp(v->name, "prewink")) { 11187 confp->timing.prewinktime = atoi(v->value); 11188 } else if (!strcasecmp(v->name, "preflash")) { 11189 confp->timing.preflashtime = atoi(v->value); 11190 } else if (!strcasecmp(v->name, "wink")) { 11191 confp->timing.winktime = atoi(v->value); 11192 } else if (!strcasecmp(v->name, "flash")) { 11193 confp->timing.flashtime = atoi(v->value); 11194 } else if (!strcasecmp(v->name, "start")) { 11195 confp->timing.starttime = atoi(v->value); 11196 } else if (!strcasecmp(v->name, "rxwink")) { 11197 confp->timing.rxwinktime = atoi(v->value); 11198 } else if (!strcasecmp(v->name, "rxflash")) { 11199 confp->timing.rxflashtime = atoi(v->value); 11200 } else if (!strcasecmp(v->name, "debounce")) { 11201 confp->timing.debouncetime = atoi(v->value); 11202 } else if (!strcasecmp(v->name, "toneduration")) { 11203 int toneduration; 11204 int ctlfd; 11205 int res; 11206 struct zt_dialparams dps; 11207 11208 ctlfd = open("/dev/zap/ctl", O_RDWR); 11209 if (ctlfd == -1) { 11210 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 11211 return -1; 11212 } 11213 11214 toneduration = atoi(v->value); 11215 if (toneduration > -1) { 11216 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 11217 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 11218 if (res < 0) { 11219 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 11220 return -1; 11221 } 11222 } 11223 close(ctlfd); 11224 } else if (!strcasecmp(v->name, "defaultcic")) { 11225 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 11226 } else if (!strcasecmp(v->name, "defaultozz")) { 11227 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 11228 } 11229 } else if (!skipchannels) 11230 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11231 } 11232 if (zapchan[0]) { 11233 /* The user has set 'zapchan' */ 11234 /*< \todo pass proper line number instead of 0 */ 11235 if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) { 11236 return -1; 11237 } 11238 } 11239 /*< \todo why check for the pseudo in the per-channel section. 11240 * Any actual use for manual setup of the pseudo channel? */ 11241 if (!found_pseudo && reload == 0) { 11242 /* Make sure pseudo isn't a member of any groups if 11243 we're automatically making it. */ 11244 11245 confp->chan.group = 0; 11246 confp->chan.callgroup = 0; 11247 confp->chan.pickupgroup = 0; 11248 11249 tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload); 11250 11251 if (tmp) { 11252 if (option_verbose > 2) 11253 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 11254 } else { 11255 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 11256 } 11257 } 11258 return 0; 11259 }
static int reload | ( | void | ) | [static] |
Definition at line 11542 of file chan_zap.c.
References ast_log(), and setup_zap().
11543 { 11544 int res = 0; 11545 11546 res = setup_zap(1); 11547 if (res) { 11548 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 11549 return -1; 11550 } 11551 return 0; 11552 }
static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1343 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_hangup().
01344 { 01345 ZT_CONFINFO zi; 01346 memset(&zi, 0, sizeof(zi)); 01347 p->confno = -1; 01348 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01349 if (p->subs[SUB_REAL].zfd > -1) { 01350 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01351 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01352 } 01353 return 0; 01354 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 7007 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), and LOG_ERROR.
07008 { 07009 pthread_attr_t attr; 07010 pthread_attr_init(&attr); 07011 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07012 /* If we're supposed to be stopped -- stay stopped */ 07013 if (monitor_thread == AST_PTHREADT_STOP) 07014 return 0; 07015 ast_mutex_lock(&monlock); 07016 if (monitor_thread == pthread_self()) { 07017 ast_mutex_unlock(&monlock); 07018 ast_log(LOG_WARNING, "Cannot kill myself\n"); 07019 return -1; 07020 } 07021 if (monitor_thread != AST_PTHREADT_NULL) { 07022 /* Wake up the thread */ 07023 pthread_kill(monitor_thread, SIGURG); 07024 } else { 07025 /* Start a new monitor */ 07026 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 07027 ast_mutex_unlock(&monlock); 07028 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 07029 pthread_attr_destroy(&attr); 07030 return -1; 07031 } 07032 } 07033 ast_mutex_unlock(&monlock); 07034 pthread_attr_destroy(&attr); 07035 return 0; 07036 }
static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1675 of file chan_zap.c.
References ast_log(), errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by send_callerid(), zt_handle_event(), and zt_read().
01676 { 01677 int res; 01678 if (p->saveconf.confmode) { 01679 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01680 p->saveconf.confmode = 0; 01681 if (res) { 01682 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01683 return -1; 01684 } 01685 } 01686 if (option_debug) 01687 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01688 return 0; 01689 }
static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1602 of file chan_zap.c.
References ast_log(), errno, zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread(), and zt_hangup().
01603 { 01604 int res; 01605 01606 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01607 if (res) { 01608 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01609 return -1; 01610 } 01611 01612 return 0; 01613 }
static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1647 of file chan_zap.c.
References ast_log(), errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_callwait(), and zt_handle_event().
01648 { 01649 struct zt_confinfo c; 01650 int res; 01651 if (p->saveconf.confmode) { 01652 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01653 return -1; 01654 } 01655 p->saveconf.chan = 0; 01656 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01657 if (res) { 01658 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01659 p->saveconf.confmode = 0; 01660 return -1; 01661 } 01662 c.chan = 0; 01663 c.confno = 0; 01664 c.confmode = ZT_CONF_NORMAL; 01665 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01666 if (res) { 01667 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01668 return -1; 01669 } 01670 if (option_debug) 01671 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01672 return 0; 01673 }
static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1715 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, errno, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_setlinear().
Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().
01716 { 01717 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01718 int res; 01719 /* Take out of linear mode if necessary */ 01720 if (p->subs[SUB_REAL].linear) { 01721 p->subs[SUB_REAL].linear = 0; 01722 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01723 } 01724 while (p->cidpos < p->cidlen) { 01725 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01726 if (res < 0) { 01727 if (errno == EAGAIN) 01728 return 0; 01729 else { 01730 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01731 return -1; 01732 } 01733 } 01734 if (!res) 01735 return 0; 01736 p->cidpos += res; 01737 } 01738 free(p->cidspill); 01739 p->cidspill = NULL; 01740 if (p->callwaitcas) { 01741 /* Wait for CID/CW to expire */ 01742 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01743 } else 01744 restore_conference(p); 01745 return 0; 01746 }
static int send_cwcidspill | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1693 of file chan_zap.c.
References ast_callerid_callwaiting_generate(), AST_LAW, ast_malloc, 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, MAX_CALLERID_SIZE, option_verbose, READ_SIZE, send_callerid(), and VERBOSE_PREFIX_3.
Referenced by zt_handle_dtmfup().
01694 { 01695 p->callwaitcas = 0; 01696 p->cidcwexpire = 0; 01697 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 01698 return -1; 01699 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01700 /* Make sure we account for the end */ 01701 p->cidlen += READ_SIZE * 4; 01702 p->cidpos = 0; 01703 send_callerid(p); 01704 if (option_verbose > 2) 01705 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01706 return 0; 01707 }
static int set_actual_gain | ( | int | fd, | |
int | chan, | |||
float | rxgain, | |||
float | txgain, | |||
int | law | |||
) | [static] |
Definition at line 1583 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), restore_gains(), and zt_call().
01584 { 01585 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01586 }
static int set_actual_rxgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1565 of file chan_zap.c.
References ast_log(), errno, fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01566 { 01567 struct zt_gains g; 01568 int res; 01569 01570 memset(&g, 0, sizeof(g)); 01571 g.chan = chan; 01572 res = ioctl(fd, ZT_GETGAINS, &g); 01573 if (res) { 01574 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01575 return res; 01576 } 01577 01578 fill_rxgain(&g, gain, law); 01579 01580 return ioctl(fd, ZT_SETGAINS, &g); 01581 }
static int set_actual_txgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1546 of file chan_zap.c.
References ast_log(), errno, fill_txgain(), LOG_DEBUG, and option_debug.
Referenced by set_actual_gain(), and zt_setoption().
01547 { 01548 struct zt_gains g; 01549 int res; 01550 01551 memset(&g, 0, sizeof(g)); 01552 g.chan = chan; 01553 res = ioctl(fd, ZT_GETGAINS, &g); 01554 if (res) { 01555 if (option_debug) 01556 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01557 return res; 01558 } 01559 01560 fill_txgain(&g, gain, law); 01561 01562 return ioctl(fd, ZT_SETGAINS, &g); 01563 }
static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 11261 of file chan_zap.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), default_jbconf, global_jbconf, ast_variable::lineno, LOG_ERROR, ast_variable::name, ast_variable::next, option_verbose, process_zap(), restart_monitor(), ast_variable::value, VERBOSE_PREFIX_2, and zt_chan_conf_default().
Referenced by load_module(), reload(), and zap_restart().
11262 { 11263 struct ast_config *cfg; 11264 struct ast_variable *v; 11265 struct zt_chan_conf conf = zt_chan_conf_default(); 11266 int res; 11267 11268 #ifdef HAVE_PRI 11269 char *c; 11270 int spanno; 11271 int i, x; 11272 int logicalspan; 11273 int trunkgroup; 11274 int dchannels[NUM_DCHANS]; 11275 #endif 11276 11277 cfg = ast_config_load(config); 11278 11279 /* Error if we have no config file */ 11280 if (!cfg) { 11281 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 11282 return 0; 11283 } 11284 11285 /* It's a little silly to lock it, but we mind as well just to be sure */ 11286 ast_mutex_lock(&iflock); 11287 #ifdef HAVE_PRI 11288 if (!reload) { 11289 /* Process trunkgroups first */ 11290 v = ast_variable_browse(cfg, "trunkgroups"); 11291 while (v) { 11292 if (!strcasecmp(v->name, "trunkgroup")) { 11293 trunkgroup = atoi(v->value); 11294 if (trunkgroup > 0) { 11295 if ((c = strchr(v->value, ','))) { 11296 i = 0; 11297 memset(dchannels, 0, sizeof(dchannels)); 11298 while (c && (i < NUM_DCHANS)) { 11299 dchannels[i] = atoi(c + 1); 11300 if (dchannels[i] < 0) { 11301 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); 11302 } else 11303 i++; 11304 c = strchr(c + 1, ','); 11305 } 11306 if (i) { 11307 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 11308 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); 11309 } else if (option_verbose > 1) 11310 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"); 11311 } else 11312 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 11313 } else 11314 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 11315 } else 11316 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 11317 } else if (!strcasecmp(v->name, "spanmap")) { 11318 spanno = atoi(v->value); 11319 if (spanno > 0) { 11320 if ((c = strchr(v->value, ','))) { 11321 trunkgroup = atoi(c + 1); 11322 if (trunkgroup > 0) { 11323 if ((c = strchr(c + 1, ','))) 11324 logicalspan = atoi(c + 1); 11325 else 11326 logicalspan = 0; 11327 if (logicalspan >= 0) { 11328 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 11329 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11330 } else if (option_verbose > 1) 11331 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11332 } else 11333 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 11334 } else 11335 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 11336 } else 11337 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 11338 } else 11339 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 11340 } else { 11341 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 11342 } 11343 v = v->next; 11344 } 11345 } 11346 #endif 11347 11348 /* Copy the default jb config over global_jbconf */ 11349 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 11350 11351 v = ast_variable_browse(cfg, "channels"); 11352 res = process_zap(&conf, v, reload, 0); 11353 ast_mutex_unlock(&iflock); 11354 ast_config_destroy(cfg); 11355 if (res) 11356 return res; 11357 cfg = ast_config_load("users.conf"); 11358 if (cfg) { 11359 char *cat; 11360 const char *chans; 11361 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 11362 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 11363 if (!strcasecmp(cat, "general")) 11364 continue; 11365 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 11366 if (!ast_strlen_zero(chans)) { 11367 /** \todo At this point we should probably 11368 * duplicate conf, and pass a copy, to prevent 11369 * one section from affecting another 11370 */ 11371 process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0); 11372 } 11373 } 11374 ast_config_destroy(cfg); 11375 } 11376 #ifdef HAVE_PRI 11377 if (!reload) { 11378 for (x = 0; x < NUM_SPANS; x++) { 11379 if (pris[x].pvts[0]) { 11380 if (start_pri(pris + x)) { 11381 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 11382 return -1; 11383 } else if (option_verbose > 1) 11384 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 11385 } 11386 } 11387 } 11388 #endif 11389 /* And start the monitor for the first time */ 11390 restart_monitor(); 11391 return 0; 11392 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5426 of file chan_zap.c.
References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), ast_smdi_md_message::calling_st, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::context, ast_channel::context, ringContextData::contextData, counter, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, errno, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, f, free, func, ast_smdi_md_message::fwd_st, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, zt_pvt::lastcid_num, len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, manager_event(), my_getsigstr(), name, NEED_MFDETECT, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, timeout, zt_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zap_tech, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().
Referenced by handle_init_event(), and zt_handle_event().
05427 { 05428 struct ast_channel *chan = data; 05429 struct zt_pvt *p = chan->tech_pvt; 05430 char exten[AST_MAX_EXTENSION] = ""; 05431 char exten2[AST_MAX_EXTENSION] = ""; 05432 unsigned char buf[256]; 05433 char dtmfcid[300]; 05434 char dtmfbuf[300]; 05435 struct callerid_state *cs = NULL; 05436 char *name = NULL, *number = NULL; 05437 int distMatches; 05438 int curRingData[3]; 05439 int receivedRingT; 05440 int counter1; 05441 int counter; 05442 int samples = 0; 05443 struct ast_smdi_md_message *smdi_msg = NULL; 05444 int flags; 05445 int i; 05446 int timeout; 05447 int getforward = 0; 05448 char *s1, *s2; 05449 int len = 0; 05450 int res; 05451 int index; 05452 05453 /* in the bizarre case where the channel has become a zombie before we 05454 even get started here, abort safely 05455 */ 05456 if (!p) { 05457 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05458 ast_hangup(chan); 05459 return NULL; 05460 } 05461 05462 if (option_verbose > 2) 05463 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05464 index = zt_get_index(chan, p, 1); 05465 if (index < 0) { 05466 ast_log(LOG_WARNING, "Huh?\n"); 05467 ast_hangup(chan); 05468 return NULL; 05469 } 05470 if (p->dsp) 05471 ast_dsp_digitreset(p->dsp); 05472 switch (p->sig) { 05473 #ifdef HAVE_PRI 05474 case SIG_PRI: 05475 /* Now loop looking for an extension */ 05476 ast_copy_string(exten, p->exten, sizeof(exten)); 05477 len = strlen(exten); 05478 res = 0; 05479 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05480 if (len && !ast_ignore_pattern(chan->context, exten)) 05481 tone_zone_play_tone(p->subs[index].zfd, -1); 05482 else 05483 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05484 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05485 timeout = matchdigittimeout; 05486 else 05487 timeout = gendigittimeout; 05488 res = ast_waitfordigit(chan, timeout); 05489 if (res < 0) { 05490 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05491 ast_hangup(chan); 05492 return NULL; 05493 } else if (res) { 05494 exten[len++] = res; 05495 exten[len] = '\0'; 05496 } else 05497 break; 05498 } 05499 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05500 if (ast_strlen_zero(exten)) { 05501 if (option_verbose > 2) 05502 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05503 exten[0] = 's'; 05504 exten[1] = '\0'; 05505 } 05506 tone_zone_play_tone(p->subs[index].zfd, -1); 05507 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05508 /* Start the real PBX */ 05509 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05510 if (p->dsp) ast_dsp_digitreset(p->dsp); 05511 zt_enable_ec(p); 05512 ast_setstate(chan, AST_STATE_RING); 05513 res = ast_pbx_run(chan); 05514 if (res) { 05515 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05516 } 05517 } else { 05518 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05519 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05520 ast_hangup(chan); 05521 p->exten[0] = '\0'; 05522 /* Since we send release complete here, we won't get one */ 05523 p->call = NULL; 05524 } 05525 return NULL; 05526 break; 05527 #endif 05528 case SIG_FEATD: 05529 case SIG_FEATDMF: 05530 case SIG_FEATDMF_TA: 05531 case SIG_E911: 05532 case SIG_FGC_CAMAMF: 05533 case SIG_FEATB: 05534 case SIG_EMWINK: 05535 case SIG_SF_FEATD: 05536 case SIG_SF_FEATDMF: 05537 case SIG_SF_FEATB: 05538 case SIG_SFWINK: 05539 if (zt_wink(p, index)) 05540 return NULL; 05541 /* Fall through */ 05542 case SIG_EM: 05543 case SIG_EM_E1: 05544 case SIG_SF: 05545 case SIG_FGC_CAMA: 05546 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05547 if (p->dsp) 05548 ast_dsp_digitreset(p->dsp); 05549 /* set digit mode appropriately */ 05550 if (p->dsp) { 05551 if (NEED_MFDETECT(p)) 05552 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05553 else 05554 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05555 } 05556 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05557 /* Wait for the first digit only if immediate=no */ 05558 if (!p->immediate) 05559 /* Wait for the first digit (up to 5 seconds). */ 05560 res = ast_waitfordigit(chan, 5000); 05561 else 05562 res = 0; 05563 if (res > 0) { 05564 /* save first char */ 05565 dtmfbuf[0] = res; 05566 switch (p->sig) { 05567 case SIG_FEATD: 05568 case SIG_SF_FEATD: 05569 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05570 if (res > 0) 05571 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05572 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05573 break; 05574 case SIG_FEATDMF_TA: 05575 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05576 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05577 if (zt_wink(p, index)) return NULL; 05578 dtmfbuf[0] = 0; 05579 /* Wait for the first digit (up to 5 seconds). */ 05580 res = ast_waitfordigit(chan, 5000); 05581 if (res <= 0) break; 05582 dtmfbuf[0] = res; 05583 /* fall through intentionally */ 05584 case SIG_FEATDMF: 05585 case SIG_E911: 05586 case SIG_FGC_CAMAMF: 05587 case SIG_SF_FEATDMF: 05588 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05589 /* if international caca, do it again to get real ANO */ 05590 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05591 { 05592 if (zt_wink(p, index)) return NULL; 05593 dtmfbuf[0] = 0; 05594 /* Wait for the first digit (up to 5 seconds). */ 05595 res = ast_waitfordigit(chan, 5000); 05596 if (res <= 0) break; 05597 dtmfbuf[0] = res; 05598 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05599 } 05600 if (res > 0) { 05601 /* if E911, take off hook */ 05602 if (p->sig == SIG_E911) 05603 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05604 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05605 } 05606 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05607 break; 05608 case SIG_FEATB: 05609 case SIG_SF_FEATB: 05610 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05611 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05612 break; 05613 case SIG_EMWINK: 05614 /* if we received a '*', we are actually receiving Feature Group D 05615 dial syntax, so use that mode; otherwise, fall through to normal 05616 mode 05617 */ 05618 if (res == '*') { 05619 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05620 if (res > 0) 05621 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05622 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05623 break; 05624 } 05625 default: 05626 /* If we got the first digit, get the rest */ 05627 len = 1; 05628 dtmfbuf[len] = '\0'; 05629 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05630 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05631 timeout = matchdigittimeout; 05632 } else { 05633 timeout = gendigittimeout; 05634 } 05635 res = ast_waitfordigit(chan, timeout); 05636 if (res < 0) { 05637 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05638 ast_hangup(chan); 05639 return NULL; 05640 } else if (res) { 05641 dtmfbuf[len++] = res; 05642 dtmfbuf[len] = '\0'; 05643 } else { 05644 break; 05645 } 05646 } 05647 break; 05648 } 05649 } 05650 if (res == -1) { 05651 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05652 ast_hangup(chan); 05653 return NULL; 05654 } else if (res < 0) { 05655 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05656 ast_hangup(chan); 05657 return NULL; 05658 } 05659 05660 if (p->sig == SIG_FGC_CAMA) { 05661 char anibuf[100]; 05662 05663 if (ast_safe_sleep(chan,1000) == -1) { 05664 ast_hangup(chan); 05665 return NULL; 05666 } 05667 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05668 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05669 res = my_getsigstr(chan, anibuf, "#", 10000); 05670 if ((res > 0) && (strlen(anibuf) > 2)) { 05671 if (anibuf[strlen(anibuf) - 1] == '#') 05672 anibuf[strlen(anibuf) - 1] = 0; 05673 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05674 } 05675 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05676 } 05677 05678 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05679 if (ast_strlen_zero(exten)) 05680 ast_copy_string(exten, "s", sizeof(exten)); 05681 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05682 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05683 if (exten[0] == '*') { 05684 char *stringp=NULL; 05685 ast_copy_string(exten2, exten, sizeof(exten2)); 05686 /* Parse out extension and callerid */ 05687 stringp=exten2 +1; 05688 s1 = strsep(&stringp, "*"); 05689 s2 = strsep(&stringp, "*"); 05690 if (s2) { 05691 if (!ast_strlen_zero(p->cid_num)) 05692 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05693 else 05694 ast_set_callerid(chan, s1, NULL, s1); 05695 ast_copy_string(exten, s2, sizeof(exten)); 05696 } else 05697 ast_copy_string(exten, s1, sizeof(exten)); 05698 } else if (p->sig == SIG_FEATD) 05699 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05700 } 05701 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05702 if (exten[0] == '*') { 05703 char *stringp=NULL; 05704 ast_copy_string(exten2, exten, sizeof(exten2)); 05705 /* Parse out extension and callerid */ 05706 stringp=exten2 +1; 05707 s1 = strsep(&stringp, "#"); 05708 s2 = strsep(&stringp, "#"); 05709 if (s2) { 05710 if (!ast_strlen_zero(p->cid_num)) 05711 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05712 else 05713 if (*(s1 + 2)) 05714 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05715 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05716 } else 05717 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05718 } else 05719 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05720 } 05721 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05722 if (exten[0] == '*') { 05723 char *stringp=NULL; 05724 ast_copy_string(exten2, exten, sizeof(exten2)); 05725 /* Parse out extension and callerid */ 05726 stringp=exten2 +1; 05727 s1 = strsep(&stringp, "#"); 05728 s2 = strsep(&stringp, "#"); 05729 if (s2 && (*(s2 + 1) == '0')) { 05730 if (*(s2 + 2)) 05731 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05732 } 05733 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05734 else ast_copy_string(exten, "911", sizeof(exten)); 05735 } else 05736 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 05737 } 05738 if (p->sig == SIG_FEATB) { 05739 if (exten[0] == '*') { 05740 char *stringp=NULL; 05741 ast_copy_string(exten2, exten, sizeof(exten2)); 05742 /* Parse out extension and callerid */ 05743 stringp=exten2 +1; 05744 s1 = strsep(&stringp, "#"); 05745 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05746 } else 05747 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05748 } 05749 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05750 zt_wink(p, index); 05751 /* some switches require a minimum guard time between 05752 the last FGD wink and something that answers 05753 immediately. This ensures it */ 05754 if (ast_safe_sleep(chan,100)) return NULL; 05755 } 05756 zt_enable_ec(p); 05757 if (NEED_MFDETECT(p)) { 05758 if (p->dsp) { 05759 if (!p->hardwaredtmf) 05760 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05761 else { 05762 ast_dsp_free(p->dsp); 05763 p->dsp = NULL; 05764 } 05765 } 05766 } 05767 05768 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05769 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05770 if (p->dsp) ast_dsp_digitreset(p->dsp); 05771 res = ast_pbx_run(chan); 05772 if (res) { 05773 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05774 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05775 } 05776 return NULL; 05777 } else { 05778 if (option_verbose > 2) 05779 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05780 sleep(2); 05781 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05782 if (res < 0) 05783 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05784 else 05785 sleep(1); 05786 res = ast_streamfile(chan, "ss-noservice", chan->language); 05787 if (res >= 0) 05788 ast_waitstream(chan, ""); 05789 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05790 ast_hangup(chan); 05791 return NULL; 05792 } 05793 break; 05794 case SIG_FXOLS: 05795 case SIG_FXOGS: 05796 case SIG_FXOKS: 05797 /* Read the first digit */ 05798 timeout = firstdigittimeout; 05799 /* If starting a threeway call, never timeout on the first digit so someone 05800 can use flash-hook as a "hold" feature */ 05801 if (p->subs[SUB_THREEWAY].owner) 05802 timeout = 999999; 05803 while (len < AST_MAX_EXTENSION-1) { 05804 /* Read digit unless it's supposed to be immediate, in which case the 05805 only answer is 's' */ 05806 if (p->immediate) 05807 res = 's'; 05808 else 05809 res = ast_waitfordigit(chan, timeout); 05810 timeout = 0; 05811 if (res < 0) { 05812 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05813 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05814 ast_hangup(chan); 05815 return NULL; 05816 } else if (res) { 05817 exten[len++]=res; 05818 exten[len] = '\0'; 05819 } 05820 if (!ast_ignore_pattern(chan->context, exten)) 05821 tone_zone_play_tone(p->subs[index].zfd, -1); 05822 else 05823 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05824 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05825 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05826 if (getforward) { 05827 /* Record this as the forwarding extension */ 05828 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05829 if (option_verbose > 2) 05830 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 05831 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05832 if (res) 05833 break; 05834 usleep(500000); 05835 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05836 sleep(1); 05837 memset(exten, 0, sizeof(exten)); 05838 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05839 len = 0; 05840 getforward = 0; 05841 } else { 05842 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05843 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05844 if (!ast_strlen_zero(p->cid_num)) { 05845 if (!p->hidecallerid) 05846 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05847 else 05848 ast_set_callerid(chan, NULL, NULL, p->cid_num); 05849 } 05850 if (!ast_strlen_zero(p->cid_name)) { 05851 if (!p->hidecallerid) 05852 ast_set_callerid(chan, NULL, p->cid_name, NULL); 05853 } 05854 ast_setstate(chan, AST_STATE_RING); 05855 zt_enable_ec(p); 05856 res = ast_pbx_run(chan); 05857 if (res) { 05858 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05859 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05860 } 05861 return NULL; 05862 } 05863 } else { 05864 /* It's a match, but they just typed a digit, and there is an ambiguous match, 05865 so just set the timeout to matchdigittimeout and wait some more */ 05866 timeout = matchdigittimeout; 05867 } 05868 } else if (res == 0) { 05869 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 05870 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05871 zt_wait_event(p->subs[index].zfd); 05872 ast_hangup(chan); 05873 return NULL; 05874 } else if (p->callwaiting && !strcmp(exten, "*70")) { 05875 if (option_verbose > 2) 05876 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 05877 /* Disable call waiting if enabled */ 05878 p->callwaiting = 0; 05879 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05880 if (res) { 05881 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05882 chan->name, strerror(errno)); 05883 } 05884 len = 0; 05885 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 05886 memset(exten, 0, sizeof(exten)); 05887 timeout = firstdigittimeout; 05888 05889 } else if (!strcmp(exten,ast_pickup_ext())) { 05890 /* Scan all channels and see if there are any 05891 * ringing channels that have call groups 05892 * that equal this channels pickup group 05893 */ 05894 if (index == SUB_REAL) { 05895 /* Switch us from Third call to Call Wait */ 05896 if (p->subs[SUB_THREEWAY].owner) { 05897 /* If you make a threeway call and the *8# a call, it should actually 05898 look like a callwait */ 05899 alloc_sub(p, SUB_CALLWAIT); 05900 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 05901 unalloc_sub(p, SUB_THREEWAY); 05902 } 05903 zt_enable_ec(p); 05904 if (ast_pickup_call(chan)) { 05905 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 05906 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05907 zt_wait_event(p->subs[index].zfd); 05908 } 05909 ast_hangup(chan); 05910 return NULL; 05911 } else { 05912 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 05913 ast_hangup(chan); 05914 return NULL; 05915 } 05916 05917 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 05918 if (option_verbose > 2) 05919 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 05920 /* Disable Caller*ID if enabled */ 05921 p->hidecallerid = 1; 05922 if (chan->cid.cid_num) 05923 free(chan->cid.cid_num); 05924 chan->cid.cid_num = NULL; 05925 if (chan->cid.cid_name) 05926 free(chan->cid.cid_name); 05927 chan->cid.cid_name = NULL; 05928 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05929 if (res) { 05930 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05931 chan->name, strerror(errno)); 05932 } 05933 len = 0; 05934 memset(exten, 0, sizeof(exten)); 05935 timeout = firstdigittimeout; 05936 } else if (p->callreturn && !strcmp(exten, "*69")) { 05937 res = 0; 05938 if (!ast_strlen_zero(p->lastcid_num)) { 05939 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 05940 } 05941 if (!res) 05942 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05943 break; 05944 } else if (!strcmp(exten, "*78")) { 05945 /* Do not disturb */ 05946 if (option_verbose > 2) 05947 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 05948 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05949 "Channel: Zap/%d\r\n" 05950 "Status: enabled\r\n", p->channel); 05951 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05952 p->dnd = 1; 05953 getforward = 0; 05954 memset(exten, 0, sizeof(exten)); 05955 len = 0; 05956 } else if (!strcmp(exten, "*79")) { 05957 /* Do not disturb */ 05958 if (option_verbose > 2) 05959 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 05960 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05961 "Channel: Zap/%d\r\n" 05962 "Status: disabled\r\n", p->channel); 05963 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05964 p->dnd = 0; 05965 getforward = 0; 05966 memset(exten, 0, sizeof(exten)); 05967 len = 0; 05968 } else if (p->cancallforward && !strcmp(exten, "*72")) { 05969 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05970 getforward = 1; 05971 memset(exten, 0, sizeof(exten)); 05972 len = 0; 05973 } else if (p->cancallforward && !strcmp(exten, "*73")) { 05974 if (option_verbose > 2) 05975 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 05976 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05977 memset(p->call_forward, 0, sizeof(p->call_forward)); 05978 getforward = 0; 05979 memset(exten, 0, sizeof(exten)); 05980 len = 0; 05981 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 05982 p->subs[SUB_THREEWAY].owner && 05983 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 05984 /* This is a three way call, the main call being a real channel, 05985 and we're parking the first call. */ 05986 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 05987 if (option_verbose > 2) 05988 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 05989 break; 05990 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 05991 if (option_verbose > 2) 05992 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 05993 res = ast_db_put("blacklist", p->lastcid_num, "1"); 05994 if (!res) { 05995 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05996 memset(exten, 0, sizeof(exten)); 05997 len = 0; 05998 } 05999 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 06000 if (option_verbose > 2) 06001 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 06002 /* Enable Caller*ID if enabled */ 06003 p->hidecallerid = 0; 06004 if (chan->cid.cid_num) 06005 free(chan->cid.cid_num); 06006 chan->cid.cid_num = NULL; 06007 if (chan->cid.cid_name) 06008 free(chan->cid.cid_name); 06009 chan->cid.cid_name = NULL; 06010 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 06011 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06012 if (res) { 06013 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06014 chan->name, strerror(errno)); 06015 } 06016 len = 0; 06017 memset(exten, 0, sizeof(exten)); 06018 timeout = firstdigittimeout; 06019 } else if (!strcmp(exten, "*0")) { 06020 struct ast_channel *nbridge = 06021 p->subs[SUB_THREEWAY].owner; 06022 struct zt_pvt *pbridge = NULL; 06023 /* set up the private struct of the bridged one, if any */ 06024 if (nbridge && ast_bridged_channel(nbridge)) 06025 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 06026 if (nbridge && pbridge && 06027 (nbridge->tech == &zap_tech) && 06028 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 06029 ISTRUNK(pbridge)) { 06030 int func = ZT_FLASH; 06031 /* Clear out the dial buffer */ 06032 p->dop.dialstr[0] = '\0'; 06033 /* flash hookswitch */ 06034 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 06035 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 06036 nbridge->name, strerror(errno)); 06037 } 06038 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06039 unalloc_sub(p, SUB_THREEWAY); 06040 p->owner = p->subs[SUB_REAL].owner; 06041 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06042 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06043 ast_hangup(chan); 06044 return NULL; 06045 } else { 06046 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06047 zt_wait_event(p->subs[index].zfd); 06048 tone_zone_play_tone(p->subs[index].zfd, -1); 06049 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06050 unalloc_sub(p, SUB_THREEWAY); 06051 p->owner = p->subs[SUB_REAL].owner; 06052 ast_hangup(chan); 06053 return NULL; 06054 } 06055 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06056 ((exten[0] != '*') || (strlen(exten) > 2))) { 06057 if (option_debug) 06058 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); 06059 break; 06060 } 06061 if (!timeout) 06062 timeout = gendigittimeout; 06063 if (len && !ast_ignore_pattern(chan->context, exten)) 06064 tone_zone_play_tone(p->subs[index].zfd, -1); 06065 } 06066 break; 06067 case SIG_FXSLS: 06068 case SIG_FXSGS: 06069 case SIG_FXSKS: 06070 #ifdef HAVE_PRI 06071 if (p->pri) { 06072 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06073 struct ast_frame *f; 06074 int res; 06075 time_t start; 06076 06077 time(&start); 06078 ast_setstate(chan, AST_STATE_RING); 06079 while (time(NULL) < start + 3) { 06080 res = ast_waitfor(chan, 1000); 06081 if (res) { 06082 f = ast_read(chan); 06083 if (!f) { 06084 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06085 ast_hangup(chan); 06086 return NULL; 06087 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06088 res = 1; 06089 } else 06090 res = 0; 06091 ast_frfree(f); 06092 if (res) { 06093 ast_log(LOG_DEBUG, "Got ring!\n"); 06094 res = 0; 06095 break; 06096 } 06097 } 06098 } 06099 } 06100 #endif 06101 /* check for SMDI messages */ 06102 if (p->use_smdi && p->smdi_iface) { 06103 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06104 06105 if (smdi_msg != NULL) { 06106 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06107 06108 if (smdi_msg->type == 'B') 06109 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06110 else if (smdi_msg->type == 'N') 06111 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06112 06113 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06114 } else { 06115 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06116 } 06117 } 06118 06119 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06120 number = smdi_msg->calling_st; 06121 06122 /* If we want caller id, we're in a prering state due to a polarity reversal 06123 * and we're set to use a polarity reversal to trigger the start of caller id, 06124 * grab the caller id and wait for ringing to start... */ 06125 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06126 /* If set to use DTMF CID signalling, listen for DTMF */ 06127 if (p->cid_signalling == CID_SIG_DTMF) { 06128 int i = 0; 06129 cs = NULL; 06130 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06131 "channel %s\n", chan->name); 06132 zt_setlinear(p->subs[index].zfd, 0); 06133 res = 2000; 06134 for (;;) { 06135 struct ast_frame *f; 06136 res = ast_waitfor(chan, res); 06137 if (res <= 0) { 06138 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06139 "Exiting simple switch\n"); 06140 ast_hangup(chan); 06141 return NULL; 06142 } 06143 f = ast_read(chan); 06144 if (!f) 06145 break; 06146 if (f->frametype == AST_FRAME_DTMF) { 06147 dtmfbuf[i++] = f->subclass; 06148 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06149 res = 2000; 06150 } 06151 ast_frfree(f); 06152 if (chan->_state == AST_STATE_RING || 06153 chan->_state == AST_STATE_RINGING) 06154 break; /* Got ring */ 06155 } 06156 dtmfbuf[i] = '\0'; 06157 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06158 /* Got cid and ring. */ 06159 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06160 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06161 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06162 dtmfcid, flags); 06163 /* If first byte is NULL, we have no cid */ 06164 if (!ast_strlen_zero(dtmfcid)) 06165 number = dtmfcid; 06166 else 06167 number = NULL; 06168 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06169 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06170 cs = callerid_new(p->cid_signalling); 06171 if (cs) { 06172 samples = 0; 06173 #if 1 06174 bump_gains(p); 06175 #endif 06176 /* Take out of linear mode for Caller*ID processing */ 06177 zt_setlinear(p->subs[index].zfd, 0); 06178 06179 /* First we wait and listen for the Caller*ID */ 06180 for (;;) { 06181 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06182 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06183 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06184 callerid_free(cs); 06185 ast_hangup(chan); 06186 return NULL; 06187 } 06188 if (i & ZT_IOMUX_SIGEVENT) { 06189 res = zt_get_event(p->subs[index].zfd); 06190 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06191 06192 if (p->cid_signalling == CID_SIG_V23_JP) { 06193 #ifdef ZT_EVENT_RINGBEGIN 06194 if (res == ZT_EVENT_RINGBEGIN) { 06195 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06196 usleep(1); 06197 } 06198 #endif 06199 } else { 06200 res = 0; 06201 break; 06202 } 06203 } else if (i & ZT_IOMUX_READ) { 06204 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06205 if (res < 0) { 06206 if (errno != ELAST) { 06207 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06208 callerid_free(cs); 06209 ast_hangup(chan); 06210 return NULL; 06211 } 06212 break; 06213 } 06214 samples += res; 06215 06216 if (p->cid_signalling == CID_SIG_V23_JP) { 06217 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06218 } else { 06219 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06220 } 06221 06222 if (res < 0) { 06223 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06224 break; 06225 } else if (res) 06226 break; 06227 else if (samples > (8000 * 10)) 06228 break; 06229 } 06230 } 06231 if (res == 1) { 06232 callerid_get(cs, &name, &number, &flags); 06233 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06234 } 06235 if (res < 0) { 06236 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06237 } 06238 06239 if (p->cid_signalling == CID_SIG_V23_JP) { 06240 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06241 usleep(1); 06242 res = 4000; 06243 } else { 06244 06245 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06246 res = 2000; 06247 } 06248 06249 for (;;) { 06250 struct ast_frame *f; 06251 res = ast_waitfor(chan, res); 06252 if (res <= 0) { 06253 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06254 "Exiting simple switch\n"); 06255 ast_hangup(chan); 06256 return NULL; 06257 } 06258 f = ast_read(chan); 06259 ast_frfree(f); 06260 if (chan->_state == AST_STATE_RING || 06261 chan->_state == AST_STATE_RINGING) 06262 break; /* Got ring */ 06263 } 06264 06265 /* We must have a ring by now, so, if configured, lets try to listen for 06266 * distinctive ringing */ 06267 if (p->usedistinctiveringdetection == 1) { 06268 len = 0; 06269 distMatches = 0; 06270 /* Clear the current ring data array so we dont have old data in it. */ 06271 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06272 curRingData[receivedRingT] = 0; 06273 receivedRingT = 0; 06274 counter = 0; 06275 counter1 = 0; 06276 /* Check to see if context is what it should be, if not set to be. */ 06277 if (strcmp(p->context,p->defcontext) != 0) { 06278 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06279 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06280 } 06281 06282 for (;;) { 06283 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06284 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06285 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06286 callerid_free(cs); 06287 ast_hangup(chan); 06288 return NULL; 06289 } 06290 if (i & ZT_IOMUX_SIGEVENT) { 06291 res = zt_get_event(p->subs[index].zfd); 06292 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06293 res = 0; 06294 /* Let us detect distinctive ring */ 06295 06296 curRingData[receivedRingT] = p->ringt; 06297 06298 if (p->ringt < p->ringt_base/2) 06299 break; 06300 /* Increment the ringT counter so we can match it against 06301 values in zapata.conf for distinctive ring */ 06302 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06303 break; 06304 } else if (i & ZT_IOMUX_READ) { 06305 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06306 if (res < 0) { 06307 if (errno != ELAST) { 06308 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06309 callerid_free(cs); 06310 ast_hangup(chan); 06311 return NULL; 06312 } 06313 break; 06314 } 06315 if (p->ringt) 06316 p->ringt--; 06317 if (p->ringt == 1) { 06318 res = -1; 06319 break; 06320 } 06321 } 06322 } 06323 if (option_verbose > 2) 06324 /* this only shows up if you have n of the dring patterns filled in */ 06325 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06326 06327 for (counter = 0; counter < 3; counter++) { 06328 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06329 channel */ 06330 distMatches = 0; 06331 for (counter1 = 0; counter1 < 3; counter1++) { 06332 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06333 (p->drings.ringnum[counter].ring[counter1]-10)) { 06334 distMatches++; 06335 } 06336 } 06337 if (distMatches == 3) { 06338 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06339 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06340 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06341 if (option_verbose > 2) 06342 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06343 break; 06344 } 06345 } 06346 } 06347 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06348 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06349 #if 1 06350 restore_gains(p); 06351 #endif 06352 } else 06353 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06354 } else { 06355 ast_log(LOG_WARNING, "Channel %s in prering " 06356 "state, but I have nothing to do. " 06357 "Terminating simple switch, should be " 06358 "restarted by the actual ring.\n", 06359 chan->name); 06360 ast_hangup(chan); 06361 return NULL; 06362 } 06363 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06364 /* FSK Bell202 callerID */ 06365 cs = callerid_new(p->cid_signalling); 06366 if (cs) { 06367 #if 1 06368 bump_gains(p); 06369 #endif 06370 samples = 0; 06371 len = 0; 06372 distMatches = 0; 06373 /* Clear the current ring data array so we dont have old data in it. */ 06374 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06375 curRingData[receivedRingT] = 0; 06376 receivedRingT = 0; 06377 counter = 0; 06378 counter1 = 0; 06379 /* Check to see if context is what it should be, if not set to be. */ 06380 if (strcmp(p->context,p->defcontext) != 0) { 06381 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06382 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06383 } 06384 06385 /* Take out of linear mode for Caller*ID processing */ 06386 zt_setlinear(p->subs[index].zfd, 0); 06387 for (;;) { 06388 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06389 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06390 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06391 callerid_free(cs); 06392 ast_hangup(chan); 06393 return NULL; 06394 } 06395 if (i & ZT_IOMUX_SIGEVENT) { 06396 res = zt_get_event(p->subs[index].zfd); 06397 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06398 /* If we get a PR event, they hung up while processing calerid */ 06399 if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 06400 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 06401 p->polarity = POLARITY_IDLE; 06402 callerid_free(cs); 06403 ast_hangup(chan); 06404 return NULL; 06405 } 06406 res = 0; 06407 /* Let us detect callerid when the telco uses distinctive ring */ 06408 06409 curRingData[receivedRingT] = p->ringt; 06410 06411 if (p->ringt < p->ringt_base/2) 06412 break; 06413 /* Increment the ringT counter so we can match it against 06414 values in zapata.conf for distinctive ring */ 06415 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06416 break; 06417 } else if (i & ZT_IOMUX_READ) { 06418 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06419 if (res < 0) { 06420 if (errno != ELAST) { 06421 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06422 callerid_free(cs); 06423 ast_hangup(chan); 06424 return NULL; 06425 } 06426 break; 06427 } 06428 if (p->ringt) 06429 p->ringt--; 06430 if (p->ringt == 1) { 06431 res = -1; 06432 break; 06433 } 06434 samples += res; 06435 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06436 if (res < 0) { 06437 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06438 break; 06439 } else if (res) 06440 break; 06441 else if (samples > (8000 * 10)) 06442 break; 06443 } 06444 } 06445 if (res == 1) { 06446 callerid_get(cs, &name, &number, &flags); 06447 if (option_debug) 06448 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06449 } 06450 if (distinctiveringaftercid == 1) { 06451 /* Clear the current ring data array so we dont have old data in it. */ 06452 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06453 curRingData[receivedRingT] = 0; 06454 } 06455 receivedRingT = 0; 06456 if (option_verbose > 2) 06457 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06458 for (;;) { 06459 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06460 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06461 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06462 callerid_free(cs); 06463 ast_hangup(chan); 06464 return NULL; 06465 } 06466 if (i & ZT_IOMUX_SIGEVENT) { 06467 res = zt_get_event(p->subs[index].zfd); 06468 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06469 res = 0; 06470 /* Let us detect callerid when the telco uses distinctive ring */ 06471 06472 curRingData[receivedRingT] = p->ringt; 06473 06474 if (p->ringt < p->ringt_base/2) 06475 break; 06476 /* Increment the ringT counter so we can match it against 06477 values in zapata.conf for distinctive ring */ 06478 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06479 break; 06480 } else if (i & ZT_IOMUX_READ) { 06481 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06482 if (res < 0) { 06483 if (errno != ELAST) { 06484 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06485 callerid_free(cs); 06486 ast_hangup(chan); 06487 return NULL; 06488 } 06489 break; 06490 } 06491 if (p->ringt) 06492 p->ringt--; 06493 if (p->ringt == 1) { 06494 res = -1; 06495 break; 06496 } 06497 } 06498 } 06499 } 06500 if (p->usedistinctiveringdetection == 1) { 06501 if (option_verbose > 2) 06502 /* this only shows up if you have n of the dring patterns filled in */ 06503 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06504 06505 for (counter = 0; counter < 3; counter++) { 06506 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06507 channel */ 06508 if (option_verbose > 2) 06509 /* this only shows up if you have n of the dring patterns filled in */ 06510 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06511 p->drings.ringnum[counter].ring[0], 06512 p->drings.ringnum[counter].ring[1], 06513 p->drings.ringnum[counter].ring[2]); 06514 distMatches = 0; 06515 for (counter1 = 0; counter1 < 3; counter1++) { 06516 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06517 (p->drings.ringnum[counter].ring[counter1]-10)) { 06518 distMatches++; 06519 } 06520 } 06521 if (distMatches == 3) { 06522 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06523 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06524 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06525 if (option_verbose > 2) 06526 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06527 break; 06528 } 06529 } 06530 } 06531 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06532 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06533 #if 1 06534 restore_gains(p); 06535 #endif 06536 if (res < 0) { 06537 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06538 } 06539 } else 06540 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06541 } 06542 else 06543 cs = NULL; 06544 06545 if (number) 06546 ast_shrink_phone_number(number); 06547 ast_set_callerid(chan, number, name, number); 06548 06549 if (smdi_msg) 06550 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06551 06552 if (cs) 06553 callerid_free(cs); 06554 06555 ast_setstate(chan, AST_STATE_RING); 06556 chan->rings = 1; 06557 p->ringt = p->ringt_base; 06558 res = ast_pbx_run(chan); 06559 if (res) { 06560 ast_hangup(chan); 06561 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06562 } 06563 return NULL; 06564 default: 06565 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06566 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06567 if (res < 0) 06568 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06569 } 06570 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06571 if (res < 0) 06572 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06573 ast_hangup(chan); 06574 return NULL; 06575 }
static void swap_subs | ( | struct zt_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 844 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().
00845 { 00846 int tchan; 00847 int tinthreeway; 00848 struct ast_channel *towner; 00849 00850 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 00851 00852 tchan = p->subs[a].chan; 00853 towner = p->subs[a].owner; 00854 tinthreeway = p->subs[a].inthreeway; 00855 00856 p->subs[a].chan = p->subs[b].chan; 00857 p->subs[a].owner = p->subs[b].owner; 00858 p->subs[a].inthreeway = p->subs[b].inthreeway; 00859 00860 p->subs[b].chan = tchan; 00861 p->subs[b].owner = towner; 00862 p->subs[b].inthreeway = tinthreeway; 00863 00864 if (p->subs[a].owner) 00865 p->subs[a].owner->fds[0] = p->subs[a].zfd; 00866 if (p->subs[b].owner) 00867 p->subs[b].owner->fds[0] = p->subs[b].zfd; 00868 wakeup_sub(p, a, NULL); 00869 wakeup_sub(p, b, NULL); 00870 }
static int unalloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 970 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().
00971 { 00972 if (!x) { 00973 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 00974 return -1; 00975 } 00976 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 00977 if (p->subs[x].zfd > -1) { 00978 zt_close(p->subs[x].zfd); 00979 } 00980 p->subs[x].zfd = -1; 00981 p->subs[x].linear = 0; 00982 p->subs[x].chan = 0; 00983 p->subs[x].owner = NULL; 00984 p->subs[x].inthreeway = 0; 00985 p->polarity = POLARITY_IDLE; 00986 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 00987 return 0; 00988 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10491 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
10492 { 10493 #ifdef HAVE_PRI 10494 int y; 10495 for (y = 0; y < NUM_SPANS; y++) 10496 ast_mutex_destroy(&pris[y].lock); 10497 #endif 10498 return __unload_module(); 10499 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1356 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().
01357 { 01358 int needconf = 0; 01359 int x; 01360 int useslavenative; 01361 struct zt_pvt *slave = NULL; 01362 01363 useslavenative = isslavenative(p, &slave); 01364 /* Start with the obvious, general stuff */ 01365 for (x = 0; x < 3; x++) { 01366 /* Look for three way calls */ 01367 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01368 conf_add(p, &p->subs[x], x, 0); 01369 needconf++; 01370 } else { 01371 conf_del(p, &p->subs[x], x); 01372 } 01373 } 01374 /* If we have a slave, add him to our conference now. or DAX 01375 if this is slave native */ 01376 for (x = 0; x < MAX_SLAVES; x++) { 01377 if (p->slaves[x]) { 01378 if (useslavenative) 01379 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01380 else { 01381 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01382 needconf++; 01383 } 01384 } 01385 } 01386 /* If we're supposed to be in there, do so now */ 01387 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01388 if (useslavenative) 01389 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01390 else { 01391 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01392 needconf++; 01393 } 01394 } 01395 /* If we have a master, add ourselves to his conference */ 01396 if (p->master) { 01397 if (isslavenative(p->master, NULL)) { 01398 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01399 } else { 01400 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01401 } 01402 } 01403 if (!needconf) { 01404 /* Nobody is left (or should be left) in our conference. 01405 Kill it. */ 01406 p->confno = -1; 01407 } 01408 if (option_debug) 01409 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01410 return 0; 01411 }
static void wakeup_sub | ( | struct zt_pvt * | p, | |
int | a, | |||
void * | pri | |||
) | [static] |
Definition at line 784 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), zt_pvt::lock, ast_channel::lock, zt_subchannel::owner, and zt_pvt::subs.
Referenced by swap_subs().
00786 { 00787 #ifdef HAVE_PRI 00788 if (pri) 00789 ast_mutex_unlock(&pri->lock); 00790 #endif 00791 for (;;) { 00792 if (p->subs[a].owner) { 00793 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00794 ast_mutex_unlock(&p->lock); 00795 usleep(1); 00796 ast_mutex_lock(&p->lock); 00797 } else { 00798 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 00799 ast_mutex_unlock(&p->subs[a].owner->lock); 00800 break; 00801 } 00802 } else 00803 break; 00804 } 00805 #ifdef HAVE_PRI 00806 if (pri) 00807 ast_mutex_lock(&pri->lock); 00808 #endif 00809 }
static int zap_destroy_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9852 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
09853 { 09854 int channel; 09855 09856 if (argc != 4) 09857 return RESULT_SHOWUSAGE; 09858 09859 channel = atoi(argv[3]); 09860 09861 return zap_destroy_channel_bynum(channel); 09862 }
static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6578 of file chan_zap.c.
References zt_pvt::channel, destroy_channel(), iflist, zt_pvt::next, zt_pvt::prev, RESULT_FAILURE, and RESULT_SUCCESS.
Referenced by handle_init_event(), and zap_destroy_channel().
06579 { 06580 struct zt_pvt *tmp = NULL; 06581 struct zt_pvt *prev = NULL; 06582 06583 tmp = iflist; 06584 while (tmp) { 06585 if (tmp->channel == channel) { 06586 destroy_channel(prev, tmp, 1); 06587 return RESULT_SUCCESS; 06588 } 06589 prev = tmp; 06590 tmp = tmp->next; 06591 } 06592 return RESULT_FAILURE; 06593 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 10240 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
10241 { 10242 if (p) { 10243 switch (mode) { 10244 case TRANSFER: 10245 p->fake_event = ZT_EVENT_WINKFLASH; 10246 break; 10247 case HANGUP: 10248 p->fake_event = ZT_EVENT_ONHOOK; 10249 break; 10250 default: 10251 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 10252 } 10253 } 10254 return 0; 10255 }
Definition at line 814 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), f, zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.
Referenced by action_zapdialoffhook().
00816 { 00817 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00818 #ifdef HAVE_PRI 00819 if (pri) 00820 ast_mutex_unlock(&pri->lock); 00821 #endif 00822 for (;;) { 00823 if (p->owner) { 00824 if (ast_mutex_trylock(&p->owner->lock)) { 00825 ast_mutex_unlock(&p->lock); 00826 usleep(1); 00827 ast_mutex_lock(&p->lock); 00828 } else { 00829 ast_queue_frame(p->owner, f); 00830 ast_mutex_unlock(&p->owner->lock); 00831 break; 00832 } 00833 } else 00834 break; 00835 } 00836 #ifdef HAVE_PRI 00837 if (pri) 00838 ast_mutex_lock(&pri->lock); 00839 #endif 00840 }
static int zap_restart | ( | void | ) | [static] |
Definition at line 9865 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().
09866 { 09867 if (option_verbose > 0) 09868 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 09869 while (iflist) { 09870 if (option_debug) 09871 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 09872 /* Also updates iflist: */ 09873 destroy_channel(NULL, iflist, 1); 09874 } 09875 if (option_debug) 09876 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 09877 if (setup_zap(0) != 0) { 09878 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 09879 return 1; 09880 } 09881 return 0; 09882 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9884 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
09885 { 09886 if (argc != 2) { 09887 return RESULT_SHOWUSAGE; 09888 } 09889 09890 if (zap_restart() != 0) 09891 return RESULT_FAILURE; 09892 return RESULT_SUCCESS; 09893 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9966 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, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
09967 { 09968 int channel; 09969 struct zt_pvt *tmp = NULL; 09970 ZT_CONFINFO ci; 09971 ZT_PARAMS ps; 09972 int x; 09973 ast_mutex_t *lock; 09974 struct zt_pvt *start; 09975 #ifdef HAVE_PRI 09976 char *c; 09977 int trunkgroup; 09978 struct zt_pri *pri=NULL; 09979 #endif 09980 09981 lock = &iflock; 09982 start = iflist; 09983 09984 if (argc != 4) 09985 return RESULT_SHOWUSAGE; 09986 #ifdef HAVE_PRI 09987 if ((c = strchr(argv[3], ':'))) { 09988 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 09989 return RESULT_SHOWUSAGE; 09990 if ((trunkgroup < 1) || (channel < 1)) 09991 return RESULT_SHOWUSAGE; 09992 for (x = 0; x < NUM_SPANS; x++) { 09993 if (pris[x].trunkgroup == trunkgroup) { 09994 pri = pris + x; 09995 break; 09996 } 09997 } 09998 if (pri) { 09999 start = pri->crvs; 10000 lock = &pri->lock; 10001 } else { 10002 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 10003 return RESULT_FAILURE; 10004 } 10005 } else 10006 #endif 10007 channel = atoi(argv[3]); 10008 10009 ast_mutex_lock(lock); 10010 tmp = start; 10011 while (tmp) { 10012 if (tmp->channel == channel) { 10013 #ifdef HAVE_PRI 10014 if (pri) 10015 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 10016 else 10017 #endif 10018 ast_cli(fd, "Channel: %d\n", tmp->channel); 10019 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 10020 ast_cli(fd, "Span: %d\n", tmp->span); 10021 ast_cli(fd, "Extension: %s\n", tmp->exten); 10022 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 10023 ast_cli(fd, "Context: %s\n", tmp->context); 10024 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 10025 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 10026 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 10027 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 10028 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 10029 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 10030 ast_cli(fd, "Radio: %d\n", tmp->radio); 10031 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 10032 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)" : ""); 10033 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)" : ""); 10034 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)" : ""); 10035 ast_cli(fd, "Confno: %d\n", tmp->confno); 10036 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 10037 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 10038 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 10039 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 10040 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 10041 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 10042 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 10043 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 10044 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 10045 if (tmp->master) 10046 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 10047 for (x = 0; x < MAX_SLAVES; x++) { 10048 if (tmp->slaves[x]) 10049 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 10050 } 10051 #ifdef HAVE_PRI 10052 if (tmp->pri) { 10053 ast_cli(fd, "PRI Flags: "); 10054 if (tmp->resetting) 10055 ast_cli(fd, "Resetting "); 10056 if (tmp->call) 10057 ast_cli(fd, "Call "); 10058 if (tmp->bearer) 10059 ast_cli(fd, "Bearer "); 10060 ast_cli(fd, "\n"); 10061 if (tmp->logicalspan) 10062 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 10063 else 10064 ast_cli(fd, "PRI Logical Span: Implicit\n"); 10065 } 10066 10067 #endif 10068 memset(&ci, 0, sizeof(ci)); 10069 ps.channo = tmp->channel; 10070 if (tmp->subs[SUB_REAL].zfd > -1) { 10071 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 10072 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 10073 } 10074 #ifdef ZT_GETCONFMUTE 10075 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 10076 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 10077 } 10078 #endif 10079 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 10080 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 10081 } else { 10082 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 10083 } 10084 } 10085 ast_mutex_unlock(lock); 10086 return RESULT_SUCCESS; 10087 } 10088 tmp = tmp->next; 10089 } 10090 10091 ast_cli(fd, "Unable to find given channel %d\n", channel); 10092 ast_mutex_unlock(lock); 10093 return RESULT_FAILURE; 10094 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9905 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::mohinterpret, zt_pvt::next, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
09906 { 09907 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09908 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09909 struct zt_pvt *tmp = NULL; 09910 char tmps[20] = ""; 09911 ast_mutex_t *lock; 09912 struct zt_pvt *start; 09913 #ifdef HAVE_PRI 09914 int trunkgroup; 09915 struct zt_pri *pri = NULL; 09916 int x; 09917 #endif 09918 09919 lock = &iflock; 09920 start = iflist; 09921 09922 #ifdef HAVE_PRI 09923 if (argc == 4) { 09924 if ((trunkgroup = atoi(argv[3])) < 1) 09925 return RESULT_SHOWUSAGE; 09926 for (x = 0; x < NUM_SPANS; x++) { 09927 if (pris[x].trunkgroup == trunkgroup) { 09928 pri = pris + x; 09929 break; 09930 } 09931 } 09932 if (pri) { 09933 start = pri->crvs; 09934 lock = &pri->lock; 09935 } else { 09936 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09937 return RESULT_FAILURE; 09938 } 09939 } else 09940 #endif 09941 if (argc != 3) 09942 return RESULT_SHOWUSAGE; 09943 09944 ast_mutex_lock(lock); 09945 #ifdef HAVE_PRI 09946 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09947 #else 09948 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09949 #endif 09950 09951 tmp = start; 09952 while (tmp) { 09953 if (tmp->channel > 0) { 09954 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 09955 } else 09956 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 09957 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 09958 tmp = tmp->next; 09959 } 09960 ast_mutex_unlock(lock); 09961 return RESULT_SUCCESS; 09962 #undef FORMAT 09963 #undef FORMAT2 09964 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10127 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), errno, FORMAT, FORMAT2, and RESULT_FAILURE.
10127 { 10128 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 10129 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 10130 10131 int span; 10132 int res; 10133 char alarms[50]; 10134 10135 int ctl; 10136 ZT_SPANINFO s; 10137 10138 ctl = open("/dev/zap/ctl", O_RDWR); 10139 if (ctl < 0) { 10140 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 10141 ast_cli(fd, "No Zaptel interface found.\n"); 10142 return RESULT_FAILURE; 10143 } 10144 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 10145 10146 for (span = 1; span < ZT_MAX_SPANS; ++span) { 10147 s.spanno = span; 10148 res = ioctl(ctl, ZT_SPANSTAT, &s); 10149 if (res) { 10150 continue; 10151 } 10152 alarms[0] = '\0'; 10153 if (s.alarms > 0) { 10154 if (s.alarms & ZT_ALARM_BLUE) 10155 strcat(alarms, "BLU/"); 10156 if (s.alarms & ZT_ALARM_YELLOW) 10157 strcat(alarms, "YEL/"); 10158 if (s.alarms & ZT_ALARM_RED) 10159 strcat(alarms, "RED/"); 10160 if (s.alarms & ZT_ALARM_LOOPBACK) 10161 strcat(alarms, "LB/"); 10162 if (s.alarms & ZT_ALARM_RECOVER) 10163 strcat(alarms, "REC/"); 10164 if (s.alarms & ZT_ALARM_NOTOPEN) 10165 strcat(alarms, "NOP/"); 10166 if (!strlen(alarms)) 10167 strcat(alarms, "UUU/"); 10168 if (strlen(alarms)) { 10169 /* Strip trailing / */ 10170 alarms[strlen(alarms) - 1] = '\0'; 10171 } 10172 } else { 10173 if (s.numchans) 10174 strcpy(alarms, "OK"); 10175 else 10176 strcpy(alarms, "UNCONFIGURED"); 10177 } 10178 10179 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 10180 } 10181 close(ctl); 10182 10183 return RESULT_SUCCESS; 10184 #undef FORMAT 10185 #undef FORMAT2 10186 }
static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1166 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_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01167 { 01168 static char buf[256]; 01169 switch (sig) { 01170 case SIG_EM: 01171 return "E & M Immediate"; 01172 case SIG_EMWINK: 01173 return "E & M Wink"; 01174 case SIG_EM_E1: 01175 return "E & M E1"; 01176 case SIG_FEATD: 01177 return "Feature Group D (DTMF)"; 01178 case SIG_FEATDMF: 01179 return "Feature Group D (MF)"; 01180 case SIG_FEATDMF_TA: 01181 return "Feature Groud D (MF) Tandem Access"; 01182 case SIG_FEATB: 01183 return "Feature Group B (MF)"; 01184 case SIG_E911: 01185 return "E911 (MF)"; 01186 case SIG_FGC_CAMA: 01187 return "FGC/CAMA (Dialpulse)"; 01188 case SIG_FGC_CAMAMF: 01189 return "FGC/CAMA (MF)"; 01190 case SIG_FXSLS: 01191 return "FXS Loopstart"; 01192 case SIG_FXSGS: 01193 return "FXS Groundstart"; 01194 case SIG_FXSKS: 01195 return "FXS Kewlstart"; 01196 case SIG_FXOLS: 01197 return "FXO Loopstart"; 01198 case SIG_FXOGS: 01199 return "FXO Groundstart"; 01200 case SIG_FXOKS: 01201 return "FXO Kewlstart"; 01202 case SIG_PRI: 01203 return "ISDN PRI"; 01204 case SIG_SF: 01205 return "SF (Tone) Immediate"; 01206 case SIG_SFWINK: 01207 return "SF (Tone) Wink"; 01208 case SIG_SF_FEATD: 01209 return "SF (Tone) with Feature Group D (DTMF)"; 01210 case SIG_SF_FEATDMF: 01211 return "SF (Tone) with Feature Group D (MF)"; 01212 case SIG_SF_FEATB: 01213 return "SF (Tone) with Feature Group B (MF)"; 01214 case SIG_GR303FXOKS: 01215 return "GR-303 with FXOKS"; 01216 case SIG_GR303FXSKS: 01217 return "GR-303 with FXSKS"; 01218 case 0: 01219 return "Pseudo"; 01220 default: 01221 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01222 return buf; 01223 } 01224 }
static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2740 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_subchannel::inthreeway, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, 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_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, 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::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().
02741 { 02742 struct zt_pvt *p = ast->tech_pvt; 02743 int res = 0; 02744 int index; 02745 int oldstate = ast->_state; 02746 ast_setstate(ast, AST_STATE_UP); 02747 ast_mutex_lock(&p->lock); 02748 index = zt_get_index(ast, p, 0); 02749 if (index < 0) 02750 index = SUB_REAL; 02751 /* nothing to do if a radio channel */ 02752 if ((p->radio || (p->oprmode < 0))) { 02753 ast_mutex_unlock(&p->lock); 02754 return 0; 02755 } 02756 switch (p->sig) { 02757 case SIG_FXSLS: 02758 case SIG_FXSGS: 02759 case SIG_FXSKS: 02760 p->ringt = 0; 02761 /* Fall through */ 02762 case SIG_EM: 02763 case SIG_EM_E1: 02764 case SIG_EMWINK: 02765 case SIG_FEATD: 02766 case SIG_FEATDMF: 02767 case SIG_FEATDMF_TA: 02768 case SIG_E911: 02769 case SIG_FGC_CAMA: 02770 case SIG_FGC_CAMAMF: 02771 case SIG_FEATB: 02772 case SIG_SF: 02773 case SIG_SFWINK: 02774 case SIG_SF_FEATD: 02775 case SIG_SF_FEATDMF: 02776 case SIG_SF_FEATB: 02777 case SIG_FXOLS: 02778 case SIG_FXOGS: 02779 case SIG_FXOKS: 02780 /* Pick up the line */ 02781 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02782 if (p->hanguponpolarityswitch) { 02783 gettimeofday(&p->polaritydelaytv, NULL); 02784 } 02785 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02786 tone_zone_play_tone(p->subs[index].zfd, -1); 02787 p->dialing = 0; 02788 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02789 if (oldstate == AST_STATE_RINGING) { 02790 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02791 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02792 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02793 p->owner = p->subs[SUB_REAL].owner; 02794 } 02795 } 02796 if (p->sig & __ZT_SIG_FXS) { 02797 zt_enable_ec(p); 02798 zt_train_ec(p); 02799 } 02800 break; 02801 #ifdef HAVE_PRI 02802 case SIG_PRI: 02803 /* Send a pri acknowledge */ 02804 if (!pri_grab(p, p->pri)) { 02805 p->proceeding = 1; 02806 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02807 pri_rel(p->pri); 02808 } else { 02809 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02810 res = -1; 02811 } 02812 break; 02813 #endif 02814 case 0: 02815 ast_mutex_unlock(&p->lock); 02816 return 0; 02817 default: 02818 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02819 res = -1; 02820 } 02821 ast_mutex_unlock(&p->lock); 02822 return res; 02823 }
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 3149 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_verbose(), ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), f, ast_channel::fds, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, master, option_verbose, 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(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().
03150 { 03151 struct ast_channel *who; 03152 struct zt_pvt *p0, *p1, *op0, *op1; 03153 struct zt_pvt *master = NULL, *slave = NULL; 03154 struct ast_frame *f; 03155 int inconf = 0; 03156 int nothingok = 1; 03157 int ofd0, ofd1; 03158 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03159 int os0 = -1, os1 = -1; 03160 int priority = 0; 03161 struct ast_channel *oc0, *oc1; 03162 enum ast_bridge_result res; 03163 03164 #ifdef PRI_2BCT 03165 int triedtopribridge = 0; 03166 q931_call *q931c0 = NULL, *q931c1 = NULL; 03167 #endif 03168 03169 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03170 There is code below to handle it properly until DTMF is actually seen, 03171 but due to currently unresolved issues it's ignored... 03172 */ 03173 03174 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03175 return AST_BRIDGE_FAILED_NOWARN; 03176 03177 ast_mutex_lock(&c0->lock); 03178 while (ast_mutex_trylock(&c1->lock)) { 03179 ast_mutex_unlock(&c0->lock); 03180 usleep(1); 03181 ast_mutex_lock(&c0->lock); 03182 } 03183 03184 p0 = c0->tech_pvt; 03185 p1 = c1->tech_pvt; 03186 /* cant do pseudo-channels here */ 03187 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03188 ast_mutex_unlock(&c0->lock); 03189 ast_mutex_unlock(&c1->lock); 03190 return AST_BRIDGE_FAILED_NOWARN; 03191 } 03192 03193 oi0 = zt_get_index(c0, p0, 0); 03194 oi1 = zt_get_index(c1, p1, 0); 03195 if ((oi0 < 0) || (oi1 < 0)) { 03196 ast_mutex_unlock(&c0->lock); 03197 ast_mutex_unlock(&c1->lock); 03198 return AST_BRIDGE_FAILED; 03199 } 03200 03201 op0 = p0 = c0->tech_pvt; 03202 op1 = p1 = c1->tech_pvt; 03203 ofd0 = c0->fds[0]; 03204 ofd1 = c1->fds[0]; 03205 oc0 = p0->owner; 03206 oc1 = p1->owner; 03207 03208 if (ast_mutex_trylock(&p0->lock)) { 03209 /* Don't block, due to potential for deadlock */ 03210 ast_mutex_unlock(&c0->lock); 03211 ast_mutex_unlock(&c1->lock); 03212 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03213 return AST_BRIDGE_RETRY; 03214 } 03215 if (ast_mutex_trylock(&p1->lock)) { 03216 /* Don't block, due to potential for deadlock */ 03217 ast_mutex_unlock(&p0->lock); 03218 ast_mutex_unlock(&c0->lock); 03219 ast_mutex_unlock(&c1->lock); 03220 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03221 return AST_BRIDGE_RETRY; 03222 } 03223 03224 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03225 if (p0->owner && p1->owner) { 03226 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03227 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03228 master = p0; 03229 slave = p1; 03230 inconf = 1; 03231 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03232 master = p1; 03233 slave = p0; 03234 inconf = 1; 03235 } else { 03236 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03237 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03238 p0->channel, 03239 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03240 p0->subs[SUB_REAL].inthreeway, p0->channel, 03241 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03242 p1->subs[SUB_REAL].inthreeway); 03243 } 03244 nothingok = 0; 03245 } 03246 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03247 if (p1->subs[SUB_THREEWAY].inthreeway) { 03248 master = p1; 03249 slave = p0; 03250 nothingok = 0; 03251 } 03252 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03253 if (p0->subs[SUB_THREEWAY].inthreeway) { 03254 master = p0; 03255 slave = p1; 03256 nothingok = 0; 03257 } 03258 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03259 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03260 don't put us in anything */ 03261 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03262 master = p1; 03263 slave = p0; 03264 nothingok = 0; 03265 } 03266 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03267 /* Same as previous */ 03268 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03269 master = p0; 03270 slave = p1; 03271 nothingok = 0; 03272 } 03273 } 03274 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03275 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03276 if (master && slave) { 03277 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03278 in an active threeway call with a channel that is ringing, we should 03279 indicate ringing. */ 03280 if ((oi1 == SUB_THREEWAY) && 03281 p1->subs[SUB_THREEWAY].inthreeway && 03282 p1->subs[SUB_REAL].owner && 03283 p1->subs[SUB_REAL].inthreeway && 03284 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03285 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03286 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03287 os1 = p1->subs[SUB_REAL].owner->_state; 03288 } else { 03289 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03290 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03291 } 03292 if ((oi0 == SUB_THREEWAY) && 03293 p0->subs[SUB_THREEWAY].inthreeway && 03294 p0->subs[SUB_REAL].owner && 03295 p0->subs[SUB_REAL].inthreeway && 03296 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03297 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03298 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03299 os0 = p0->subs[SUB_REAL].owner->_state; 03300 } else { 03301 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03302 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03303 } 03304 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03305 if (!p0->echocanbridged || !p1->echocanbridged) { 03306 /* Disable echo cancellation if appropriate */ 03307 zt_disable_ec(p0); 03308 zt_disable_ec(p1); 03309 } 03310 } 03311 zt_link(slave, master); 03312 master->inconference = inconf; 03313 } else if (!nothingok) 03314 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03315 03316 update_conf(p0); 03317 update_conf(p1); 03318 t0 = p0->subs[SUB_REAL].inthreeway; 03319 t1 = p1->subs[SUB_REAL].inthreeway; 03320 03321 ast_mutex_unlock(&p0->lock); 03322 ast_mutex_unlock(&p1->lock); 03323 03324 ast_mutex_unlock(&c0->lock); 03325 ast_mutex_unlock(&c1->lock); 03326 03327 /* Native bridge failed */ 03328 if ((!master || !slave) && !nothingok) { 03329 zt_enable_ec(p0); 03330 zt_enable_ec(p1); 03331 return AST_BRIDGE_FAILED; 03332 } 03333 03334 if (option_verbose > 2) 03335 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03336 03337 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03338 disable_dtmf_detect(op0); 03339 03340 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03341 disable_dtmf_detect(op1); 03342 03343 for (;;) { 03344 struct ast_channel *c0_priority[2] = {c0, c1}; 03345 struct ast_channel *c1_priority[2] = {c1, c0}; 03346 03347 /* Here's our main loop... Start by locking things, looking for private parts, 03348 and then balking if anything is wrong */ 03349 ast_mutex_lock(&c0->lock); 03350 while (ast_mutex_trylock(&c1->lock)) { 03351 ast_mutex_unlock(&c0->lock); 03352 usleep(1); 03353 ast_mutex_lock(&c0->lock); 03354 } 03355 03356 p0 = c0->tech_pvt; 03357 p1 = c1->tech_pvt; 03358 03359 if (op0 == p0) 03360 i0 = zt_get_index(c0, p0, 1); 03361 if (op1 == p1) 03362 i1 = zt_get_index(c1, p1, 1); 03363 ast_mutex_unlock(&c0->lock); 03364 ast_mutex_unlock(&c1->lock); 03365 03366 if (!timeoutms || 03367 (op0 != p0) || 03368 (op1 != p1) || 03369 (ofd0 != c0->fds[0]) || 03370 (ofd1 != c1->fds[0]) || 03371 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03372 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03373 (oc0 != p0->owner) || 03374 (oc1 != p1->owner) || 03375 (t0 != p0->subs[SUB_REAL].inthreeway) || 03376 (t1 != p1->subs[SUB_REAL].inthreeway) || 03377 (oi0 != i0) || 03378 (oi1 != i1)) { 03379 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03380 op0->channel, oi0, op1->channel, oi1); 03381 res = AST_BRIDGE_RETRY; 03382 goto return_from_bridge; 03383 } 03384 03385 #ifdef PRI_2BCT 03386 q931c0 = p0->call; 03387 q931c1 = p1->call; 03388 if (p0->transfer && p1->transfer 03389 && q931c0 && q931c1 03390 && !triedtopribridge) { 03391 pri_channel_bridge(q931c0, q931c1); 03392 triedtopribridge = 1; 03393 } 03394 #endif 03395 03396 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03397 if (!who) { 03398 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03399 continue; 03400 } 03401 f = ast_read(who); 03402 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03403 *fo = f; 03404 *rc = who; 03405 res = AST_BRIDGE_COMPLETE; 03406 goto return_from_bridge; 03407 } 03408 if (f->frametype == AST_FRAME_DTMF) { 03409 if ((who == c0) && p0->pulsedial) { 03410 ast_write(c1, f); 03411 } else if ((who == c1) && p1->pulsedial) { 03412 ast_write(c0, f); 03413 } else { 03414 *fo = f; 03415 *rc = who; 03416 res = AST_BRIDGE_COMPLETE; 03417 goto return_from_bridge; 03418 } 03419 } 03420 ast_frfree(f); 03421 03422 /* Swap who gets priority */ 03423 priority = !priority; 03424 } 03425 03426 return_from_bridge: 03427 if (op0 == p0) 03428 zt_enable_ec(p0); 03429 03430 if (op1 == p1) 03431 zt_enable_ec(p1); 03432 03433 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03434 enable_dtmf_detect(op0); 03435 03436 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03437 enable_dtmf_detect(op1); 03438 03439 zt_unlink(slave, master, 1); 03440 03441 return res; 03442 }
static int zt_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 1776 of file chan_zap.c.
References ast_channel::_state, ast_callerid_generate(), AST_LAW, ast_log(), ast_malloc, 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, errno, zt_pvt::finaldial, free, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, IS_DIGITAL, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_pvt::law, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_CALLERID_SIZE, zt_subchannel::needbusy, zt_subchannel::needringing, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::owner, pbx_builtin_getvar_helper(), PRI_TRANS_CAP_DIGITAL, 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_FGC_CAMA, SIG_FGC_CAMAMF, 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().
01777 { 01778 struct zt_pvt *p = ast->tech_pvt; 01779 int x, res, index,mysig; 01780 char *c, *n, *l; 01781 #ifdef HAVE_PRI 01782 char *s = NULL; 01783 #endif 01784 char dest[256]; /* must be same length as p->dialdest */ 01785 ast_mutex_lock(&p->lock); 01786 ast_copy_string(dest, rdest, sizeof(dest)); 01787 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01788 if ((ast->_state == AST_STATE_BUSY)) { 01789 p->subs[SUB_REAL].needbusy = 1; 01790 ast_mutex_unlock(&p->lock); 01791 return 0; 01792 } 01793 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01794 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01795 ast_mutex_unlock(&p->lock); 01796 return -1; 01797 } 01798 p->dialednone = 0; 01799 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 01800 { 01801 /* Special pseudo -- automatically up */ 01802 ast_setstate(ast, AST_STATE_UP); 01803 ast_mutex_unlock(&p->lock); 01804 return 0; 01805 } 01806 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01807 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01808 if (res) 01809 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01810 p->outgoing = 1; 01811 01812 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01813 01814 mysig = p->sig; 01815 if (p->outsigmod > -1) 01816 mysig = p->outsigmod; 01817 01818 switch (mysig) { 01819 case SIG_FXOLS: 01820 case SIG_FXOGS: 01821 case SIG_FXOKS: 01822 if (p->owner == ast) { 01823 /* Normal ring, on hook */ 01824 01825 /* Don't send audio while on hook, until the call is answered */ 01826 p->dialing = 1; 01827 if (p->use_callerid) { 01828 /* Generate the Caller-ID spill if desired */ 01829 if (p->cidspill) { 01830 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01831 free(p->cidspill); 01832 } 01833 p->callwaitcas = 0; 01834 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01835 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 01836 p->cidpos = 0; 01837 send_callerid(p); 01838 } 01839 } 01840 /* Choose proper cadence */ 01841 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 01842 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1])) 01843 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 01844 p->cidrings = cidrings[p->distinctivering - 1]; 01845 } else { 01846 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 01847 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 01848 p->cidrings = p->sendcalleridafter; 01849 } 01850 01851 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 01852 c = strchr(dest, '/'); 01853 if (c) 01854 c++; 01855 if (c && (strlen(c) < p->stripmsd)) { 01856 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01857 c = NULL; 01858 } 01859 if (c) { 01860 p->dop.op = ZT_DIAL_OP_REPLACE; 01861 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 01862 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 01863 } else { 01864 p->dop.dialstr[0] = '\0'; 01865 } 01866 x = ZT_RING; 01867 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 01868 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 01869 ast_mutex_unlock(&p->lock); 01870 return -1; 01871 } 01872 p->dialing = 1; 01873 } else { 01874 /* Call waiting call */ 01875 p->callwaitrings = 0; 01876 if (ast->cid.cid_num) 01877 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 01878 else 01879 p->callwait_num[0] = '\0'; 01880 if (ast->cid.cid_name) 01881 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 01882 else 01883 p->callwait_name[0] = '\0'; 01884 /* Call waiting tone instead */ 01885 if (zt_callwait(ast)) { 01886 ast_mutex_unlock(&p->lock); 01887 return -1; 01888 } 01889 /* Make ring-back */ 01890 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 01891 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 01892 01893 } 01894 n = ast->cid.cid_name; 01895 l = ast->cid.cid_num; 01896 if (l) 01897 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 01898 else 01899 p->lastcid_num[0] = '\0'; 01900 if (n) 01901 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 01902 else 01903 p->lastcid_name[0] = '\0'; 01904 ast_setstate(ast, AST_STATE_RINGING); 01905 index = zt_get_index(ast, p, 0); 01906 if (index > -1) { 01907 p->subs[index].needringing = 1; 01908 } 01909 break; 01910 case SIG_FXSLS: 01911 case SIG_FXSGS: 01912 case SIG_FXSKS: 01913 case SIG_EMWINK: 01914 case SIG_EM: 01915 case SIG_EM_E1: 01916 case SIG_FEATD: 01917 case SIG_FEATDMF: 01918 case SIG_E911: 01919 case SIG_FGC_CAMA: 01920 case SIG_FGC_CAMAMF: 01921 case SIG_FEATB: 01922 case SIG_SFWINK: 01923 case SIG_SF: 01924 case SIG_SF_FEATD: 01925 case SIG_SF_FEATDMF: 01926 case SIG_FEATDMF_TA: 01927 case SIG_SF_FEATB: 01928 c = strchr(dest, '/'); 01929 if (c) 01930 c++; 01931 else 01932 c = ""; 01933 if (strlen(c) < p->stripmsd) { 01934 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01935 ast_mutex_unlock(&p->lock); 01936 return -1; 01937 } 01938 #ifdef HAVE_PRI 01939 /* Start the trunk, if not GR-303 */ 01940 if (!p->pri) { 01941 #endif 01942 x = ZT_START; 01943 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 01944 if (res < 0) { 01945 if (errno != EINPROGRESS) { 01946 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 01947 ast_mutex_unlock(&p->lock); 01948 return -1; 01949 } 01950 } 01951 #ifdef HAVE_PRI 01952 } 01953 #endif 01954 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 01955 p->dop.op = ZT_DIAL_OP_REPLACE; 01956 01957 c += p->stripmsd; 01958 01959 switch (mysig) { 01960 case SIG_FEATD: 01961 l = ast->cid.cid_num; 01962 if (l) 01963 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 01964 else 01965 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 01966 break; 01967 case SIG_FEATDMF: 01968 l = ast->cid.cid_num; 01969 if (l) 01970 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 01971 else 01972 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 01973 break; 01974 case SIG_FEATDMF_TA: 01975 { 01976 const char *cic, *ozz; 01977 01978 /* If you have to go through a Tandem Access point you need to use this */ 01979 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 01980 if (!ozz) 01981 ozz = defaultozz; 01982 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 01983 if (!cic) 01984 cic = defaultcic; 01985 if (!ozz || !cic) { 01986 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 01987 ast_mutex_unlock(&p->lock); 01988 return -1; 01989 } 01990 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 01991 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 01992 p->whichwink = 0; 01993 } 01994 break; 01995 case SIG_E911: 01996 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 01997 break; 01998 case SIG_FGC_CAMA: 01999 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 02000 break; 02001 case SIG_FGC_CAMAMF: 02002 case SIG_FEATB: 02003 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 02004 break; 02005 default: 02006 if (p->pulse) 02007 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 02008 else 02009 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 02010 break; 02011 } 02012 02013 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 02014 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02015 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02016 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02017 p->echobreak = 1; 02018 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02019 } else 02020 p->echobreak = 0; 02021 if (!res) { 02022 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 02023 x = ZT_ONHOOK; 02024 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02025 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 02026 ast_mutex_unlock(&p->lock); 02027 return -1; 02028 } 02029 } else 02030 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 02031 p->dialing = 1; 02032 if (ast_strlen_zero(c)) 02033 p->dialednone = 1; 02034 ast_setstate(ast, AST_STATE_DIALING); 02035 break; 02036 case 0: 02037 /* Special pseudo -- automatically up*/ 02038 ast_setstate(ast, AST_STATE_UP); 02039 break; 02040 case SIG_PRI: 02041 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02042 p->dialdest[0] = '\0'; 02043 break; 02044 default: 02045 ast_log(LOG_DEBUG, "not yet implemented\n"); 02046 ast_mutex_unlock(&p->lock); 02047 return -1; 02048 } 02049 #ifdef HAVE_PRI 02050 if (p->pri) { 02051 struct pri_sr *sr; 02052 #ifdef SUPPORT_USERUSER 02053 const char *useruser; 02054 #endif 02055 int pridialplan; 02056 int dp_strip; 02057 int prilocaldialplan; 02058 int ldp_strip; 02059 int exclusive; 02060 const char *rr_str; 02061 int redirect_reason; 02062 02063 c = strchr(dest, '/'); 02064 if (c) 02065 c++; 02066 else 02067 c = dest; 02068 02069 l = NULL; 02070 n = NULL; 02071 02072 if (!p->hidecallerid) { 02073 l = ast->cid.cid_num; 02074 if (!p->hidecalleridname) { 02075 n = ast->cid.cid_name; 02076 } 02077 } 02078 02079 02080 if (strlen(c) < p->stripmsd) { 02081 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02082 ast_mutex_unlock(&p->lock); 02083 return -1; 02084 } 02085 if (mysig != SIG_FXSKS) { 02086 p->dop.op = ZT_DIAL_OP_REPLACE; 02087 s = strchr(c + p->stripmsd, 'w'); 02088 if (s) { 02089 if (strlen(s) > 1) 02090 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02091 else 02092 p->dop.dialstr[0] = '\0'; 02093 *s = '\0'; 02094 } else { 02095 p->dop.dialstr[0] = '\0'; 02096 } 02097 } 02098 if (pri_grab(p, p->pri)) { 02099 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02100 ast_mutex_unlock(&p->lock); 02101 return -1; 02102 } 02103 if (!(p->call = pri_new_call(p->pri->pri))) { 02104 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02105 pri_rel(p->pri); 02106 ast_mutex_unlock(&p->lock); 02107 return -1; 02108 } 02109 if (!(sr = pri_sr_new())) { 02110 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02111 pri_rel(p->pri); 02112 ast_mutex_unlock(&p->lock); 02113 } 02114 if (p->bearer || (mysig == SIG_FXSKS)) { 02115 if (p->bearer) { 02116 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); 02117 p->bearer->call = p->call; 02118 } else 02119 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02120 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02121 } 02122 p->digital = IS_DIGITAL(ast->transfercapability); 02123 /* Add support for exclusive override */ 02124 if (p->priexclusive) 02125 exclusive = 1; 02126 else { 02127 /* otherwise, traditional behavior */ 02128 if (p->pri->nodetype == PRI_NETWORK) 02129 exclusive = 0; 02130 else 02131 exclusive = 1; 02132 } 02133 02134 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02135 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02136 (p->digital ? -1 : 02137 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); 02138 if (p->pri->facilityenable) 02139 pri_facility_enable(p->pri->pri); 02140 02141 if (option_verbose > 2) 02142 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02143 dp_strip = 0; 02144 pridialplan = p->pri->dialplan - 1; 02145 if (pridialplan == -2) { /* compute dynamically */ 02146 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02147 dp_strip = strlen(p->pri->internationalprefix); 02148 pridialplan = PRI_INTERNATIONAL_ISDN; 02149 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02150 dp_strip = strlen(p->pri->nationalprefix); 02151 pridialplan = PRI_NATIONAL_ISDN; 02152 } else { 02153 pridialplan = PRI_LOCAL_ISDN; 02154 } 02155 } 02156 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02157 02158 ldp_strip = 0; 02159 prilocaldialplan = p->pri->localdialplan - 1; 02160 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02161 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02162 ldp_strip = strlen(p->pri->internationalprefix); 02163 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02164 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02165 ldp_strip = strlen(p->pri->nationalprefix); 02166 prilocaldialplan = PRI_NATIONAL_ISDN; 02167 } else { 02168 prilocaldialplan = PRI_LOCAL_ISDN; 02169 } 02170 } 02171 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02172 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02173 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { 02174 if (!strcasecmp(rr_str, "UNKNOWN")) 02175 redirect_reason = 0; 02176 else if (!strcasecmp(rr_str, "BUSY")) 02177 redirect_reason = 1; 02178 else if (!strcasecmp(rr_str, "NO_REPLY")) 02179 redirect_reason = 2; 02180 else if (!strcasecmp(rr_str, "UNCONDITIONAL")) 02181 redirect_reason = 15; 02182 else 02183 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02184 } else 02185 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02186 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); 02187 02188 #ifdef SUPPORT_USERUSER 02189 /* User-user info */ 02190 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02191 02192 if (useruser) 02193 pri_sr_set_useruser(sr, useruser); 02194 #endif 02195 02196 if (pri_setup(p->pri->pri, p->call, sr)) { 02197 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02198 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02199 pri_rel(p->pri); 02200 ast_mutex_unlock(&p->lock); 02201 pri_sr_free(sr); 02202 return -1; 02203 } 02204 pri_sr_free(sr); 02205 ast_setstate(ast, AST_STATE_DIALING); 02206 pri_rel(p->pri); 02207 } 02208 #endif 02209 ast_mutex_unlock(&p->lock); 02210 return 0; 02211 }
static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1748 of file chan_zap.c.
References ast_gen_cas(), AST_LAW, ast_log(), ast_malloc, 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, READ_SIZE, save_conference(), send_callerid(), and ast_channel::tech_pvt.
Referenced by zt_call(), and zt_read().
01749 { 01750 struct zt_pvt *p = ast->tech_pvt; 01751 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01752 if (p->cidspill) { 01753 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01754 free(p->cidspill); 01755 } 01756 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01757 return -1; 01758 save_conference(p); 01759 /* Silence */ 01760 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01761 if (!p->callwaitrings && p->callwaitingcallerid) { 01762 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01763 p->callwaitcas = 1; 01764 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01765 } else { 01766 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01767 p->callwaitcas = 0; 01768 p->cidlen = 2400 + READ_SIZE * 4; 01769 } 01770 p->cidpos = 0; 01771 send_callerid(p); 01772 01773 return 0; 01774 }
static struct zt_chan_conf zt_chan_conf_default | ( | void | ) | [static] |
returns a new zt_chan_conf with default values (by-value)
Definition at line 600 of file chan_zap.c.
References zt_chan_conf::chan, CID_SIG_BELL, CID_START_RING, zt_pvt::context, and DEFAULT_CIDRINGS.
Referenced by setup_zap().
00600 { 00601 /* recall that if a field is not included here it is initialized 00602 * to 0 or equivalent 00603 */ 00604 struct zt_chan_conf conf = { 00605 #ifdef HAVE_PRI 00606 .pri = { 00607 .nsf = PRI_NSF_NONE, 00608 .switchtype = PRI_SWITCH_NI2, 00609 .dialplan = PRI_NATIONAL_ISDN + 1, 00610 .localdialplan = PRI_NATIONAL_ISDN + 1, 00611 .nodetype = PRI_CPE, 00612 00613 .minunused = 2, 00614 .idleext = "", 00615 .idledial = "", 00616 .internationalprefix = "", 00617 .nationalprefix = "", 00618 .localprefix = "", 00619 .privateprefix = "", 00620 .unknownprefix = "", 00621 00622 .resetinterval = 3600 00623 }, 00624 #endif 00625 .chan = { 00626 .context = "default", 00627 .cid_num = "", 00628 .cid_name = "", 00629 .mohinterpret = "default", 00630 .mohsuggest = "", 00631 .transfertobusy = 1, 00632 00633 .cid_signalling = CID_SIG_BELL, 00634 .cid_start = CID_START_RING, 00635 .zaptrcallerid = 0, 00636 .use_callerid = 1, 00637 .sig = -1, 00638 .outsigmod = -1, 00639 00640 .tonezone = -1, 00641 00642 .echocancel = 1, 00643 00644 .busycount = 3, 00645 00646 .accountcode = "", 00647 00648 .mailbox = "", 00649 00650 00651 .polarityonanswerdelay = 600, 00652 00653 .sendcalleridafter = DEFAULT_CIDRINGS 00654 }, 00655 .timing = { 00656 .prewinktime = -1, 00657 .preflashtime = -1, 00658 .winktime = -1, 00659 .flashtime = -1, 00660 .starttime = -1, 00661 .rxwinktime = -1, 00662 .rxflashtime = -1, 00663 .debouncetime = -1 00664 }, 00665 .smdi_port = "/dev/ttyS0", 00666 }; 00667 00668 return conf; 00669 }
static void zt_close | ( | int | fd | ) | [static] |
Definition at line 919 of file chan_zap.c.
Referenced by __unload_module(), alloc_sub(), destroy_channel(), and unalloc_sub().
static int zt_confmute | ( | struct zt_pvt * | p, | |
int | muted | |||
) | [inline, static] |
Definition at line 1631 of file chan_zap.c.
References ast_log(), zt_pvt::channel, errno, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_handle_dtmfup(), zt_handle_event(), zt_hangup(), and zt_new().
01632 { 01633 int x, y, res; 01634 x = muted; 01635 if (p->sig == SIG_PRI) { 01636 y = 1; 01637 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01638 if (res) 01639 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01640 } 01641 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01642 if (res < 0) 01643 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01644 return res; 01645 }
static int zt_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1006 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DIALING, zt_pvt::begindigit, zt_pvt::dialdest, zt_pvt::dialing, digit_to_dtmfindex(), zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::owner, zt_pvt::pulse, zt_pvt::sig, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, and zt_get_index().
01007 { 01008 struct zt_pvt *pvt; 01009 int index; 01010 int dtmf = -1; 01011 01012 pvt = chan->tech_pvt; 01013 01014 ast_mutex_lock(&pvt->lock); 01015 01016 index = zt_get_index(chan, pvt, 0); 01017 01018 if ((index != SUB_REAL) || !pvt->owner) 01019 goto out; 01020 01021 #ifdef HAVE_PRI 01022 if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) { 01023 if (pvt->setup_ack) { 01024 if (!pri_grab(pvt, pvt->pri)) { 01025 pri_information(pvt->pri->pri, pvt->call, digit); 01026 pri_rel(pvt->pri); 01027 } else 01028 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span); 01029 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 01030 int res; 01031 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01032 res = strlen(pvt->dialdest); 01033 pvt->dialdest[res++] = digit; 01034 pvt->dialdest[res] = '\0'; 01035 } 01036 goto out; 01037 } 01038 #endif 01039 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 01040 goto out; 01041 01042 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) { 01043 int res; 01044 ZT_DIAL_OPERATION zo = { 01045 .op = ZT_DIAL_OP_APPEND, 01046 .dialstr[0] = 'T', 01047 .dialstr[1] = digit, 01048 .dialstr[2] = 0, 01049 }; 01050 if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01051 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01052 else 01053 pvt->dialing = 1; 01054 } else { 01055 ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit); 01056 pvt->dialing = 1; 01057 pvt->begindigit = digit; 01058 } 01059 01060 out: 01061 ast_mutex_unlock(&pvt->lock); 01062 01063 return 0; 01064 }
static int zt_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1066 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::begindigit, zt_pvt::dialing, zt_pvt::lock, LOG_DEBUG, zt_pvt::owner, zt_pvt::pulse, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, and zt_get_index().
01067 { 01068 struct zt_pvt *pvt; 01069 int res = 0; 01070 int index; 01071 int x; 01072 01073 pvt = chan->tech_pvt; 01074 01075 ast_mutex_lock(&pvt->lock); 01076 01077 index = zt_get_index(chan, pvt, 0); 01078 01079 if ((index != SUB_REAL) || !pvt->owner || pvt->pulse) 01080 goto out; 01081 01082 #ifdef HAVE_PRI 01083 /* This means that the digit was already sent via PRI signalling */ 01084 if (pvt->sig == SIG_PRI && !pvt->begindigit) 01085 goto out; 01086 #endif 01087 01088 if (pvt->begindigit) { 01089 x = -1; 01090 ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit); 01091 res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x); 01092 pvt->dialing = 0; 01093 pvt->begindigit = 0; 01094 } 01095 01096 out: 01097 ast_mutex_unlock(&pvt->lock); 01098 01099 return res; 01100 }
static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1463 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, option_debug, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01464 { 01465 int x; 01466 int res; 01467 if (p->echocancel) { 01468 x = 0; 01469 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01470 if (res) 01471 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01472 else if (option_debug) 01473 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01474 } 01475 p->echocanon = 0; 01476 }
static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1413 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_setoption().
01414 { 01415 int x; 01416 int res; 01417 if (!p) 01418 return; 01419 if (p->echocanon) { 01420 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01421 return; 01422 } 01423 if (p->digital) { 01424 ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n"); 01425 return; 01426 } 01427 if (p->echocancel) { 01428 if (p->sig == SIG_PRI) { 01429 x = 1; 01430 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01431 if (res) 01432 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno)); 01433 } 01434 x = p->echocancel; 01435 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01436 if (res) 01437 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 01438 else { 01439 p->echocanon = 1; 01440 if (option_debug) 01441 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01442 } 01443 } else if (option_debug) 01444 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01445 }
static struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4625 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), f, zt_pvt::lock, and ast_channel::tech_pvt.
04626 { 04627 struct zt_pvt *p = ast->tech_pvt; 04628 struct ast_frame *f; 04629 ast_mutex_lock(&p->lock); 04630 f = __zt_exception(ast); 04631 ast_mutex_unlock(&p->lock); 04632 return f; 04633 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3444 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, and zt_unlink().
03445 { 03446 struct zt_pvt *p = newchan->tech_pvt; 03447 int x; 03448 ast_mutex_lock(&p->lock); 03449 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03450 if (p->owner == oldchan) { 03451 p->owner = newchan; 03452 } 03453 for (x = 0; x < 3; x++) 03454 if (p->subs[x].owner == oldchan) { 03455 if (!x) 03456 zt_unlink(NULL, p, 0); 03457 p->subs[x].owner = newchan; 03458 } 03459 if (newchan->_state == AST_STATE_RINGING) 03460 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03461 update_conf(p); 03462 ast_mutex_unlock(&p->lock); 03463 return 0; 03464 }
static int zt_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3010 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, zt_pvt::rxgain, ast_channel::tech_pvt, and zt_pvt::txgain.
03011 { 03012 struct zt_pvt *p = chan->tech_pvt; 03013 03014 if (!strcasecmp(data, "rxgain")) { 03015 ast_mutex_lock(&p->lock); 03016 snprintf(buf, len, "%f", p->rxgain); 03017 ast_mutex_unlock(&p->lock); 03018 } else if (!strcasecmp(data, "txgain")) { 03019 ast_mutex_lock(&p->lock); 03020 snprintf(buf, len, "%f", p->txgain); 03021 ast_mutex_unlock(&p->lock); 03022 } else { 03023 ast_copy_string(buf, "", len); 03024 } 03025 return 0; 03026 }
static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 256 of file chan_zap.c.
Referenced by __zt_exception(), ss_thread(), and zt_handle_event().
00257 { 00258 int j; 00259 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00260 return -1; 00261 return j; 00262 }
static int zt_get_index | ( | struct ast_channel * | ast, | |
struct zt_pvt * | p, | |||
int | nullok | |||
) | [static] |
Definition at line 764 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_begin(), zt_digit_end(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), zt_sendtext(), zt_setoption(), and zt_write().
00765 { 00766 int res; 00767 if (p->subs[0].owner == ast) 00768 res = 0; 00769 else if (p->subs[1].owner == ast) 00770 res = 1; 00771 else if (p->subs[2].owner == ast) 00772 res = 2; 00773 else { 00774 res = -1; 00775 if (!nullok) 00776 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00777 } 00778 return res; 00779 }
static void zt_handle_dtmfup | ( | struct ast_channel * | ast, | |
int | index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 3612 of file chan_zap.c.
References ast_async_goto(), AST_CONTROL_ANSWER, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), ast_verbose(), zt_pvt::callprogress, zt_pvt::callwaitcas, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_channel::exten, zt_subchannel::f, f, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, ast_channel::macrocontext, option_debug, option_verbose, pbx_builtin_setvar_helper(), S_OR, send_cwcidspill(), ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, VERBOSE_PREFIX_3, and zt_confmute().
Referenced by zt_handle_event(), and zt_read().
03613 { 03614 struct zt_pvt *p = ast->tech_pvt; 03615 struct ast_frame *f = *dest; 03616 03617 if (option_debug) 03618 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03619 03620 if (p->confirmanswer) { 03621 if (option_debug) 03622 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03623 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03624 of a DTMF digit */ 03625 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03626 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03627 *dest = &p->subs[index].f; 03628 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03629 p->confirmanswer = 0; 03630 } else if (p->callwaitcas) { 03631 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03632 if (option_debug) 03633 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03634 if (p->cidspill) 03635 free(p->cidspill); 03636 send_cwcidspill(p); 03637 } 03638 if ((f->subclass != 'm') && (f->subclass != 'u')) 03639 p->callwaitcas = 0; 03640 p->subs[index].f.frametype = AST_FRAME_NULL; 03641 p->subs[index].f.subclass = 0; 03642 *dest = &p->subs[index].f; 03643 } else if (f->subclass == 'f') { 03644 /* Fax tone -- Handle and return NULL */ 03645 if ((p->callprogress & 0x6) && !p->faxhandled) { 03646 p->faxhandled++; 03647 if (strcmp(ast->exten, "fax")) { 03648 const char *target_context = S_OR(ast->macrocontext, ast->context); 03649 03650 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03651 if (option_verbose > 2) 03652 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03653 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03654 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03655 if (ast_async_goto(ast, target_context, "fax", 1)) 03656 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03657 } else 03658 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03659 } else if (option_debug) 03660 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03661 } else if (option_debug) 03662 ast_log(LOG_DEBUG, "Fax already handled\n"); 03663 zt_confmute(p, 0); 03664 p->subs[index].f.frametype = AST_FRAME_NULL; 03665 p->subs[index].f.subclass = 0; 03666 *dest = &p->subs[index].f; 03667 } else if (f->subclass == 'm') { 03668 /* Confmute request */ 03669 zt_confmute(p, 1); 03670 p->subs[index].f.frametype = AST_FRAME_NULL; 03671 p->subs[index].f.subclass = 0; 03672 *dest = &p->subs[index].f; 03673 } else if (f->subclass == 'u') { 03674 /* Unmute */ 03675 zt_confmute(p, 0); 03676 p->subs[index].f.frametype = AST_FRAME_NULL; 03677 p->subs[index].f.subclass = 0; 03678 *dest = &p->subs[index].f; 03679 } else 03680 zt_confmute(p, 0); 03681 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3683 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_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), 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_strdup, 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, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, 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::echocanon, zt_pvt::echorest, zt_pvt::echotraining, errno, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::onhooktime, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::outsigmod, 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, restore_conference(), ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, S_OR, ast_frame::samples, save_conference(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), 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(), zt_pvt::unknown_alarm, update_conf(), VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_enable_ec(), ZT_EVENT_DTMFDOWN, ZT_EVENT_DTMFUP, zt_get_event(), zt_get_index(), zt_handle_dtmfup(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().
Referenced by __zt_exception().
03684 { 03685 int res, x; 03686 int index, mysig; 03687 char *c; 03688 struct zt_pvt *p = ast->tech_pvt; 03689 pthread_t threadid; 03690 pthread_attr_t attr; 03691 struct ast_channel *chan; 03692 struct ast_frame *f; 03693 03694 index = zt_get_index(ast, p, 0); 03695 mysig = p->sig; 03696 if (p->outsigmod > -1) 03697 mysig = p->outsigmod; 03698 p->subs[index].f.frametype = AST_FRAME_NULL; 03699 p->subs[index].f.subclass = 0; 03700 p->subs[index].f.datalen = 0; 03701 p->subs[index].f.samples = 0; 03702 p->subs[index].f.mallocd = 0; 03703 p->subs[index].f.offset = 0; 03704 p->subs[index].f.src = "zt_handle_event"; 03705 p->subs[index].f.data = NULL; 03706 f = &p->subs[index].f; 03707 03708 if (index < 0) 03709 return &p->subs[index].f; 03710 if (p->fake_event) { 03711 res = p->fake_event; 03712 p->fake_event = 0; 03713 } else 03714 res = zt_get_event(p->subs[index].zfd); 03715 03716 if (option_debug) 03717 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03718 03719 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03720 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 03721 03722 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03723 #ifdef HAVE_PRI 03724 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03725 /* absorb event */ 03726 } else { 03727 #endif 03728 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 03729 p->subs[index].f.subclass = res & 0xff; 03730 #ifdef HAVE_PRI 03731 } 03732 #endif 03733 zt_handle_dtmfup(ast, index, &f); 03734 return f; 03735 } 03736 03737 if (res & ZT_EVENT_DTMFDOWN) { 03738 if (option_debug) 03739 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03740 /* Mute conference */ 03741 zt_confmute(p, 1); 03742 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 03743 p->subs[index].f.subclass = res & 0xff; 03744 return &p->subs[index].f; 03745 } 03746 03747 switch (res) { 03748 #ifdef ZT_EVENT_EC_DISABLED 03749 case ZT_EVENT_EC_DISABLED: 03750 if (option_verbose > 2) 03751 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 03752 p->echocanon = 0; 03753 break; 03754 #endif 03755 case ZT_EVENT_BITSCHANGED: 03756 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03757 case ZT_EVENT_PULSE_START: 03758 /* Stop tone if there's a pulse start and the PBX isn't started */ 03759 if (!ast->pbx) 03760 tone_zone_play_tone(p->subs[index].zfd, -1); 03761 break; 03762 case ZT_EVENT_DIALCOMPLETE: 03763 if (p->inalarm) break; 03764 if ((p->radio || (p->oprmode < 0))) break; 03765 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03766 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03767 return NULL; 03768 } 03769 if (!x) { /* if not still dialing in driver */ 03770 zt_enable_ec(p); 03771 if (p->echobreak) { 03772 zt_train_ec(p); 03773 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03774 p->dop.op = ZT_DIAL_OP_REPLACE; 03775 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03776 p->echobreak = 0; 03777 } else { 03778 p->dialing = 0; 03779 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 03780 /* if thru with dialing after offhook */ 03781 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03782 ast_setstate(ast, AST_STATE_UP); 03783 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03784 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03785 break; 03786 } else { /* if to state wait for offhook to dial rest */ 03787 /* we now wait for off hook */ 03788 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03789 } 03790 } 03791 if (ast->_state == AST_STATE_DIALING) { 03792 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03793 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03794 } else if (p->confirmanswer || (!p->dialednone && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) || (mysig == SIG_SF) || (mysig == SIG_SFWINK) || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) || (mysig == SIG_SF_FEATB)))) { 03795 ast_setstate(ast, AST_STATE_RINGING); 03796 } else if (!p->answeronpolarityswitch) { 03797 ast_setstate(ast, AST_STATE_UP); 03798 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03799 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03800 /* If aops=0 and hops=1, this is necessary */ 03801 p->polarity = POLARITY_REV; 03802 } else { 03803 /* Start clean, so we can catch the change to REV polarity when party answers */ 03804 p->polarity = POLARITY_IDLE; 03805 } 03806 } 03807 } 03808 } 03809 break; 03810 case ZT_EVENT_ALARM: 03811 #ifdef HAVE_PRI 03812 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 03813 /* T309 is not enabled : hangup calls when alarm occurs */ 03814 if (p->call) { 03815 if (p->pri && p->pri->pri) { 03816 if (!pri_grab(p, p->pri)) { 03817 pri_hangup(p->pri->pri, p->call, -1); 03818 pri_destroycall(p->pri->pri, p->call); 03819 p->call = NULL; 03820 pri_rel(p->pri); 03821 } else 03822 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03823 } else 03824 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 03825 } 03826 if (p->owner) 03827 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03828 } 03829 if (p->bearer) 03830 p->bearer->inalarm = 1; 03831 else 03832 #endif 03833 p->inalarm = 1; 03834 res = get_alarms(p); 03835 do { 03836 const char *alarm_str = alarm2str(res); 03837 03838 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 03839 * doesn't know what to do with it. Don't confuse users with log messages. */ 03840 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 03841 p->unknown_alarm = 1; 03842 break; 03843 } else { 03844 p->unknown_alarm = 0; 03845 } 03846 03847 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 03848 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 03849 "Alarm: %s\r\n" 03850 "Channel: %d\r\n", 03851 alarm_str, p->channel); 03852 } while (0); 03853 #ifdef HAVE_LIBPRI 03854 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 03855 /* fall through intentionally */ 03856 } else { 03857 break; 03858 } 03859 #endif 03860 case ZT_EVENT_ONHOOK: 03861 if (p->radio) { 03862 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03863 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 03864 break; 03865 } 03866 if (p->oprmode < 0) 03867 { 03868 if (p->oprmode != -1) break; 03869 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03870 { 03871 /* Make sure it starts ringing */ 03872 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03873 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 03874 save_conference(p->oprpeer); 03875 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03876 } 03877 break; 03878 } 03879 switch (p->sig) { 03880 case SIG_FXOLS: 03881 case SIG_FXOGS: 03882 case SIG_FXOKS: 03883 p->onhooktime = time(NULL); 03884 p->msgstate = -1; 03885 /* Check for some special conditions regarding call waiting */ 03886 if (index == SUB_REAL) { 03887 /* The normal line was hung up */ 03888 if (p->subs[SUB_CALLWAIT].owner) { 03889 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 03890 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 03891 if (option_verbose > 2) 03892 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 03893 unalloc_sub(p, SUB_CALLWAIT); 03894 #if 0 03895 p->subs[index].needanswer = 0; 03896 p->subs[index].needringing = 0; 03897 #endif 03898 p->callwaitingrepeat = 0; 03899 p->cidcwexpire = 0; 03900 p->owner = NULL; 03901 /* Don't start streaming audio yet if the incoming call isn't up yet */ 03902 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 03903 p->dialing = 1; 03904 zt_ring_phone(p); 03905 } else if (p->subs[SUB_THREEWAY].owner) { 03906 unsigned int mssinceflash; 03907 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 03908 the private structure -- not especially easy or clean */ 03909 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 03910 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 03911 ast_mutex_unlock(&p->lock); 03912 ast_mutex_unlock(&ast->lock); 03913 usleep(1); 03914 /* We can grab ast and p in that order, without worry. We should make sure 03915 nothing seriously bad has happened though like some sort of bizarre double 03916 masquerade! */ 03917 ast_mutex_lock(&ast->lock); 03918 ast_mutex_lock(&p->lock); 03919 if (p->owner != ast) { 03920 ast_log(LOG_WARNING, "This isn't good...\n"); 03921 return NULL; 03922 } 03923 } 03924 if (!p->subs[SUB_THREEWAY].owner) { 03925 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 03926 return NULL; 03927 } 03928 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 03929 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 03930 if (mssinceflash < MIN_MS_SINCE_FLASH) { 03931 /* It hasn't been long enough since the last flashook. This is probably a bounce on 03932 hanging up. Hangup both channels now */ 03933 if (p->subs[SUB_THREEWAY].owner) 03934 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 03935 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03936 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 03937 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03938 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 03939 if (p->transfer) { 03940 /* In any case this isn't a threeway call anymore */ 03941 p->subs[SUB_REAL].inthreeway = 0; 03942 p->subs[SUB_THREEWAY].inthreeway = 0; 03943 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 03944 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 03945 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03946 /* Swap subs and dis-own channel */ 03947 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03948 p->owner = NULL; 03949 /* Ring the phone */ 03950 zt_ring_phone(p); 03951 } else { 03952 if ((res = attempt_transfer(p)) < 0) { 03953 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03954 if (p->subs[SUB_THREEWAY].owner) 03955 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03956 } else if (res) { 03957 /* Don't actually hang up at this point */ 03958 if (p->subs[SUB_THREEWAY].owner) 03959 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03960 break; 03961 } 03962 } 03963 } else { 03964 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03965 if (p->subs[SUB_THREEWAY].owner) 03966 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03967 } 03968 } else { 03969 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03970 /* Swap subs and dis-own channel */ 03971 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03972 p->owner = NULL; 03973 /* Ring the phone */ 03974 zt_ring_phone(p); 03975 } 03976 } 03977 } else { 03978 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 03979 } 03980 /* Fall through */ 03981 default: 03982 zt_disable_ec(p); 03983 return NULL; 03984 } 03985 break; 03986 case ZT_EVENT_RINGOFFHOOK: 03987 if (p->inalarm) break; 03988 if (p->oprmode < 0) 03989 { 03990 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03991 { 03992 /* Make sure it stops ringing */ 03993 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03994 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 03995 restore_conference(p->oprpeer); 03996 } 03997 break; 03998 } 03999 if (p->radio) 04000 { 04001 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04002 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04003 break; 04004 } 04005 /* for E911, its supposed to wait for offhook then dial 04006 the second half of the dial string */ 04007 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 04008 c = strchr(p->dialdest, '/'); 04009 if (c) 04010 c++; 04011 else 04012 c = p->dialdest; 04013 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 04014 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 04015 if (strlen(p->dop.dialstr) > 4) { 04016 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 04017 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 04018 p->echorest[sizeof(p->echorest) - 1] = '\0'; 04019 p->echobreak = 1; 04020 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 04021 } else 04022 p->echobreak = 0; 04023 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 04024 x = ZT_ONHOOK; 04025 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 04026 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 04027 return NULL; 04028 } 04029 p->dialing = 1; 04030 return &p->subs[index].f; 04031 } 04032 switch (p->sig) { 04033 case SIG_FXOLS: 04034 case SIG_FXOGS: 04035 case SIG_FXOKS: 04036 switch (ast->_state) { 04037 case AST_STATE_RINGING: 04038 zt_enable_ec(p); 04039 zt_train_ec(p); 04040 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04041 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04042 /* Make sure it stops ringing */ 04043 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04044 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 04045 if (p->cidspill) { 04046 /* Cancel any running CallerID spill */ 04047 free(p->cidspill); 04048 p->cidspill = NULL; 04049 } 04050 p->dialing = 0; 04051 p->callwaitcas = 0; 04052 if (p->confirmanswer) { 04053 /* Ignore answer if "confirm answer" is enabled */ 04054 p->subs[index].f.frametype = AST_FRAME_NULL; 04055 p->subs[index].f.subclass = 0; 04056 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04057 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04058 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04059 if (res < 0) { 04060 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04061 p->dop.dialstr[0] = '\0'; 04062 return NULL; 04063 } else { 04064 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04065 p->subs[index].f.frametype = AST_FRAME_NULL; 04066 p->subs[index].f.subclass = 0; 04067 p->dialing = 1; 04068 } 04069 p->dop.dialstr[0] = '\0'; 04070 ast_setstate(ast, AST_STATE_DIALING); 04071 } else 04072 ast_setstate(ast, AST_STATE_UP); 04073 return &p->subs[index].f; 04074 case AST_STATE_DOWN: 04075 ast_setstate(ast, AST_STATE_RING); 04076 ast->rings = 1; 04077 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04078 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04079 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04080 return &p->subs[index].f; 04081 case AST_STATE_UP: 04082 /* Make sure it stops ringing */ 04083 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04084 /* Okay -- probably call waiting*/ 04085 if (ast_bridged_channel(p->owner)) 04086 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04087 p->subs[index].needunhold = 1; 04088 break; 04089 case AST_STATE_RESERVED: 04090 /* Start up dialtone */ 04091 if (has_voicemail(p)) 04092 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04093 else 04094 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04095 break; 04096 default: 04097 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04098 } 04099 break; 04100 case SIG_FXSLS: 04101 case SIG_FXSGS: 04102 case SIG_FXSKS: 04103 if (ast->_state == AST_STATE_RING) { 04104 p->ringt = p->ringt_base; 04105 } 04106 04107 /* Fall through */ 04108 case SIG_EM: 04109 case SIG_EM_E1: 04110 case SIG_EMWINK: 04111 case SIG_FEATD: 04112 case SIG_FEATDMF: 04113 case SIG_FEATDMF_TA: 04114 case SIG_E911: 04115 case SIG_FGC_CAMA: 04116 case SIG_FGC_CAMAMF: 04117 case SIG_FEATB: 04118 case SIG_SF: 04119 case SIG_SFWINK: 04120 case SIG_SF_FEATD: 04121 case SIG_SF_FEATDMF: 04122 case SIG_SF_FEATB: 04123 if (ast->_state == AST_STATE_PRERING) 04124 ast_setstate(ast, AST_STATE_RING); 04125 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04126 if (option_debug) 04127 ast_log(LOG_DEBUG, "Ring detected\n"); 04128 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04129 p->subs[index].f.subclass = AST_CONTROL_RING; 04130 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04131 if (option_debug) 04132 ast_log(LOG_DEBUG, "Line answered\n"); 04133 if (p->confirmanswer) { 04134 p->subs[index].f.frametype = AST_FRAME_NULL; 04135 p->subs[index].f.subclass = 0; 04136 } else { 04137 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04138 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04139 ast_setstate(ast, AST_STATE_UP); 04140 } 04141 } else if (ast->_state != AST_STATE_RING) 04142 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04143 break; 04144 default: 04145 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04146 } 04147 break; 04148 #ifdef ZT_EVENT_RINGBEGIN 04149 case ZT_EVENT_RINGBEGIN: 04150 switch (p->sig) { 04151 case SIG_FXSLS: 04152 case SIG_FXSGS: 04153 case SIG_FXSKS: 04154 if (ast->_state == AST_STATE_RING) { 04155 p->ringt = p->ringt_base; 04156 } 04157 break; 04158 } 04159 break; 04160 #endif 04161 case ZT_EVENT_RINGEROFF: 04162 if (p->inalarm) break; 04163 if ((p->radio || (p->oprmode < 0))) break; 04164 ast->rings++; 04165 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04166 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04167 free(p->cidspill); 04168 p->cidspill = NULL; 04169 p->callwaitcas = 0; 04170 } 04171 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04172 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04173 break; 04174 case ZT_EVENT_RINGERON: 04175 break; 04176 case ZT_EVENT_NOALARM: 04177 p->inalarm = 0; 04178 #ifdef HAVE_PRI 04179 /* Extremely unlikely but just in case */ 04180 if (p->bearer) 04181 p->bearer->inalarm = 0; 04182 #endif 04183 if (!p->unknown_alarm) { 04184 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04185 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04186 "Channel: %d\r\n", p->channel); 04187 } else { 04188 p->unknown_alarm = 0; 04189 } 04190 break; 04191 case ZT_EVENT_WINKFLASH: 04192 if (p->inalarm) break; 04193 if (p->radio) break; 04194 if (p->oprmode < 0) break; 04195 if (p->oprmode > 1) 04196 { 04197 struct zt_params par; 04198 04199 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04200 { 04201 if (!par.rxisoffhook) 04202 { 04203 /* Make sure it stops ringing */ 04204 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04205 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04206 save_conference(p); 04207 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04208 } 04209 } 04210 break; 04211 } 04212 /* Remember last time we got a flash-hook */ 04213 gettimeofday(&p->flashtime, NULL); 04214 switch (mysig) { 04215 case SIG_FXOLS: 04216 case SIG_FXOGS: 04217 case SIG_FXOKS: 04218 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04219 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04220 p->callwaitcas = 0; 04221 04222 if (index != SUB_REAL) { 04223 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04224 goto winkflashdone; 04225 } 04226 04227 if (p->subs[SUB_CALLWAIT].owner) { 04228 /* Swap to call-wait */ 04229 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04230 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04231 p->owner = p->subs[SUB_REAL].owner; 04232 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04233 if (p->owner->_state == AST_STATE_RINGING) { 04234 ast_setstate(p->owner, AST_STATE_UP); 04235 p->subs[SUB_REAL].needanswer = 1; 04236 } 04237 p->callwaitingrepeat = 0; 04238 p->cidcwexpire = 0; 04239 /* Start music on hold if appropriate */ 04240 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04241 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04242 S_OR(p->mohsuggest, NULL), 04243 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04244 } 04245 p->subs[SUB_CALLWAIT].needhold = 1; 04246 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04247 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04248 S_OR(p->mohsuggest, NULL), 04249 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04250 } 04251 p->subs[SUB_REAL].needunhold = 1; 04252 } else if (!p->subs[SUB_THREEWAY].owner) { 04253 char cid_num[256]; 04254 char cid_name[256]; 04255 04256 if (!p->threewaycalling) { 04257 /* Just send a flash if no 3-way calling */ 04258 p->subs[SUB_REAL].needflash = 1; 04259 goto winkflashdone; 04260 } else if (!check_for_conference(p)) { 04261 if (p->zaptrcallerid && p->owner) { 04262 if (p->owner->cid.cid_num) 04263 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04264 if (p->owner->cid.cid_name) 04265 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04266 } 04267 /* XXX This section needs much more error checking!!! XXX */ 04268 /* Start a 3-way call if feasible */ 04269 if (!((ast->pbx) || 04270 (ast->_state == AST_STATE_UP) || 04271 (ast->_state == AST_STATE_RING))) { 04272 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04273 goto winkflashdone; 04274 } 04275 if (alloc_sub(p, SUB_THREEWAY)) { 04276 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04277 goto winkflashdone; 04278 } 04279 /* Make new channel */ 04280 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04281 if (p->zaptrcallerid) { 04282 if (!p->origcid_num) 04283 p->origcid_num = ast_strdup(p->cid_num); 04284 if (!p->origcid_name) 04285 p->origcid_name = ast_strdup(p->cid_name); 04286 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04287 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04288 } 04289 /* Swap things around between the three-way and real call */ 04290 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04291 /* Disable echo canceller for better dialing */ 04292 zt_disable_ec(p); 04293 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04294 if (res) 04295 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04296 p->owner = chan; 04297 pthread_attr_init(&attr); 04298 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04299 if (!chan) { 04300 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04301 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04302 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04303 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04304 zt_enable_ec(p); 04305 ast_hangup(chan); 04306 } else { 04307 if (option_verbose > 2) 04308 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04309 /* Start music on hold if appropriate */ 04310 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04311 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04312 S_OR(p->mohsuggest, NULL), 04313 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04314 } 04315 p->subs[SUB_THREEWAY].needhold = 1; 04316 } 04317 pthread_attr_destroy(&attr); 04318 } 04319 } else { 04320 /* Already have a 3 way call */ 04321 if (p->subs[SUB_THREEWAY].inthreeway) { 04322 /* Call is already up, drop the last person */ 04323 if (option_debug) 04324 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04325 /* If the primary call isn't answered yet, use it */ 04326 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04327 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04328 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04329 p->owner = p->subs[SUB_REAL].owner; 04330 } 04331 /* Drop the last call and stop the conference */ 04332 if (option_verbose > 2) 04333 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04334 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04335 p->subs[SUB_REAL].inthreeway = 0; 04336 p->subs[SUB_THREEWAY].inthreeway = 0; 04337 } else { 04338 /* Lets see what we're up to */ 04339 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04340 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04341 int otherindex = SUB_THREEWAY; 04342 04343 if (option_verbose > 2) 04344 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); 04345 /* Put them in the threeway, and flip */ 04346 p->subs[SUB_THREEWAY].inthreeway = 1; 04347 p->subs[SUB_REAL].inthreeway = 1; 04348 if (ast->_state == AST_STATE_UP) { 04349 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04350 otherindex = SUB_REAL; 04351 } 04352 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04353 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04354 p->subs[otherindex].needunhold = 1; 04355 p->owner = p->subs[SUB_REAL].owner; 04356 if (ast->_state == AST_STATE_RINGING) { 04357 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04358 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04359 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04360 } 04361 } else { 04362 if (option_verbose > 2) 04363 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04364 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04365 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04366 p->owner = p->subs[SUB_REAL].owner; 04367 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04368 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04369 p->subs[SUB_REAL].needunhold = 1; 04370 zt_enable_ec(p); 04371 } 04372 04373 } 04374 } 04375 winkflashdone: 04376 update_conf(p); 04377 break; 04378 case SIG_EM: 04379 case SIG_EM_E1: 04380 case SIG_EMWINK: 04381 case SIG_FEATD: 04382 case SIG_SF: 04383 case SIG_SFWINK: 04384 case SIG_SF_FEATD: 04385 case SIG_FXSLS: 04386 case SIG_FXSGS: 04387 if (p->dialing) 04388 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04389 else 04390 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04391 break; 04392 case SIG_FEATDMF_TA: 04393 switch (p->whichwink) { 04394 case 0: 04395 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04396 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04397 break; 04398 case 1: 04399 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04400 break; 04401 case 2: 04402 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04403 return NULL; 04404 } 04405 p->whichwink++; 04406 /* Fall through */ 04407 case SIG_FEATDMF: 04408 case SIG_E911: 04409 case SIG_FGC_CAMAMF: 04410 case SIG_FGC_CAMA: 04411 case SIG_FEATB: 04412 case SIG_SF_FEATDMF: 04413 case SIG_SF_FEATB: 04414 /* FGD MF *Must* wait for wink */ 04415 if (!ast_strlen_zero(p->dop.dialstr)) 04416 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04417 else if (res < 0) { 04418 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04419 p->dop.dialstr[0] = '\0'; 04420 return NULL; 04421 } else 04422 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04423 p->dop.dialstr[0] = '\0'; 04424 break; 04425 default: 04426 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04427 } 04428 break; 04429 case ZT_EVENT_HOOKCOMPLETE: 04430 if (p->inalarm) break; 04431 if ((p->radio || (p->oprmode < 0))) break; 04432 switch (mysig) { 04433 case SIG_FXSLS: /* only interesting for FXS */ 04434 case SIG_FXSGS: 04435 case SIG_FXSKS: 04436 case SIG_EM: 04437 case SIG_EM_E1: 04438 case SIG_EMWINK: 04439 case SIG_FEATD: 04440 case SIG_SF: 04441 case SIG_SFWINK: 04442 case SIG_SF_FEATD: 04443 if (!ast_strlen_zero(p->dop.dialstr)) 04444 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04445 else if (res < 0) { 04446 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04447 p->dop.dialstr[0] = '\0'; 04448 return NULL; 04449 } else 04450 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04451 p->dop.dialstr[0] = '\0'; 04452 p->dop.op = ZT_DIAL_OP_REPLACE; 04453 break; 04454 case SIG_FEATDMF: 04455 case SIG_FEATDMF_TA: 04456 case SIG_E911: 04457 case SIG_FGC_CAMA: 04458 case SIG_FGC_CAMAMF: 04459 case SIG_FEATB: 04460 case SIG_SF_FEATDMF: 04461 case SIG_SF_FEATB: 04462 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04463 break; 04464 default: 04465 break; 04466 } 04467 break; 04468 case ZT_EVENT_POLARITY: 04469 /* 04470 * If we get a Polarity Switch event, check to see 04471 * if we should change the polarity state and 04472 * mark the channel as UP or if this is an indication 04473 * of remote end disconnect. 04474 */ 04475 if (p->polarity == POLARITY_IDLE) { 04476 p->polarity = POLARITY_REV; 04477 if (p->answeronpolarityswitch && 04478 ((ast->_state == AST_STATE_DIALING) || 04479 (ast->_state == AST_STATE_RINGING))) { 04480 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04481 ast_setstate(p->owner, AST_STATE_UP); 04482 if (p->hanguponpolarityswitch) { 04483 gettimeofday(&p->polaritydelaytv, NULL); 04484 } 04485 } else 04486 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04487 } 04488 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04489 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04490 if (p->hanguponpolarityswitch && 04491 (p->polarityonanswerdelay > 0) && 04492 (p->polarity == POLARITY_REV) && 04493 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04494 /* Added log_debug information below to provide a better indication of what is going on */ 04495 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) ); 04496 04497 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04498 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04499 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04500 p->polarity = POLARITY_IDLE; 04501 } else { 04502 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); 04503 } 04504 } else { 04505 p->polarity = POLARITY_IDLE; 04506 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04507 } 04508 /* Added more log_debug information below to provide a better indication of what is going on */ 04509 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) ); 04510 break; 04511 default: 04512 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04513 } 04514 return &p->subs[index].f; 04515 }
static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2412 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), ast_channel_setoption(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_dsp_digitmode(), ast_dsp_free(), ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), 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, zt_pvt::mohsuggest, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::oprmode, 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, S_OR, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().
02413 { 02414 int res; 02415 int index,x, law; 02416 /*static int restore_gains(struct zt_pvt *p);*/ 02417 struct zt_pvt *p = ast->tech_pvt; 02418 struct zt_pvt *tmp = NULL; 02419 struct zt_pvt *prev = NULL; 02420 ZT_PARAMS par; 02421 02422 if (option_debug) 02423 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02424 if (!ast->tech_pvt) { 02425 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02426 return 0; 02427 } 02428 02429 ast_mutex_lock(&p->lock); 02430 02431 index = zt_get_index(ast, p, 1); 02432 02433 if (p->sig == SIG_PRI) { 02434 x = 1; 02435 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02436 } 02437 02438 x = 0; 02439 zt_confmute(p, 0); 02440 restore_gains(p); 02441 if (p->origcid_num) { 02442 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02443 free(p->origcid_num); 02444 p->origcid_num = NULL; 02445 } 02446 if (p->origcid_name) { 02447 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02448 free(p->origcid_name); 02449 p->origcid_name = NULL; 02450 } 02451 if (p->dsp) 02452 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02453 if (p->exten) 02454 p->exten[0] = '\0'; 02455 02456 if (option_debug) 02457 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02458 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02459 p->ignoredtmf = 0; 02460 02461 if (index > -1) { 02462 /* Real channel, do some fixup */ 02463 p->subs[index].owner = NULL; 02464 p->subs[index].needanswer = 0; 02465 p->subs[index].needflash = 0; 02466 p->subs[index].needringing = 0; 02467 p->subs[index].needbusy = 0; 02468 p->subs[index].needcongestion = 0; 02469 p->subs[index].linear = 0; 02470 p->subs[index].needcallerid = 0; 02471 p->polarity = POLARITY_IDLE; 02472 zt_setlinear(p->subs[index].zfd, 0); 02473 if (index == SUB_REAL) { 02474 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02475 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02476 if (p->subs[SUB_CALLWAIT].inthreeway) { 02477 /* We had flipped over to answer a callwait and now it's gone */ 02478 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02479 /* Move to the call-wait, but un-own us until they flip back. */ 02480 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02481 unalloc_sub(p, SUB_CALLWAIT); 02482 p->owner = NULL; 02483 } else { 02484 /* The three way hung up, but we still have a call wait */ 02485 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02486 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02487 unalloc_sub(p, SUB_THREEWAY); 02488 if (p->subs[SUB_REAL].inthreeway) { 02489 /* This was part of a three way call. Immediately make way for 02490 another call */ 02491 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02492 p->owner = p->subs[SUB_REAL].owner; 02493 } else { 02494 /* This call hasn't been completed yet... Set owner to NULL */ 02495 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02496 p->owner = NULL; 02497 } 02498 p->subs[SUB_REAL].inthreeway = 0; 02499 } 02500 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02501 /* Move to the call-wait and switch back to them. */ 02502 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02503 unalloc_sub(p, SUB_CALLWAIT); 02504 p->owner = p->subs[SUB_REAL].owner; 02505 if (p->owner->_state != AST_STATE_UP) 02506 p->subs[SUB_REAL].needanswer = 1; 02507 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02508 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 02509 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02510 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02511 unalloc_sub(p, SUB_THREEWAY); 02512 if (p->subs[SUB_REAL].inthreeway) { 02513 /* This was part of a three way call. Immediately make way for 02514 another call */ 02515 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02516 p->owner = p->subs[SUB_REAL].owner; 02517 } else { 02518 /* This call hasn't been completed yet... Set owner to NULL */ 02519 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02520 p->owner = NULL; 02521 } 02522 p->subs[SUB_REAL].inthreeway = 0; 02523 } 02524 } else if (index == SUB_CALLWAIT) { 02525 /* Ditch the holding callwait call, and immediately make it availabe */ 02526 if (p->subs[SUB_CALLWAIT].inthreeway) { 02527 /* This is actually part of a three way, placed on hold. Place the third part 02528 on music on hold now */ 02529 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 02530 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02531 S_OR(p->mohsuggest, NULL), 02532 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02533 } 02534 p->subs[SUB_THREEWAY].inthreeway = 0; 02535 /* Make it the call wait now */ 02536 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02537 unalloc_sub(p, SUB_THREEWAY); 02538 } else 02539 unalloc_sub(p, SUB_CALLWAIT); 02540 } else if (index == SUB_THREEWAY) { 02541 if (p->subs[SUB_CALLWAIT].inthreeway) { 02542 /* The other party of the three way call is currently in a call-wait state. 02543 Start music on hold for them, and take the main guy out of the third call */ 02544 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 02545 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02546 S_OR(p->mohsuggest, NULL), 02547 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02548 } 02549 p->subs[SUB_CALLWAIT].inthreeway = 0; 02550 } 02551 p->subs[SUB_REAL].inthreeway = 0; 02552 /* If this was part of a three way call index, let us make 02553 another three way call */ 02554 unalloc_sub(p, SUB_THREEWAY); 02555 } else { 02556 /* This wasn't any sort of call, but how are we an index? */ 02557 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02558 } 02559 } 02560 02561 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02562 p->owner = NULL; 02563 p->ringt = 0; 02564 p->distinctivering = 0; 02565 p->confirmanswer = 0; 02566 p->cidrings = 1; 02567 p->outgoing = 0; 02568 p->digital = 0; 02569 p->faxhandled = 0; 02570 p->pulsedial = 0; 02571 p->onhooktime = time(NULL); 02572 #ifdef HAVE_PRI 02573 p->proceeding = 0; 02574 p->progress = 0; 02575 p->alerting = 0; 02576 p->setup_ack = 0; 02577 #endif 02578 if (p->dsp) { 02579 ast_dsp_free(p->dsp); 02580 p->dsp = NULL; 02581 } 02582 02583 law = ZT_LAW_DEFAULT; 02584 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02585 if (res < 0) 02586 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02587 /* Perform low level hangup if no owner left */ 02588 #ifdef HAVE_PRI 02589 if (p->pri) { 02590 #ifdef SUPPORT_USERUSER 02591 const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02592 #endif 02593 02594 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02595 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02596 if (!pri_grab(p, p->pri)) { 02597 if (p->alreadyhungup) { 02598 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02599 02600 #ifdef SUPPORT_USERUSER 02601 pri_call_set_useruser(p->call, useruser); 02602 #endif 02603 02604 pri_hangup(p->pri->pri, p->call, -1); 02605 p->call = NULL; 02606 if (p->bearer) 02607 p->bearer->call = NULL; 02608 } else { 02609 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02610 int icause = ast->hangupcause ? ast->hangupcause : -1; 02611 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02612 02613 #ifdef SUPPORT_USERUSER 02614 pri_call_set_useruser(p->call, useruser); 02615 #endif 02616 02617 p->alreadyhungup = 1; 02618 if (p->bearer) 02619 p->bearer->alreadyhungup = 1; 02620 if (cause) { 02621 if (atoi(cause)) 02622 icause = atoi(cause); 02623 } 02624 pri_hangup(p->pri->pri, p->call, icause); 02625 } 02626 if (res < 0) 02627 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02628 pri_rel(p->pri); 02629 } else { 02630 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02631 res = -1; 02632 } 02633 } else { 02634 if (p->bearer) 02635 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02636 p->call = NULL; 02637 res = 0; 02638 } 02639 } 02640 #endif 02641 if (p->sig && (p->sig != SIG_PRI)) 02642 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02643 if (res < 0) { 02644 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02645 } 02646 switch (p->sig) { 02647 case SIG_FXOGS: 02648 case SIG_FXOLS: 02649 case SIG_FXOKS: 02650 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02651 if (!res) { 02652 #if 0 02653 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02654 #endif 02655 /* If they're off hook, try playing congestion */ 02656 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02657 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02658 else 02659 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02660 } 02661 break; 02662 case SIG_FXSGS: 02663 case SIG_FXSLS: 02664 case SIG_FXSKS: 02665 /* Make sure we're not made available for at least two seconds assuming 02666 we were actually used for an inbound or outbound call. */ 02667 if (ast->_state != AST_STATE_RESERVED) { 02668 time(&p->guardtime); 02669 p->guardtime += 2; 02670 } 02671 break; 02672 default: 02673 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02674 } 02675 if (p->cidspill) 02676 free(p->cidspill); 02677 if (p->sig) 02678 zt_disable_ec(p); 02679 x = 0; 02680 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02681 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02682 p->didtdd = 0; 02683 p->cidspill = NULL; 02684 p->callwaitcas = 0; 02685 p->callwaiting = p->permcallwaiting; 02686 p->hidecallerid = p->permhidecallerid; 02687 p->dialing = 0; 02688 p->rdnis[0] = '\0'; 02689 update_conf(p); 02690 reset_conf(p); 02691 /* Restore data mode */ 02692 if (p->sig == SIG_PRI) { 02693 x = 0; 02694 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02695 } 02696 #ifdef HAVE_PRI 02697 if (p->bearer) { 02698 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02699 /* Free up the bearer channel as well, and 02700 don't use its file descriptor anymore */ 02701 update_conf(p->bearer); 02702 reset_conf(p->bearer); 02703 p->bearer->owner = NULL; 02704 p->bearer->realcall = NULL; 02705 p->bearer = NULL; 02706 p->subs[SUB_REAL].zfd = -1; 02707 p->pri = NULL; 02708 } 02709 #endif 02710 restart_monitor(); 02711 } 02712 02713 p->callwaitingrepeat = 0; 02714 p->cidcwexpire = 0; 02715 p->oprmode = 0; 02716 ast->tech_pvt = NULL; 02717 ast_mutex_unlock(&p->lock); 02718 ast_module_unref(ast_module_info->self); 02719 if (option_verbose > 2) 02720 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02721 02722 ast_mutex_lock(&iflock); 02723 tmp = iflist; 02724 prev = NULL; 02725 if (p->destroy) { 02726 while (tmp) { 02727 if (tmp == p) { 02728 destroy_channel(prev, tmp, 0); 02729 break; 02730 } else { 02731 prev = tmp; 02732 tmp = tmp->next; 02733 } 02734 } 02735 } 02736 ast_mutex_unlock(&iflock); 02737 return 0; 02738 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5028 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_SRCUPDATE, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), 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, errno, func, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, zt_pvt::mohinterpret, option_debug, 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().
05029 { 05030 struct zt_pvt *p = chan->tech_pvt; 05031 int res=-1; 05032 int index; 05033 int func = ZT_FLASH; 05034 ast_mutex_lock(&p->lock); 05035 index = zt_get_index(chan, p, 0); 05036 if (option_debug) 05037 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 05038 if (index == SUB_REAL) { 05039 switch (condition) { 05040 case AST_CONTROL_BUSY: 05041 #ifdef HAVE_PRI 05042 if (p->priindication_oob && p->sig == SIG_PRI) { 05043 chan->hangupcause = AST_CAUSE_USER_BUSY; 05044 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05045 res = 0; 05046 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05047 if (p->pri->pri) { 05048 if (!pri_grab(p, p->pri)) { 05049 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05050 pri_rel(p->pri); 05051 } 05052 else 05053 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05054 } 05055 p->progress = 1; 05056 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05057 } else 05058 #endif 05059 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05060 break; 05061 case AST_CONTROL_RINGING: 05062 #ifdef HAVE_PRI 05063 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05064 if (p->pri->pri) { 05065 if (!pri_grab(p, p->pri)) { 05066 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05067 pri_rel(p->pri); 05068 } 05069 else 05070 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05071 } 05072 p->alerting = 1; 05073 } 05074 #endif 05075 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05076 if (chan->_state != AST_STATE_UP) { 05077 if ((chan->_state != AST_STATE_RING) || 05078 ((p->sig != SIG_FXSKS) && 05079 (p->sig != SIG_FXSLS) && 05080 (p->sig != SIG_FXSGS))) 05081 ast_setstate(chan, AST_STATE_RINGING); 05082 } 05083 break; 05084 case AST_CONTROL_PROCEEDING: 05085 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05086 #ifdef HAVE_PRI 05087 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05088 if (p->pri->pri) { 05089 if (!pri_grab(p, p->pri)) { 05090 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05091 pri_rel(p->pri); 05092 } 05093 else 05094 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05095 } 05096 p->proceeding = 1; 05097 } 05098 #endif 05099 /* don't continue in ast_indicate */ 05100 res = 0; 05101 break; 05102 case AST_CONTROL_PROGRESS: 05103 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05104 #ifdef HAVE_PRI 05105 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05106 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05107 if (p->pri->pri) { 05108 if (!pri_grab(p, p->pri)) { 05109 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05110 pri_rel(p->pri); 05111 } 05112 else 05113 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05114 } 05115 p->progress = 1; 05116 } 05117 #endif 05118 /* don't continue in ast_indicate */ 05119 res = 0; 05120 break; 05121 case AST_CONTROL_CONGESTION: 05122 chan->hangupcause = AST_CAUSE_CONGESTION; 05123 #ifdef HAVE_PRI 05124 if (p->priindication_oob && p->sig == SIG_PRI) { 05125 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05126 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05127 res = 0; 05128 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05129 if (p->pri) { 05130 if (!pri_grab(p, p->pri)) { 05131 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05132 pri_rel(p->pri); 05133 } else 05134 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05135 } 05136 p->progress = 1; 05137 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05138 } else 05139 #endif 05140 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05141 break; 05142 case AST_CONTROL_HOLD: 05143 #ifdef HAVE_PRI 05144 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05145 if (!pri_grab(p, p->pri)) { 05146 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05147 pri_rel(p->pri); 05148 } else 05149 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05150 } else 05151 #endif 05152 ast_moh_start(chan, data, p->mohinterpret); 05153 break; 05154 case AST_CONTROL_UNHOLD: 05155 #ifdef HAVE_PRI 05156 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05157 if (!pri_grab(p, p->pri)) { 05158 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05159 pri_rel(p->pri); 05160 } else 05161 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05162 } else 05163 #endif 05164 ast_moh_stop(chan); 05165 break; 05166 case AST_CONTROL_RADIO_KEY: 05167 if (p->radio) 05168 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05169 res = 0; 05170 break; 05171 case AST_CONTROL_RADIO_UNKEY: 05172 if (p->radio) 05173 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05174 res = 0; 05175 break; 05176 case AST_CONTROL_FLASH: 05177 /* flash hookswitch */ 05178 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05179 /* Clear out the dial buffer */ 05180 p->dop.dialstr[0] = '\0'; 05181 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05182 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05183 chan->name, strerror(errno)); 05184 } else 05185 res = 0; 05186 } else 05187 res = 0; 05188 break; 05189 case AST_CONTROL_SRCUPDATE: 05190 res = 0; 05191 break; 05192 case -1: 05193 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05194 break; 05195 } 05196 } else 05197 res = 0; 05198 ast_mutex_unlock(&p->lock); 05199 return res; 05200 }
Definition at line 3087 of file chan_zap.c.
References ast_log(), LOG_WARNING, and master.
Referenced by zt_bridge().
03087 { 03088 int x; 03089 if (!slave || !master) { 03090 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03091 return; 03092 } 03093 for (x = 0; x < MAX_SLAVES; x++) { 03094 if (!master->slaves[x]) { 03095 master->slaves[x] = slave; 03096 break; 03097 } 03098 } 03099 if (x >= MAX_SLAVES) { 03100 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03101 master->slaves[MAX_SLAVES - 1] = slave; 03102 } 03103 if (slave->master) 03104 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03105 slave->master = master; 03106 03107 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03108 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | , | |
int | , | |||
int | , | |||
int | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5202 of file chan_zap.c.
References 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_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_random(), ast_safe_string_alloc(), AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_transfercapability2str(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::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, zt_pvt::cid_name, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, ast_channel::context, zt_pvt::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, free, global_jbconf, zt_pvt::hardwaredtmf, language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, PRI_TRANS_CAP_DIGITAL, 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, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::writeformat, zap_tech, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
05203 { 05204 struct ast_channel *tmp; 05205 int deflaw; 05206 int res; 05207 int x,y; 05208 int features; 05209 char *b2 = NULL; 05210 ZT_PARAMS ps; 05211 if (i->subs[index].owner) { 05212 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05213 return NULL; 05214 } 05215 y = 1; 05216 do { 05217 if (b2) 05218 free(b2); 05219 #ifdef HAVE_PRI 05220 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05221 b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05222 else 05223 #endif 05224 if (i->channel == CHAN_PSEUDO) 05225 b2 = ast_safe_string_alloc("pseudo-%ld", ast_random()); 05226 else 05227 b2 = ast_safe_string_alloc("%d-%d", i->channel, y); 05228 for (x = 0; x < 3; x++) { 05229 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05230 break; 05231 } 05232 y++; 05233 } while (x < 3); 05234 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2); 05235 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05236 free(b2); 05237 if (!tmp) 05238 return NULL; 05239 tmp->tech = &zap_tech; 05240 ps.channo = i->channel; 05241 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05242 if (res) { 05243 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05244 ps.curlaw = ZT_LAW_MULAW; 05245 } 05246 if (ps.curlaw == ZT_LAW_ALAW) 05247 deflaw = AST_FORMAT_ALAW; 05248 else 05249 deflaw = AST_FORMAT_ULAW; 05250 if (law) { 05251 if (law == ZT_LAW_ALAW) 05252 deflaw = AST_FORMAT_ALAW; 05253 else 05254 deflaw = AST_FORMAT_ULAW; 05255 } 05256 tmp->fds[0] = i->subs[index].zfd; 05257 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05258 /* Start out assuming ulaw since it's smaller :) */ 05259 tmp->rawreadformat = deflaw; 05260 tmp->readformat = deflaw; 05261 tmp->rawwriteformat = deflaw; 05262 tmp->writeformat = deflaw; 05263 i->subs[index].linear = 0; 05264 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05265 features = 0; 05266 if (index == SUB_REAL) { 05267 if (i->busydetect && CANBUSYDETECT(i)) 05268 features |= DSP_FEATURE_BUSY_DETECT; 05269 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05270 features |= DSP_FEATURE_CALL_PROGRESS; 05271 if ((!i->outgoing && (i->callprogress & 4)) || 05272 (i->outgoing && (i->callprogress & 2))) { 05273 features |= DSP_FEATURE_FAX_DETECT; 05274 } 05275 #ifdef ZT_TONEDETECT 05276 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05277 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05278 #endif 05279 i->hardwaredtmf = 0; 05280 features |= DSP_FEATURE_DTMF_DETECT; 05281 #ifdef ZT_TONEDETECT 05282 } else if (NEED_MFDETECT(i)) { 05283 i->hardwaredtmf = 1; 05284 features |= DSP_FEATURE_DTMF_DETECT; 05285 } 05286 #endif 05287 } 05288 if (features) { 05289 if (i->dsp) { 05290 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05291 } else { 05292 if (i->channel != CHAN_PSEUDO) 05293 i->dsp = ast_dsp_new(); 05294 else 05295 i->dsp = NULL; 05296 if (i->dsp) { 05297 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05298 #ifdef HAVE_PRI 05299 /* We cannot do progress detection until receives PROGRESS message */ 05300 if (i->outgoing && (i->sig == SIG_PRI)) { 05301 /* Remember requested DSP features, don't treat 05302 talking as ANSWER */ 05303 features = 0; 05304 } 05305 #endif 05306 ast_dsp_set_features(i->dsp, features); 05307 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05308 if (!ast_strlen_zero(progzone)) 05309 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05310 if (i->busydetect && CANBUSYDETECT(i)) { 05311 ast_dsp_set_busy_count(i->dsp, i->busycount); 05312 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05313 } 05314 } 05315 } 05316 } 05317 05318 if (state == AST_STATE_RING) 05319 tmp->rings = 1; 05320 tmp->tech_pvt = i; 05321 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05322 /* Only FXO signalled stuff can be picked up */ 05323 tmp->callgroup = i->callgroup; 05324 tmp->pickupgroup = i->pickupgroup; 05325 } 05326 if (!ast_strlen_zero(i->language)) 05327 ast_string_field_set(tmp, language, i->language); 05328 if (!i->owner) 05329 i->owner = tmp; 05330 if (!ast_strlen_zero(i->accountcode)) 05331 ast_string_field_set(tmp, accountcode, i->accountcode); 05332 if (i->amaflags) 05333 tmp->amaflags = i->amaflags; 05334 i->subs[index].owner = tmp; 05335 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05336 ast_string_field_set(tmp, call_forward, i->call_forward); 05337 /* If we've been told "no ADSI" then enforce it */ 05338 if (!i->adsi) 05339 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05340 if (!ast_strlen_zero(i->exten)) 05341 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05342 if (!ast_strlen_zero(i->rdnis)) 05343 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05344 if (!ast_strlen_zero(i->dnid)) 05345 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05346 05347 /* Don't use ast_set_callerid() here because it will 05348 * generate a needless NewCallerID event */ 05349 #ifdef PRI_ANI 05350 if (!ast_strlen_zero(i->cid_ani)) 05351 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05352 else 05353 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05354 #else 05355 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05356 #endif 05357 tmp->cid.cid_pres = i->callingpres; 05358 tmp->cid.cid_ton = i->cid_ton; 05359 #ifdef HAVE_PRI 05360 tmp->transfercapability = transfercapability; 05361 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05362 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05363 i->digital = 1; 05364 /* Assume calls are not idle calls unless we're told differently */ 05365 i->isidlecall = 0; 05366 i->alreadyhungup = 0; 05367 #endif 05368 /* clear the fake event in case we posted one before we had ast_channel */ 05369 i->fake_event = 0; 05370 /* Assure there is no confmute on this channel */ 05371 zt_confmute(i, 0); 05372 /* Configure the new channel jb */ 05373 ast_jb_configure(tmp, &global_jbconf); 05374 if (startpbx) { 05375 if (ast_pbx_start(tmp)) { 05376 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05377 ast_hangup(tmp); 05378 i->owner = NULL; 05379 return NULL; 05380 } 05381 } 05382 05383 ast_module_ref(ast_module_info->self); 05384 05385 return tmp; 05386 }
static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 872 of file chan_zap.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
00873 { 00874 int fd; 00875 int isnum; 00876 int chan = 0; 00877 int bs; 00878 int x; 00879 isnum = 1; 00880 for (x = 0; x < strlen(fn); x++) { 00881 if (!isdigit(fn[x])) { 00882 isnum = 0; 00883 break; 00884 } 00885 } 00886 if (isnum) { 00887 chan = atoi(fn); 00888 if (chan < 1) { 00889 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 00890 return -1; 00891 } 00892 fn = "/dev/zap/channel"; 00893 } 00894 fd = open(fn, O_RDWR | O_NONBLOCK); 00895 if (fd < 0) { 00896 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 00897 return -1; 00898 } 00899 if (chan) { 00900 if (ioctl(fd, ZT_SPECIFY, &chan)) { 00901 x = errno; 00902 close(fd); 00903 errno = x; 00904 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 00905 return -1; 00906 } 00907 } 00908 bs = READ_SIZE; 00909 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) { 00910 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 00911 x = errno; 00912 close(fd); 00913 errno = x; 00914 return -1; 00915 } 00916 return fd; 00917 }
static struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4635 of file chan_zap.c.
References __zt_exception(), ast_channel::_state, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_dsp_process(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_callerid(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_subchannel::buffer, zt_pvt::busydetect, zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::channel, CHECK_BLOCKING, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, zt_pvt::dsp, errno, zt_subchannel::f, f, zt_pvt::fake_event, zt_pvt::firstradio, ast_frame::frametype, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, S_OR, ast_frame::samples, send_callerid(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_get_index(), zt_handle_dtmfup(), and zt_setlinear().
04636 { 04637 struct zt_pvt *p = ast->tech_pvt; 04638 int res; 04639 int index; 04640 void *readbuf; 04641 struct ast_frame *f; 04642 04643 04644 ast_mutex_lock(&p->lock); 04645 04646 index = zt_get_index(ast, p, 0); 04647 04648 /* Hang up if we don't really exist */ 04649 if (index < 0) { 04650 ast_log(LOG_WARNING, "We dont exist?\n"); 04651 ast_mutex_unlock(&p->lock); 04652 return NULL; 04653 } 04654 04655 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04656 04657 p->subs[index].f.frametype = AST_FRAME_NULL; 04658 p->subs[index].f.datalen = 0; 04659 p->subs[index].f.samples = 0; 04660 p->subs[index].f.mallocd = 0; 04661 p->subs[index].f.offset = 0; 04662 p->subs[index].f.subclass = 0; 04663 p->subs[index].f.delivery = ast_tv(0,0); 04664 p->subs[index].f.src = "zt_read"; 04665 p->subs[index].f.data = NULL; 04666 04667 /* make sure it sends initial key state as first frame */ 04668 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04669 { 04670 ZT_PARAMS ps; 04671 04672 ps.channo = p->channel; 04673 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04674 ast_mutex_unlock(&p->lock); 04675 return NULL; 04676 } 04677 p->firstradio = 1; 04678 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04679 if (ps.rxisoffhook) 04680 { 04681 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04682 } 04683 else 04684 { 04685 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04686 } 04687 ast_mutex_unlock(&p->lock); 04688 return &p->subs[index].f; 04689 } 04690 if (p->ringt == 1) { 04691 ast_mutex_unlock(&p->lock); 04692 return NULL; 04693 } 04694 else if (p->ringt > 0) 04695 p->ringt--; 04696 04697 if (p->subs[index].needringing) { 04698 /* Send ringing frame if requested */ 04699 p->subs[index].needringing = 0; 04700 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04701 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04702 ast_setstate(ast, AST_STATE_RINGING); 04703 ast_mutex_unlock(&p->lock); 04704 return &p->subs[index].f; 04705 } 04706 04707 if (p->subs[index].needbusy) { 04708 /* Send busy frame if requested */ 04709 p->subs[index].needbusy = 0; 04710 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04711 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04712 ast_mutex_unlock(&p->lock); 04713 return &p->subs[index].f; 04714 } 04715 04716 if (p->subs[index].needcongestion) { 04717 /* Send congestion frame if requested */ 04718 p->subs[index].needcongestion = 0; 04719 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04720 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04721 ast_mutex_unlock(&p->lock); 04722 return &p->subs[index].f; 04723 } 04724 04725 if (p->subs[index].needcallerid) { 04726 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04727 S_OR(p->lastcid_name, NULL), 04728 S_OR(p->lastcid_num, NULL) 04729 ); 04730 p->subs[index].needcallerid = 0; 04731 } 04732 04733 if (p->subs[index].needanswer) { 04734 /* Send answer frame if requested */ 04735 p->subs[index].needanswer = 0; 04736 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04737 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04738 ast_mutex_unlock(&p->lock); 04739 return &p->subs[index].f; 04740 } 04741 04742 if (p->subs[index].needflash) { 04743 /* Send answer frame if requested */ 04744 p->subs[index].needflash = 0; 04745 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04746 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04747 ast_mutex_unlock(&p->lock); 04748 return &p->subs[index].f; 04749 } 04750 04751 if (p->subs[index].needhold) { 04752 /* Send answer frame if requested */ 04753 p->subs[index].needhold = 0; 04754 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04755 p->subs[index].f.subclass = AST_CONTROL_HOLD; 04756 ast_mutex_unlock(&p->lock); 04757 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 04758 return &p->subs[index].f; 04759 } 04760 04761 if (p->subs[index].needunhold) { 04762 /* Send answer frame if requested */ 04763 p->subs[index].needunhold = 0; 04764 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04765 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 04766 ast_mutex_unlock(&p->lock); 04767 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 04768 return &p->subs[index].f; 04769 } 04770 04771 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04772 if (!p->subs[index].linear) { 04773 p->subs[index].linear = 1; 04774 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04775 if (res) 04776 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04777 } 04778 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04779 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04780 if (p->subs[index].linear) { 04781 p->subs[index].linear = 0; 04782 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04783 if (res) 04784 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04785 } 04786 } else { 04787 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04788 ast_mutex_unlock(&p->lock); 04789 return NULL; 04790 } 04791 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04792 CHECK_BLOCKING(ast); 04793 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04794 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04795 /* Check for hangup */ 04796 if (res < 0) { 04797 f = NULL; 04798 if (res == -1) { 04799 if (errno == EAGAIN) { 04800 /* Return "NULL" frame if there is nobody there */ 04801 ast_mutex_unlock(&p->lock); 04802 return &p->subs[index].f; 04803 } else if (errno == ELAST) { 04804 f = __zt_exception(ast); 04805 } else 04806 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04807 } 04808 ast_mutex_unlock(&p->lock); 04809 return f; 04810 } 04811 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04812 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04813 f = __zt_exception(ast); 04814 ast_mutex_unlock(&p->lock); 04815 return f; 04816 } 04817 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04818 int c; 04819 04820 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04821 if (c < 0) { 04822 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04823 ast_mutex_unlock(&p->lock); 04824 return NULL; 04825 } 04826 if (c) { /* if a char to return */ 04827 p->subs[index].f.subclass = 0; 04828 p->subs[index].f.frametype = AST_FRAME_TEXT; 04829 p->subs[index].f.mallocd = 0; 04830 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04831 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04832 p->subs[index].f.datalen = 1; 04833 *((char *) p->subs[index].f.data) = c; 04834 ast_mutex_unlock(&p->lock); 04835 return &p->subs[index].f; 04836 } 04837 } 04838 if (p->callwaitingrepeat) 04839 p->callwaitingrepeat--; 04840 if (p->cidcwexpire) 04841 p->cidcwexpire--; 04842 /* Repeat callwaiting */ 04843 if (p->callwaitingrepeat == 1) { 04844 p->callwaitrings++; 04845 zt_callwait(ast); 04846 } 04847 /* Expire CID/CW */ 04848 if (p->cidcwexpire == 1) { 04849 if (option_verbose > 2) 04850 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 04851 restore_conference(p); 04852 } 04853 if (p->subs[index].linear) { 04854 p->subs[index].f.datalen = READ_SIZE * 2; 04855 } else 04856 p->subs[index].f.datalen = READ_SIZE; 04857 04858 /* Handle CallerID Transmission */ 04859 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 04860 send_callerid(p); 04861 } 04862 04863 p->subs[index].f.frametype = AST_FRAME_VOICE; 04864 p->subs[index].f.subclass = ast->rawreadformat; 04865 p->subs[index].f.samples = READ_SIZE; 04866 p->subs[index].f.mallocd = 0; 04867 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04868 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 04869 #if 0 04870 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 04871 #endif 04872 if (p->dialing || /* Transmitting something */ 04873 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 04874 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 04875 ) { 04876 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 04877 don't send anything */ 04878 p->subs[index].f.frametype = AST_FRAME_NULL; 04879 p->subs[index].f.subclass = 0; 04880 p->subs[index].f.samples = 0; 04881 p->subs[index].f.mallocd = 0; 04882 p->subs[index].f.offset = 0; 04883 p->subs[index].f.data = NULL; 04884 p->subs[index].f.datalen= 0; 04885 } 04886 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 04887 /* Perform busy detection. etc on the zap line */ 04888 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 04889 if (f) { 04890 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 04891 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 04892 /* Treat this as a "hangup" instead of a "busy" on the assumption that 04893 a busy */ 04894 f = NULL; 04895 } 04896 } else if (f->frametype == AST_FRAME_DTMF) { 04897 #ifdef HAVE_PRI 04898 if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { 04899 /* Don't accept in-band DTMF when in overlap dial mode */ 04900 f->frametype = AST_FRAME_NULL; 04901 f->subclass = 0; 04902 } 04903 #endif 04904 /* DSP clears us of being pulse */ 04905 p->pulsedial = 0; 04906 } 04907 } 04908 } else 04909 f = &p->subs[index].f; 04910 04911 if (f && (f->frametype == AST_FRAME_DTMF)) 04912 zt_handle_dtmfup(ast, index, &f); 04913 04914 /* If we have a fake_event, trigger exception to handle it */ 04915 if (p->fake_event) 04916 ast_set_flag(ast, AST_FLAG_EXCEPTION); 04917 04918 ast_mutex_unlock(&p->lock); 04919 return f; 04920 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 7782 of file chan_zap.c.
References alloc_sub(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CDR_CALLWAIT, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_NOTICE, 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, zt_subchannel::zfd, and zt_new().
07783 { 07784 ast_group_t groupmatch = 0; 07785 int channelmatch = -1; 07786 int roundrobin = 0; 07787 int callwait = 0; 07788 int busy = 0; 07789 struct zt_pvt *p; 07790 struct ast_channel *tmp = NULL; 07791 char *dest=NULL; 07792 int x; 07793 char *s; 07794 char opt=0; 07795 int res=0, y=0; 07796 int backwards = 0; 07797 #ifdef HAVE_PRI 07798 int crv; 07799 int bearer = -1; 07800 int trunkgroup; 07801 struct zt_pri *pri=NULL; 07802 #endif 07803 struct zt_pvt *exit, *start, *end; 07804 ast_mutex_t *lock; 07805 int channelmatched = 0; 07806 int groupmatched = 0; 07807 07808 /* Assume we're locking the iflock */ 07809 lock = &iflock; 07810 start = iflist; 07811 end = ifend; 07812 if (data) { 07813 dest = ast_strdupa((char *)data); 07814 } else { 07815 ast_log(LOG_WARNING, "Channel requested with no data\n"); 07816 return NULL; 07817 } 07818 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 07819 /* Retrieve the group number */ 07820 char *stringp=NULL; 07821 stringp=dest + 1; 07822 s = strsep(&stringp, "/"); 07823 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07824 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 07825 return NULL; 07826 } 07827 groupmatch = ((ast_group_t) 1 << x); 07828 if (toupper(dest[0]) == 'G') { 07829 if (dest[0] == 'G') { 07830 backwards = 1; 07831 p = ifend; 07832 } else 07833 p = iflist; 07834 } else { 07835 if (dest[0] == 'R') { 07836 backwards = 1; 07837 p = round_robin[x]?round_robin[x]->prev:ifend; 07838 if (!p) 07839 p = ifend; 07840 } else { 07841 p = round_robin[x]?round_robin[x]->next:iflist; 07842 if (!p) 07843 p = iflist; 07844 } 07845 roundrobin = 1; 07846 } 07847 } else { 07848 char *stringp=NULL; 07849 stringp=dest; 07850 s = strsep(&stringp, "/"); 07851 p = iflist; 07852 if (!strcasecmp(s, "pseudo")) { 07853 /* Special case for pseudo */ 07854 x = CHAN_PSEUDO; 07855 channelmatch = x; 07856 } 07857 #ifdef HAVE_PRI 07858 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 07859 if ((trunkgroup < 1) || (crv < 1)) { 07860 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 07861 return NULL; 07862 } 07863 res--; 07864 for (x = 0; x < NUM_SPANS; x++) { 07865 if (pris[x].trunkgroup == trunkgroup) { 07866 pri = pris + x; 07867 lock = &pri->lock; 07868 start = pri->crvs; 07869 end = pri->crvend; 07870 break; 07871 } 07872 } 07873 if (!pri) { 07874 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 07875 return NULL; 07876 } 07877 channelmatch = crv; 07878 p = pris[x].crvs; 07879 } 07880 #endif 07881 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07882 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 07883 return NULL; 07884 } else { 07885 channelmatch = x; 07886 } 07887 } 07888 /* Search for an unowned channel */ 07889 ast_mutex_lock(lock); 07890 exit = p; 07891 while (p && !tmp) { 07892 if (roundrobin) 07893 round_robin[x] = p; 07894 #if 0 07895 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 07896 #endif 07897 07898 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 07899 if (option_debug) 07900 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 07901 if (p->inalarm) 07902 goto next; 07903 07904 callwait = (p->owner != NULL); 07905 #ifdef HAVE_PRI 07906 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 07907 if (p->sig != SIG_FXSKS) { 07908 /* Gotta find an actual channel to use for this 07909 CRV if this isn't a callwait */ 07910 bearer = pri_find_empty_chan(pri, 0); 07911 if (bearer < 0) { 07912 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 07913 p = NULL; 07914 break; 07915 } 07916 pri_assign_bearer(p, pri, pri->pvts[bearer]); 07917 } else { 07918 if (alloc_sub(p, 0)) { 07919 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 07920 p = NULL; 07921 break; 07922 } else 07923 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 07924 p->pri = pri; 07925 } 07926 } 07927 #endif 07928 if (p->channel == CHAN_PSEUDO) { 07929 p = chandup(p); 07930 if (!p) { 07931 break; 07932 } 07933 } 07934 if (p->owner) { 07935 if (alloc_sub(p, SUB_CALLWAIT)) { 07936 p = NULL; 07937 break; 07938 } 07939 } 07940 p->outgoing = 1; 07941 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 07942 #ifdef HAVE_PRI 07943 if (p->bearer) { 07944 /* Log owner to bearer channel, too */ 07945 p->bearer->owner = tmp; 07946 } 07947 #endif 07948 /* Make special notes */ 07949 if (res > 1) { 07950 if (opt == 'c') { 07951 /* Confirm answer */ 07952 p->confirmanswer = 1; 07953 } else if (opt == 'r') { 07954 /* Distinctive ring */ 07955 if (res < 3) 07956 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 07957 else 07958 p->distinctivering = y; 07959 } else if (opt == 'd') { 07960 /* If this is an ISDN call, make it digital */ 07961 p->digital = 1; 07962 if (tmp) 07963 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 07964 } else { 07965 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 07966 } 07967 } 07968 /* Note if the call is a call waiting call */ 07969 if (tmp && callwait) 07970 tmp->cdrflags |= AST_CDR_CALLWAIT; 07971 break; 07972 } 07973 next: 07974 if (backwards) { 07975 p = p->prev; 07976 if (!p) 07977 p = end; 07978 } else { 07979 p = p->next; 07980 if (!p) 07981 p = start; 07982 } 07983 /* stop when you roll to the one that we started from */ 07984 if (p == exit) 07985 break; 07986 } 07987 ast_mutex_unlock(lock); 07988 restart_monitor(); 07989 if (callwait) 07990 *cause = AST_CAUSE_BUSY; 07991 else if (!tmp) { 07992 if (channelmatched) { 07993 if (busy) 07994 *cause = AST_CAUSE_BUSY; 07995 } else if (groupmatched) { 07996 *cause = AST_CAUSE_CONGESTION; 07997 } 07998 } 07999 08000 return tmp; 08001 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3466 of file chan_zap.c.
References ast_log(), errno, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), and zt_handle_event().
03467 { 03468 int x; 03469 int res; 03470 /* Make sure our transmit state is on hook */ 03471 x = 0; 03472 x = ZT_ONHOOK; 03473 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03474 do { 03475 x = ZT_RING; 03476 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03477 if (res) { 03478 switch (errno) { 03479 case EBUSY: 03480 case EINTR: 03481 /* Wait just in case */ 03482 usleep(10000); 03483 continue; 03484 case EINPROGRESS: 03485 res = 0; 03486 break; 03487 default: 03488 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03489 res = 0; 03490 } 03491 } 03492 } while (res); 03493 return res; 03494 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 11441 of file chan_zap.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), ast_free, AST_LAW, ast_log(), ast_malloc, zt_pvt::channel, END_SILENCE_LEN, errno, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_ERROR, 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().
11442 { 11443 #define END_SILENCE_LEN 400 11444 #define HEADER_MS 50 11445 #define TRAILER_MS 5 11446 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 11447 #define ASCII_BYTES_PER_CHAR 80 11448 11449 unsigned char *buf,*mybuf; 11450 struct zt_pvt *p = c->tech_pvt; 11451 struct pollfd fds[1]; 11452 int size,res,fd,len,x; 11453 int bytes=0; 11454 /* Initial carrier (imaginary) */ 11455 float cr = 1.0; 11456 float ci = 0.0; 11457 float scont = 0.0; 11458 int index; 11459 11460 index = zt_get_index(c, p, 0); 11461 if (index < 0) { 11462 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 11463 return -1; 11464 } 11465 if (!text[0]) return(0); /* if nothing to send, dont */ 11466 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 11467 if (p->mate) 11468 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 11469 else 11470 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 11471 if (!buf) 11472 return -1; 11473 mybuf = buf; 11474 if (p->mate) { 11475 int codec = AST_LAW(p); 11476 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 11477 PUT_CLID_MARKMS; 11478 } 11479 /* Put actual message */ 11480 for (x = 0; text[x]; x++) { 11481 PUT_CLID(text[x]); 11482 } 11483 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 11484 PUT_CLID_MARKMS; 11485 } 11486 len = bytes; 11487 buf = mybuf; 11488 } else { 11489 len = tdd_generate(p->tdd, buf, text); 11490 if (len < 1) { 11491 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 11492 free(mybuf); 11493 return -1; 11494 } 11495 } 11496 memset(buf + len, 0x7f, END_SILENCE_LEN); 11497 len += END_SILENCE_LEN; 11498 fd = p->subs[index].zfd; 11499 while (len) { 11500 if (ast_check_hangup(c)) { 11501 free(mybuf); 11502 return -1; 11503 } 11504 size = len; 11505 if (size > READ_SIZE) 11506 size = READ_SIZE; 11507 fds[0].fd = fd; 11508 fds[0].events = POLLOUT | POLLPRI; 11509 fds[0].revents = 0; 11510 res = poll(fds, 1, -1); 11511 if (!res) { 11512 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 11513 continue; 11514 } 11515 /* if got exception */ 11516 if (fds[0].revents & POLLPRI) { 11517 ast_free(mybuf); 11518 return -1; 11519 } 11520 if (!(fds[0].revents & POLLOUT)) { 11521 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 11522 continue; 11523 } 11524 res = write(fd, buf, size); 11525 if (res != size) { 11526 if (res == -1) { 11527 free(mybuf); 11528 return -1; 11529 } 11530 if (option_debug) 11531 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 11532 break; 11533 } 11534 len -= size; 11535 buf += size; 11536 } 11537 free(mybuf); 11538 return(0); 11539 }
static int zt_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 1615 of file chan_zap.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by __zt_exception(), handle_init_event(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().
01616 { 01617 int x, res; 01618 01619 x = hs; 01620 res = ioctl(fd, ZT_HOOK, &x); 01621 01622 if (res < 0) { 01623 if (errno == EINPROGRESS) 01624 return 0; 01625 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01626 } 01627 01628 return res; 01629 }
static int zt_setlinear | ( | int | zfd, | |
int | linear | |||
) | [static] |
Definition at line 925 of file chan_zap.c.
Referenced by send_callerid(), ss_thread(), zt_hangup(), zt_new(), zt_read(), and zt_write().
00926 { 00927 int res; 00928 res = ioctl(zfd, ZT_SETLINEAR, &linear); 00929 if (res) 00930 return res; 00931 return 0; 00932 }
static int zt_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2825 of file chan_zap.c.
References ast_check_hangup(), ast_dsp_digitmode(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_ECHOCAN, AST_OPTION_OPRMODE, 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, errno, pollfd::events, pollfd::fd, zt_pvt::law, len, LOG_DEBUG, LOG_WARNING, zt_pvt::mate, oprmode::mode, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, oprmode::peer, 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(), zt_enable_ec(), and zt_get_index().
02826 { 02827 char *cp; 02828 signed char *scp; 02829 int x; 02830 int index; 02831 struct zt_pvt *p = chan->tech_pvt, *pp; 02832 struct oprmode *oprmode; 02833 02834 02835 /* all supported options require data */ 02836 if (!data || (datalen < 1)) { 02837 errno = EINVAL; 02838 return -1; 02839 } 02840 02841 switch (option) { 02842 case AST_OPTION_TXGAIN: 02843 scp = (signed char *) data; 02844 index = zt_get_index(chan, p, 0); 02845 if (index < 0) { 02846 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02847 return -1; 02848 } 02849 if (option_debug) 02850 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02851 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02852 case AST_OPTION_RXGAIN: 02853 scp = (signed char *) data; 02854 index = zt_get_index(chan, p, 0); 02855 if (index < 0) { 02856 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 02857 return -1; 02858 } 02859 if (option_debug) 02860 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 02861 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 02862 case AST_OPTION_TONE_VERIFY: 02863 if (!p->dsp) 02864 break; 02865 cp = (char *) data; 02866 switch (*cp) { 02867 case 1: 02868 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 02869 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 02870 break; 02871 case 2: 02872 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 02873 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 02874 break; 02875 default: 02876 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 02877 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 02878 break; 02879 } 02880 break; 02881 case AST_OPTION_TDD: 02882 /* turn on or off TDD */ 02883 cp = (char *) data; 02884 p->mate = 0; 02885 if (!*cp) { /* turn it off */ 02886 if (option_debug) 02887 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 02888 if (p->tdd) 02889 tdd_free(p->tdd); 02890 p->tdd = 0; 02891 break; 02892 } 02893 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 02894 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 02895 zt_disable_ec(p); 02896 /* otherwise, turn it on */ 02897 if (!p->didtdd) { /* if havent done it yet */ 02898 unsigned char mybuf[41000], *buf; 02899 int size, res, fd, len; 02900 struct pollfd fds[1]; 02901 02902 buf = mybuf; 02903 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 02904 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 02905 len = 40000; 02906 index = zt_get_index(chan, p, 0); 02907 if (index < 0) { 02908 ast_log(LOG_WARNING, "No index in TDD?\n"); 02909 return -1; 02910 } 02911 fd = p->subs[index].zfd; 02912 while (len) { 02913 if (ast_check_hangup(chan)) 02914 return -1; 02915 size = len; 02916 if (size > READ_SIZE) 02917 size = READ_SIZE; 02918 fds[0].fd = fd; 02919 fds[0].events = POLLPRI | POLLOUT; 02920 fds[0].revents = 0; 02921 res = poll(fds, 1, -1); 02922 if (!res) { 02923 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 02924 continue; 02925 } 02926 /* if got exception */ 02927 if (fds[0].revents & POLLPRI) 02928 return -1; 02929 if (!(fds[0].revents & POLLOUT)) { 02930 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 02931 continue; 02932 } 02933 res = write(fd, buf, size); 02934 if (res != size) { 02935 if (res == -1) return -1; 02936 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 02937 break; 02938 } 02939 len -= size; 02940 buf += size; 02941 } 02942 p->didtdd = 1; /* set to have done it now */ 02943 } 02944 if (*cp == 2) { /* Mate mode */ 02945 if (p->tdd) 02946 tdd_free(p->tdd); 02947 p->tdd = 0; 02948 p->mate = 1; 02949 break; 02950 } 02951 if (!p->tdd) { /* if we dont have one yet */ 02952 p->tdd = tdd_new(); /* allocate one */ 02953 } 02954 break; 02955 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 02956 if (!p->dsp) 02957 break; 02958 cp = (char *) data; 02959 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 02960 *cp ? "ON" : "OFF", (int) *cp, chan->name); 02961 p->dtmfrelax = 0; 02962 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 02963 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 02964 break; 02965 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 02966 cp = (char *) data; 02967 if (!*cp) { 02968 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 02969 x = 0; 02970 zt_disable_ec(p); 02971 } else { 02972 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 02973 x = 1; 02974 } 02975 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 02976 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 02977 break; 02978 case AST_OPTION_OPRMODE: /* Operator services mode */ 02979 oprmode = (struct oprmode *) data; 02980 pp = oprmode->peer->tech_pvt; 02981 p->oprmode = pp->oprmode = 0; 02982 /* setup peers */ 02983 p->oprpeer = pp; 02984 pp->oprpeer = p; 02985 /* setup modes, if any */ 02986 if (oprmode->mode) 02987 { 02988 pp->oprmode = oprmode->mode; 02989 p->oprmode = -oprmode->mode; 02990 } 02991 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 02992 oprmode->mode, chan->name,oprmode->peer->name);; 02993 break; 02994 case AST_OPTION_ECHOCAN: 02995 cp = (char *) data; 02996 if (*cp) { 02997 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 02998 zt_enable_ec(p); 02999 } else { 03000 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 03001 zt_disable_ec(p); 03002 } 03003 break; 03004 } 03005 errno = 0; 03006 03007 return 0; 03008 }
static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1447 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echotraining, LOG_DEBUG, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_answer(), and zt_handle_event().
01448 { 01449 int x; 01450 int res; 01451 if (p && p->echocancel && p->echotraining) { 01452 x = p->echotraining; 01453 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01454 if (res) 01455 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01456 else { 01457 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01458 } 01459 } else 01460 ast_log(LOG_DEBUG, "No echo training requested\n"); 01461 }
Definition at line 3029 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().
03030 { 03031 /* Unlink a specific slave or all slaves/masters from a given master */ 03032 int x; 03033 int hasslaves; 03034 if (!master) 03035 return; 03036 if (needlock) { 03037 ast_mutex_lock(&master->lock); 03038 if (slave) { 03039 while (ast_mutex_trylock(&slave->lock)) { 03040 ast_mutex_unlock(&master->lock); 03041 usleep(1); 03042 ast_mutex_lock(&master->lock); 03043 } 03044 } 03045 } 03046 hasslaves = 0; 03047 for (x = 0; x < MAX_SLAVES; x++) { 03048 if (master->slaves[x]) { 03049 if (!slave || (master->slaves[x] == slave)) { 03050 /* Take slave out of the conference */ 03051 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03052 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03053 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03054 master->slaves[x]->master = NULL; 03055 master->slaves[x] = NULL; 03056 } else 03057 hasslaves = 1; 03058 } 03059 if (!hasslaves) 03060 master->inconference = 0; 03061 } 03062 if (!slave) { 03063 if (master->master) { 03064 /* Take master out of the conference */ 03065 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03066 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03067 hasslaves = 0; 03068 for (x = 0; x < MAX_SLAVES; x++) { 03069 if (master->master->slaves[x] == master) 03070 master->master->slaves[x] = NULL; 03071 else if (master->master->slaves[x]) 03072 hasslaves = 1; 03073 } 03074 if (!hasslaves) 03075 master->master->inconference = 0; 03076 } 03077 master->master = NULL; 03078 } 03079 update_conf(master); 03080 if (needlock) { 03081 if (slave) 03082 ast_mutex_unlock(&slave->lock); 03083 ast_mutex_unlock(&master->lock); 03084 } 03085 }
static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 265 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00266 { 00267 int i, j = 0; 00268 i = ZT_IOMUX_SIGEVENT; 00269 if (ioctl(fd, ZT_IOMUX, &i) == -1) 00270 return -1; 00271 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00272 return -1; 00273 return j; 00274 }
static int zt_wink | ( | struct zt_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 5408 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05409 { 05410 int j; 05411 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05412 for (;;) 05413 { 05414 /* set bits of interest */ 05415 j = ZT_IOMUX_SIGEVENT; 05416 /* wait for some happening */ 05417 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05418 /* exit loop if we have it */ 05419 if (j & ZT_IOMUX_SIGEVENT) break; 05420 } 05421 /* get the event info */ 05422 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05423 return 0; 05424 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4945 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, errno, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, my_zt_write(), 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().
04946 { 04947 struct zt_pvt *p = ast->tech_pvt; 04948 int res; 04949 int index; 04950 index = zt_get_index(ast, p, 0); 04951 if (index < 0) { 04952 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 04953 return -1; 04954 } 04955 04956 #if 0 04957 #ifdef HAVE_PRI 04958 ast_mutex_lock(&p->lock); 04959 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04960 if (p->pri->pri) { 04961 if (!pri_grab(p, p->pri)) { 04962 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04963 pri_rel(p->pri); 04964 } else 04965 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04966 } 04967 p->proceeding=1; 04968 } 04969 ast_mutex_unlock(&p->lock); 04970 #endif 04971 #endif 04972 /* Write a frame of (presumably voice) data */ 04973 if (frame->frametype != AST_FRAME_VOICE) { 04974 if (frame->frametype != AST_FRAME_IMAGE) 04975 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 04976 return 0; 04977 } 04978 if ((frame->subclass != AST_FORMAT_SLINEAR) && 04979 (frame->subclass != AST_FORMAT_ULAW) && 04980 (frame->subclass != AST_FORMAT_ALAW)) { 04981 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 04982 return -1; 04983 } 04984 if (p->dialing) { 04985 if (option_debug) 04986 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 04987 return 0; 04988 } 04989 if (!p->owner) { 04990 if (option_debug) 04991 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 04992 return 0; 04993 } 04994 if (p->cidspill) { 04995 if (option_debug) 04996 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 04997 return 0; 04998 } 04999 /* Return if it's not valid data */ 05000 if (!frame->data || !frame->datalen) 05001 return 0; 05002 05003 if (frame->subclass == AST_FORMAT_SLINEAR) { 05004 if (!p->subs[index].linear) { 05005 p->subs[index].linear = 1; 05006 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05007 if (res) 05008 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 05009 } 05010 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 05011 } else { 05012 /* x-law already */ 05013 if (p->subs[index].linear) { 05014 p->subs[index].linear = 0; 05015 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05016 if (res) 05017 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 05018 } 05019 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 05020 } 05021 if (res < 0) { 05022 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05023 return -1; 05024 } 05025 return 0; 05026 }
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 740 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 751 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 165 of file chan_zap.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 109 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 204 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 205 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 10200 of file chan_zap.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 209 of file chan_zap.c.
struct zt_distRings drings [static] |
char* events[] [static] |
int firstdigittimeout = 16000 [static] |
int gendigittimeout = 8000 [static] |
struct ast_jb_conf global_jbconf [static] |
Definition at line 116 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 235 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 229 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 247 of file chan_zap.c.
char* name |
Definition at line 1126 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 737 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 211 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 207 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 290 of file chan_zap.c.
struct zt_pvt* round_robin[32] |
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 10192 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 10188 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 159 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 738 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
char zap_restart_usage[] [static] |
Definition at line 10204 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 10096 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 10196 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 687 of file chan_zap.c.
Referenced by __unload_module(), load_module(), ss_thread(), and zt_new().