#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"
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 ZT_MAX_SPANS |
#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_GSM (0x100000 | ZT_SIG_CLEAR) |
#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) |
static int | app_zapEC (struct ast_channel *chan, void *data) |
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, const 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_sendmessage (struct ast_channel *c, const char *dest, const char *text, int ispdu) |
static int | zt_sendtext (struct ast_channel *c, const char *text) |
static int | zt_set_hook (int fd, int hs) |
static int | zt_setlaw (int zfd, int law) |
static int | zt_setlinear (int zfd, int linear) |
static int | zt_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
static int | zt_tdd_sendtext (struct ast_channel *c, const char *text) |
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 char | gsm_modem_exten [AST_MAX_EXTENSION] |
static char | gsm_modem_pin [20] |
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 |
struct zt_pvt * | round_robin [32] |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char * | subnames [] |
static const char | tdesc [] = "Zapata Telephony Driver" |
static int | user_has_defined_cadences = 0 |
static struct ast_cli_entry | zap_cli [] |
static char | zap_restart_usage [] |
static char | zap_show_cadences_help [] |
static char | zap_show_status_usage [] |
static struct ast_channel_tech | zap_tech |
static char * | zapEC_app = "zapEC" |
static char * | zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel" |
static char * | zapEC_tdesc = "Enable/disable Echo cancelation" |
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_tdd_sendtext().
#define AST_LAW | ( | p | ) | (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
Definition at line 162 of file chan_zap.c.
Referenced by do_monitor(), send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_tdd_sendtext().
#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 289 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 205 of file chan_zap.c.
Referenced by build_channels(), enable_dtmf_detect(), mkintf(), process_zap(), zt_new(), and zt_request().
#define CHANNEL_PSEUDO -12 |
Definition at line 160 of file chan_zap.c.
#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 440 of file chan_zap.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 441 of file chan_zap.c.
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define DCHAN_NOTINALARM (1 << 1) |
Definition at line 208 of file chan_zap.c.
#define DCHAN_PROVISIONED (1 << 0) |
Definition at line 207 of file chan_zap.c.
#define DCHAN_UP (1 << 2) |
Definition at line 209 of file chan_zap.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Define if you want to check the hook state for an FXO (FXS signalled) interface before dialing on it. Certain FXO interfaces always think they're out of service with this method however.
Definition at line 158 of file chan_zap.c.
Referenced by zt_chan_conf_default().
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
8,000 ms
Definition at line 293 of file chan_zap.c.
#define END_SILENCE_LEN 400 |
Referenced by zt_tdd_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) |
#define HANGUP 1 |
Definition at line 11548 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_tdd_sendtext().
#define HEADER_MS 50 |
Referenced by zt_tdd_sendtext().
#define ISTRUNK | ( | p | ) |
#define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 286 of file chan_zap.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 287 of file chan_zap.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'zapchan'.
Definition at line 11912 of file chan_zap.c.
Referenced by process_zap().
#define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 203 of file chan_zap.c.
Referenced by mkintf().
#define MAX_SLAVES 4 |
Definition at line 443 of file chan_zap.c.
Referenced by isslavenative(), update_conf(), zap_show_channel(), zt_link(), and zt_unlink().
#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 165 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
#define NUM_CADENCE_MAX 25 |
#define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 202 of file chan_zap.c.
#define NUM_SPANS ZT_MAX_SPANS |
Definition at line 201 of file chan_zap.c.
#define POLARITY_IDLE 0 |
Definition at line 397 of file chan_zap.c.
Referenced by ss_thread(), unalloc_sub(), zt_handle_event(), and zt_hangup().
#define POLARITY_REV 1 |
Definition at line 398 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), and zt_handle_event().
#define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 284 of file chan_zap.c.
Referenced by my_zt_write(), process_zap(), send_cwcidspill(), zt_callwait(), zt_open(), zt_read(), zt_setoption(), and zt_tdd_sendtext().
#define sig2str zap_sig2str |
Definition at line 1281 of file chan_zap.c.
Referenced by action_zapshowchannels(), build_channels(), handle_init_event(), mkintf(), ss_thread(), zap_show_channel(), and zt_handle_event().
#define SIG_E911 (0x1000000 | ZT_SIG_EM) |
Definition at line 180 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM ZT_SIG_EM |
Definition at line 175 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 197 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
Definition at line 176 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 179 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 177 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 178 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 181 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 182 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 183 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FXOGS ZT_SIG_FXOGS |
Definition at line 188 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_FXOKS ZT_SIG_FXOKS |
Definition at line 189 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 187 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_FXSGS ZT_SIG_FXSGS |
Definition at line 185 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 186 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 184 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_indicate().
#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
Definition at line 198 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 199 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_GSM (0x100000 | ZT_SIG_CLEAR) |
Definition at line 191 of file chan_zap.c.
Referenced by mkintf(), process_zap(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_hangup(), zt_sendmessage(), and zt_sendtext().
#define SIG_PRI ZT_SIG_CLEAR |
Definition at line 190 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(), zt_sendmessage(), zt_sendtext(), and zt_write().
#define SIG_SF ZT_SIG_SF |
Definition at line 192 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 196 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 194 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
Definition at line 195 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
Definition at line 193 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), 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 393 of file chan_zap.c.
#define SUB_REAL 0 |
Active call
Definition at line 392 of file chan_zap.c.
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 394 of file chan_zap.c.
#define tdesc "Zapata Telephony" |
Definition at line 12998 of file chan_zap.c.
#define TRAILER_MS 5 |
Referenced by zt_tdd_sendtext().
#define TRANSFER 0 |
#define ZT_EVENT_DTMFDOWN 0 |
#define ZT_EVENT_DTMFUP 0 |
static int __unload_module | ( | void | ) | [static] |
Definition at line 11729 of file chan_zap.c.
References ast_channel_unregister(), ast_cli_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, zt_pvt::subs, VERBOSE_PREFIX_3, zt_subchannel::zfd, and zt_close().
11730 { 11731 int x; 11732 struct zt_pvt *p, *pl; 11733 11734 #ifdef HAVE_PRI 11735 int i; 11736 for (i = 0; i < NUM_SPANS; i++) { 11737 if (pris[i].master != AST_PTHREADT_NULL) 11738 pthread_cancel(pris[i].master); 11739 } 11740 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 11741 ast_unregister_application(zap_send_keypad_facility_app); 11742 ast_unregister_application(zapCD_app); 11743 ast_unregister_application(zapInband_app); 11744 #endif 11745 #ifdef HAVE_GSMAT 11746 ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); 11747 ast_cli_unregister(&gsm_send_sms); 11748 ast_cli_unregister(&gsm_send_pdu); 11749 ast_cli_unregister(&gsm_show_status); 11750 #endif 11751 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 11752 ast_unregister_application(zapEC_app); 11753 ast_manager_unregister( "ZapDialOffhook" ); 11754 ast_manager_unregister( "ZapHangup" ); 11755 ast_manager_unregister( "ZapTransfer" ); 11756 ast_manager_unregister( "ZapDNDoff" ); 11757 ast_manager_unregister( "ZapDNDon" ); 11758 ast_manager_unregister("ZapShowChannels"); 11759 ast_manager_unregister("ZapRestart"); 11760 ast_channel_unregister(&zap_tech); 11761 ast_mutex_lock(&iflock); 11762 /* Hangup all interfaces if they have an owner */ 11763 p = iflist; 11764 while (p) { 11765 if (p->owner) 11766 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 11767 p = p->next; 11768 } 11769 ast_mutex_unlock(&iflock); 11770 ast_mutex_lock(&monlock); 11771 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 11772 pthread_cancel(monitor_thread); 11773 pthread_kill(monitor_thread, SIGURG); 11774 pthread_join(monitor_thread, NULL); 11775 } 11776 monitor_thread = AST_PTHREADT_STOP; 11777 ast_mutex_unlock(&monlock); 11778 11779 ast_mutex_lock(&iflock); 11780 /* Destroy all the interfaces and free their memory */ 11781 p = iflist; 11782 while (p) { 11783 /* Free any callerid */ 11784 if (p->cidspill) 11785 free(p->cidspill); 11786 /* Close the zapata thingy */ 11787 if (p->subs[SUB_REAL].zfd > -1) 11788 zt_close(p->subs[SUB_REAL].zfd); 11789 pl = p; 11790 p = p->next; 11791 x = pl->channel; 11792 /* Free associated memory */ 11793 if (pl) 11794 destroy_zt_pvt(&pl); 11795 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 11796 } 11797 iflist = NULL; 11798 ifcount = 0; 11799 ast_mutex_unlock(&iflock); 11800 #ifdef HAVE_PRI 11801 for (i = 0; i < NUM_SPANS; i++) { 11802 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 11803 pthread_join(pris[i].master, NULL); 11804 zt_close(pris[i].fds[i]); 11805 } 11806 #endif 11807 return 0; 11808 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4669 of file chan_zap.c.
References ast_channel::_state, 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::callwaitingrepeat, zt_pvt::channel, zt_pvt::cidcwexpire, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, event2str(), zt_subchannel::f, zt_pvt::fake_event, ast_channel::fds, zt_pvt::flashtime, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, zt_subchannel::needanswer, 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().
04670 { 04671 struct zt_pvt *p = ast->tech_pvt; 04672 int res; 04673 int usedindex=-1; 04674 int index; 04675 struct ast_frame *f; 04676 04677 04678 index = zt_get_index(ast, p, 1); 04679 04680 p->subs[index].f.frametype = AST_FRAME_NULL; 04681 p->subs[index].f.datalen = 0; 04682 p->subs[index].f.samples = 0; 04683 p->subs[index].f.mallocd = 0; 04684 p->subs[index].f.offset = 0; 04685 p->subs[index].f.subclass = 0; 04686 p->subs[index].f.delivery = ast_tv(0,0); 04687 p->subs[index].f.src = "zt_exception"; 04688 p->subs[index].f.data = NULL; 04689 04690 04691 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04692 /* If nobody owns us, absorb the event appropriately, otherwise 04693 we loop indefinitely. This occurs when, during call waiting, the 04694 other end hangs up our channel so that it no longer exists, but we 04695 have neither FLASH'd nor ONHOOK'd to signify our desire to 04696 change to the other channel. */ 04697 if (p->fake_event) { 04698 res = p->fake_event; 04699 p->fake_event = 0; 04700 } else 04701 res = zt_get_event(p->subs[SUB_REAL].zfd); 04702 /* Switch to real if there is one and this isn't something really silly... */ 04703 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04704 (res != ZT_EVENT_HOOKCOMPLETE)) { 04705 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04706 p->owner = p->subs[SUB_REAL].owner; 04707 if (p->owner && ast_bridged_channel(p->owner)) 04708 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04709 p->subs[SUB_REAL].needunhold = 1; 04710 } 04711 switch (res) { 04712 case ZT_EVENT_ONHOOK: 04713 zt_disable_ec(p); 04714 if (p->owner) { 04715 if (option_verbose > 2) 04716 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04717 zt_ring_phone(p); 04718 p->callwaitingrepeat = 0; 04719 p->cidcwexpire = 0; 04720 } else 04721 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04722 update_conf(p); 04723 break; 04724 case ZT_EVENT_RINGOFFHOOK: 04725 zt_enable_ec(p); 04726 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04727 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04728 p->subs[SUB_REAL].needanswer = 1; 04729 p->dialing = 0; 04730 } 04731 break; 04732 case ZT_EVENT_HOOKCOMPLETE: 04733 case ZT_EVENT_RINGERON: 04734 case ZT_EVENT_RINGEROFF: 04735 /* Do nothing */ 04736 break; 04737 case ZT_EVENT_WINKFLASH: 04738 gettimeofday(&p->flashtime, NULL); 04739 if (p->owner) { 04740 if (option_verbose > 2) 04741 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04742 if (p->owner->_state != AST_STATE_UP) { 04743 /* Answer if necessary */ 04744 usedindex = zt_get_index(p->owner, p, 0); 04745 if (usedindex > -1) { 04746 p->subs[usedindex].needanswer = 1; 04747 } 04748 ast_setstate(p->owner, AST_STATE_UP); 04749 } 04750 p->callwaitingrepeat = 0; 04751 p->cidcwexpire = 0; 04752 if (ast_bridged_channel(p->owner)) 04753 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04754 p->subs[SUB_REAL].needunhold = 1; 04755 } else 04756 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04757 update_conf(p); 04758 break; 04759 default: 04760 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04761 } 04762 f = &p->subs[index].f; 04763 return f; 04764 } 04765 if (!(p->radio || (p->oprmode < 0)) && option_debug) 04766 ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04767 /* If it's not us, return NULL immediately */ 04768 if (ast != p->owner) { 04769 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04770 f = &p->subs[index].f; 04771 return f; 04772 } 04773 f = zt_handle_event(ast); 04774 return f; 04775 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11616 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), TRANSFER, and zap_fake_event().
Referenced by load_module().
11617 { 11618 struct zt_pvt *p = NULL; 11619 const char *channel = astman_get_header(m, "ZapChannel"); 11620 11621 if (ast_strlen_zero(channel)) { 11622 astman_send_error(s, m, "No channel specified"); 11623 return 0; 11624 } 11625 p = find_channel(atoi(channel)); 11626 if (!p) { 11627 astman_send_error(s, m, "No such channel"); 11628 return 0; 11629 } 11630 zap_fake_event(p,TRANSFER); 11631 astman_send_ack(s, m, "ZapTransfer"); 11632 return 0; 11633 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11635 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, and zap_fake_event().
Referenced by load_module().
11636 { 11637 struct zt_pvt *p = NULL; 11638 const char *channel = astman_get_header(m, "ZapChannel"); 11639 11640 if (ast_strlen_zero(channel)) { 11641 astman_send_error(s, m, "No channel specified"); 11642 return 0; 11643 } 11644 p = find_channel(atoi(channel)); 11645 if (!p) { 11646 astman_send_error(s, m, "No such channel"); 11647 return 0; 11648 } 11649 zap_fake_event(p,HANGUP); 11650 astman_send_ack(s, m, "ZapHangup"); 11651 return 0; 11652 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11654 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), zt_pvt::owner, and zap_queue_frame().
Referenced by load_module().
11655 { 11656 struct zt_pvt *p = NULL; 11657 const char *channel = astman_get_header(m, "ZapChannel"); 11658 const char *number = astman_get_header(m, "Number"); 11659 int i; 11660 11661 if (ast_strlen_zero(channel)) { 11662 astman_send_error(s, m, "No channel specified"); 11663 return 0; 11664 } 11665 if (ast_strlen_zero(number)) { 11666 astman_send_error(s, m, "No number specified"); 11667 return 0; 11668 } 11669 p = find_channel(atoi(channel)); 11670 if (!p) { 11671 astman_send_error(s, m, "No such channel"); 11672 return 0; 11673 } 11674 if (!p->owner) { 11675 astman_send_error(s, m, "Channel does not have it's owner"); 11676 return 0; 11677 } 11678 for (i = 0; i < strlen(number); i++) { 11679 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 11680 zap_queue_frame(p, &f, NULL); 11681 } 11682 astman_send_ack(s, m, "ZapDialOffhook"); 11683 return 0; 11684 }
static int action_zapdndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11597 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, and find_channel().
Referenced by load_module().
11598 { 11599 struct zt_pvt *p = NULL; 11600 const char *channel = astman_get_header(m, "ZapChannel"); 11601 11602 if (ast_strlen_zero(channel)) { 11603 astman_send_error(s, m, "No channel specified"); 11604 return 0; 11605 } 11606 p = find_channel(atoi(channel)); 11607 if (!p) { 11608 astman_send_error(s, m, "No such channel"); 11609 return 0; 11610 } 11611 p->dnd = 0; 11612 astman_send_ack(s, m, "DND Disabled"); 11613 return 0; 11614 }
static int action_zapdndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11578 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, and find_channel().
Referenced by load_module().
11579 { 11580 struct zt_pvt *p = NULL; 11581 const char *channel = astman_get_header(m, "ZapChannel"); 11582 11583 if (ast_strlen_zero(channel)) { 11584 astman_send_error(s, m, "No channel specified"); 11585 return 0; 11586 } 11587 p = find_channel(atoi(channel)); 11588 if (!p) { 11589 astman_send_error(s, m, "No such channel"); 11590 return 0; 11591 } 11592 p->dnd = 1; 11593 astman_send_ack(s, m, "DND Enabled"); 11594 return 0; 11595 }
static int action_zaprestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11205 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), and zap_restart().
Referenced by load_module().
11206 { 11207 if (zap_restart() != 0) { 11208 astman_send_error(s, m, "Failed rereading zaptel configuration"); 11209 return 1; 11210 } 11211 astman_send_ack(s, m, "ZapRestart: Success"); 11212 return 0; 11213 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11686 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, zt_pvt::sig, and sig2str.
Referenced by load_module().
11687 { 11688 struct zt_pvt *tmp = NULL; 11689 const char *id = astman_get_header(m, "ActionID"); 11690 char idText[256] = ""; 11691 11692 astman_send_ack(s, m, "Zapata channel status will follow"); 11693 if (!ast_strlen_zero(id)) 11694 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 11695 11696 ast_mutex_lock(&iflock); 11697 11698 tmp = iflist; 11699 while (tmp) { 11700 if (tmp->channel > 0) { 11701 int alarm = get_alarms(tmp); 11702 astman_append(s, 11703 "Event: ZapShowChannels\r\n" 11704 "Channel: %d\r\n" 11705 "Signalling: %s\r\n" 11706 "Context: %s\r\n" 11707 "DND: %s\r\n" 11708 "Alarm: %s\r\n" 11709 "%s" 11710 "\r\n", 11711 tmp->channel, sig2str(tmp->sig), tmp->context, 11712 tmp->dnd ? "Enabled" : "Disabled", 11713 alarm2str(alarm), idText); 11714 } 11715 11716 tmp = tmp->next; 11717 } 11718 11719 ast_mutex_unlock(&iflock); 11720 11721 astman_append(s, 11722 "Event: ZapShowChannelsComplete\r\n" 11723 "%s" 11724 "\r\n", 11725 idText); 11726 return 0; 11727 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1190 of file chan_zap.c.
References alarms.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01191 { 01192 int x; 01193 for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) { 01194 if (alarms[x].alarm & alarm) 01195 return alarms[x].name; 01196 } 01197 return alarm ? "Unknown Alarm" : "No Alarm"; 01198 }
static int alloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 988 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().
00989 { 00990 ZT_BUFFERINFO bi; 00991 int res; 00992 if (p->subs[x].zfd < 0) { 00993 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 00994 if (p->subs[x].zfd > -1) { 00995 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 00996 if (!res) { 00997 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 00998 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 00999 bi.numbufs = numbufs; 01000 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 01001 if (res < 0) { 01002 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 01003 } 01004 } else 01005 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 01006 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 01007 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd); 01008 zt_close(p->subs[x].zfd); 01009 p->subs[x].zfd = -1; 01010 return -1; 01011 } 01012 if (option_debug) 01013 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 01014 return 0; 01015 } else 01016 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 01017 return -1; 01018 } 01019 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 01020 return -1; 01021 }
static int app_zapEC | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 11124 of file chan_zap.c.
References ast_log(), ast_verbose(), LOG_WARNING, option_verbose, ast_channel::tech, ast_channel::tech_pvt, ast_channel_tech::type, VERBOSE_PREFIX_3, zt_disable_ec(), and zt_enable_ec().
Referenced by load_module().
11125 { 11126 int res=-1; 11127 struct zt_pvt *p = NULL; 11128 11129 if (!data) { 11130 ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n"); 11131 } 11132 if (chan && !strcasecmp("ZAP",chan->tech->type)) { 11133 p = chan->tech_pvt; 11134 if (!p) return res; 11135 if (!strcasecmp("on",(char *)data)) { 11136 zt_enable_ec(p); 11137 res = 0; 11138 if (option_verbose > 3) { 11139 ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name); 11140 } 11141 } else if (!strcasecmp("off",(char *)data)) { 11142 zt_disable_ec(p); 11143 res = 0; 11144 if (option_verbose > 3) { 11145 ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name); 11146 } 11147 } else { 11148 ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data); 11149 } 11150 } else { 11151 ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n"); 11152 res = 0; 11153 } 11154 11155 return res; 11156 }
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 3650 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, LOG_WARNING, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.
03651 { 03652 /* In order to transfer, we need at least one of the channels to 03653 actually be in a call bridge. We can't conference two applications 03654 together (but then, why would we want to?) */ 03655 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03656 /* The three-way person we're about to transfer to could still be in MOH, so 03657 stop if now if appropriate */ 03658 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03659 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03660 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03661 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03662 } 03663 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03664 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03665 } 03666 if (p->subs[SUB_REAL].owner->cdr) { 03667 /* Move CDR from second channel to current one */ 03668 p->subs[SUB_THREEWAY].owner->cdr = 03669 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03670 p->subs[SUB_REAL].owner->cdr = NULL; 03671 } 03672 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03673 /* Move CDR from second channel's bridge to current one */ 03674 p->subs[SUB_THREEWAY].owner->cdr = 03675 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03676 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03677 } 03678 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03679 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03680 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03681 return -1; 03682 } 03683 /* Orphan the channel after releasing the lock */ 03684 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03685 unalloc_sub(p, SUB_THREEWAY); 03686 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03687 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03688 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03689 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03690 } 03691 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03692 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03693 } 03694 if (p->subs[SUB_THREEWAY].owner->cdr) { 03695 /* Move CDR from second channel to current one */ 03696 p->subs[SUB_REAL].owner->cdr = 03697 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03698 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03699 } 03700 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03701 /* Move CDR from second channel's bridge to current one */ 03702 p->subs[SUB_REAL].owner->cdr = 03703 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03704 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03705 } 03706 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03707 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03708 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03709 return -1; 03710 } 03711 /* Three-way is now the REAL */ 03712 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03713 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03714 unalloc_sub(p, SUB_THREEWAY); 03715 /* Tell the caller not to hangup */ 03716 return 1; 03717 } else { 03718 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03719 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03720 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03721 return -1; 03722 } 03723 return 0; 03724 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
ast_group_t | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7866 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, zt_pvt::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().
07867 { 07868 int res; 07869 ZT_PARAMS par; 07870 07871 /* First, check group matching */ 07872 if (groupmatch) { 07873 if ((p->group & groupmatch) != groupmatch) 07874 return 0; 07875 *groupmatched = 1; 07876 } 07877 /* Check to see if we have a channel match */ 07878 if (channelmatch != -1) { 07879 if (p->channel != channelmatch) 07880 return 0; 07881 *channelmatched = 1; 07882 } 07883 /* We're at least busy at this point */ 07884 if (busy) { 07885 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07886 *busy = 1; 07887 } 07888 /* If do not disturb, definitely not */ 07889 if (p->dnd) 07890 return 0; 07891 /* If guard time, definitely not */ 07892 if (p->guardtime && (time(NULL) < p->guardtime)) 07893 return 0; 07894 07895 /* If no owner definitely available */ 07896 if (!p->owner) { 07897 #ifdef HAVE_PRI 07898 /* Trust PRI */ 07899 if (p->pri) { 07900 if (p->resetting || p->call) 07901 return 0; 07902 else 07903 return 1; 07904 } 07905 #endif 07906 #ifdef HAVE_GSMAT 07907 if (p->gsm.modul) { 07908 return gsm_available(p->gsm.modul); 07909 } 07910 07911 #endif 07912 if (!(p->radio || (p->oprmode < 0))) 07913 { 07914 if (!p->sig || (p->sig == SIG_FXSLS)) 07915 return 1; 07916 /* Check hook state */ 07917 if (p->subs[SUB_REAL].zfd > -1) 07918 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07919 else { 07920 /* Assume not off hook on CVRS */ 07921 res = 0; 07922 par.rxisoffhook = 0; 07923 } 07924 if (res) { 07925 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07926 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07927 /* When "onhook" that means no battery on the line, and thus 07928 it is out of service..., if it's on a TDM card... If it's a channel 07929 bank, there is no telling... */ 07930 if (par.rxbits > -1) 07931 return 1; 07932 if (par.rxisoffhook) 07933 return 1; 07934 else 07935 #ifdef ZAP_CHECK_HOOKSTATE 07936 return 0; 07937 #else 07938 return 1; 07939 #endif 07940 } else if (par.rxisoffhook) { 07941 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07942 /* Not available when the other end is off hook */ 07943 return 0; 07944 } 07945 } 07946 return 1; 07947 } 07948 07949 /* If it's not an FXO, forget about call wait */ 07950 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07951 return 0; 07952 07953 if (!p->callwaiting) { 07954 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07955 return 0; 07956 } 07957 07958 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07959 /* If there is already a call waiting call, then we can't take a second one */ 07960 return 0; 07961 } 07962 07963 if ((p->owner->_state != AST_STATE_UP) && 07964 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07965 /* If the current call is not up, then don't allow the call */ 07966 return 0; 07967 } 07968 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07969 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07970 return 0; 07971 } 07972 /* We're cool */ 07973 return 1; 07974 }
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 11820 of file chan_zap.c.
References ast_log(), ast_strdupa, ast_verbose(), zt_chan_conf::chan, CHAN_PSEUDO, LOG_ERROR, LOG_WARNING, mkintf(), option_verbose, zt_pvt::sig, sig2str, strsep(), and VERBOSE_PREFIX_3.
Referenced by process_zap().
11821 { 11822 char *c, *chan; 11823 int x, start, finish; 11824 struct zt_pvt *tmp; 11825 #ifdef HAVE_PRI 11826 struct zt_pri *pri; 11827 int trunkgroup, y; 11828 #endif 11829 11830 if ((reload == 0) && (conf->chan.sig < 0)) { 11831 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 11832 return -1; 11833 } 11834 11835 c = ast_strdupa(value); 11836 11837 #ifdef HAVE_PRI 11838 pri = NULL; 11839 if (iscrv) { 11840 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 11841 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 11842 return -1; 11843 } 11844 if (trunkgroup < 1) { 11845 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 11846 return -1; 11847 } 11848 c += y; 11849 for (y = 0; y < NUM_SPANS; y++) { 11850 if (pris[y].trunkgroup == trunkgroup) { 11851 pri = pris + y; 11852 break; 11853 } 11854 } 11855 if (!pri) { 11856 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 11857 return -1; 11858 } 11859 } 11860 #endif 11861 11862 while ((chan = strsep(&c, ","))) { 11863 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 11864 /* Range */ 11865 } else if (sscanf(chan, "%d", &start)) { 11866 /* Just one */ 11867 finish = start; 11868 } else if (!strcasecmp(chan, "pseudo")) { 11869 finish = start = CHAN_PSEUDO; 11870 if (found_pseudo) 11871 *found_pseudo = 1; 11872 } else { 11873 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 11874 return -1; 11875 } 11876 if (finish < start) { 11877 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 11878 x = finish; 11879 finish = start; 11880 start = x; 11881 } 11882 11883 for (x = start; x <= finish; x++) { 11884 #ifdef HAVE_PRI 11885 tmp = mkintf(x, conf, pri, reload); 11886 #else 11887 tmp = mkintf(x, conf, NULL, reload); 11888 #endif 11889 11890 if (tmp) { 11891 if (option_verbose > 2) { 11892 #ifdef HAVE_PRI 11893 if (pri) 11894 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 11895 else 11896 #endif 11897 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 11898 } 11899 } else { 11900 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 11901 (reload == 1) ? "reconfigure" : "register", value); 11902 return -1; 11903 } 11904 } 11905 } 11906 11907 return 0; 11908 }
static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1647 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().
01648 { 01649 int res; 01650 01651 /* Bump receive gain by 5.0db */ 01652 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01653 if (res) { 01654 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01655 return -1; 01656 } 01657 01658 return 0; 01659 }
Definition at line 7976 of file chan_zap.c.
References ast_log(), ast_malloc, ast_mutex_init(), zt_pvt::destroy, destroy_zt_pvt(), errno, iflist, zt_pvt::lock, LOG_ERROR, LOG_WARNING, oh323_pvt::next, zt_pvt::next, zt_pvt::prev, SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_open().
Referenced by zt_request().
07977 { 07978 struct zt_pvt *p; 07979 ZT_BUFFERINFO bi; 07980 int res; 07981 07982 if ((p = ast_malloc(sizeof(*p)))) { 07983 memcpy(p, src, sizeof(struct zt_pvt)); 07984 ast_mutex_init(&p->lock); 07985 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07986 /* Allocate a zapata structure */ 07987 if (p->subs[SUB_REAL].zfd < 0) { 07988 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07989 destroy_zt_pvt(&p); 07990 return NULL; 07991 } 07992 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07993 if (!res) { 07994 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07995 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07996 bi.numbufs = numbufs; 07997 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07998 if (res < 0) { 07999 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 08000 } 08001 } else 08002 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 08003 } 08004 p->destroy = 1; 08005 p->next = iflist; 08006 p->prev = NULL; 08007 iflist = p; 08008 if (iflist->next) 08009 iflist->next->prev = p; 08010 return p; 08011 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3726 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, LOG_WARNING, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_subchannel::zfd.
Referenced by zt_handle_event().
03727 { 03728 ZT_CONFINFO ci; 03729 /* Fine if we already have a master, etc */ 03730 if (p->master || (p->confno > -1)) 03731 return 0; 03732 memset(&ci, 0, sizeof(ci)); 03733 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03734 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03735 return 0; 03736 } 03737 /* If we have no master and don't have a confno, then 03738 if we're in a conference, it's probably a MeetMe room or 03739 some such, so don't let us 3-way out! */ 03740 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03741 if (option_verbose > 2) 03742 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03743 return 1; 03744 } 03745 return 0; 03746 }
static int conf_add | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 1283 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().
01284 { 01285 /* If the conference already exists, and we're already in it 01286 don't bother doing anything */ 01287 ZT_CONFINFO zi; 01288 01289 memset(&zi, 0, sizeof(zi)); 01290 zi.chan = 0; 01291 01292 if (slavechannel > 0) { 01293 /* If we have only one slave, do a digital mon */ 01294 zi.confmode = ZT_CONF_DIGITALMON; 01295 zi.confno = slavechannel; 01296 } else { 01297 if (!index) { 01298 /* Real-side and pseudo-side both participate in conference */ 01299 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01300 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01301 } else 01302 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01303 zi.confno = p->confno; 01304 } 01305 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01306 return 0; 01307 if (c->zfd < 0) 01308 return 0; 01309 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01310 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01311 return -1; 01312 } 01313 if (slavechannel < 1) { 01314 p->confno = zi.confno; 01315 } 01316 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01317 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01318 return 0; 01319 }
static int conf_del | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 1332 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().
01333 { 01334 ZT_CONFINFO zi; 01335 if (/* Can't delete if there's no zfd */ 01336 (c->zfd < 0) || 01337 /* Don't delete from the conference if it's not our conference */ 01338 !isourconf(p, c) 01339 /* Don't delete if we don't think it's conferenced at all (implied) */ 01340 ) return 0; 01341 memset(&zi, 0, sizeof(zi)); 01342 zi.chan = 0; 01343 zi.confno = 0; 01344 zi.confmode = 0; 01345 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01346 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01347 return -1; 01348 } 01349 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01350 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01351 return 0; 01352 }
Definition at line 2324 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().
02325 { 02326 int owned = 0; 02327 int i = 0; 02328 02329 if (!now) { 02330 if (cur->owner) { 02331 owned = 1; 02332 } 02333 02334 for (i = 0; i < 3; i++) { 02335 if (cur->subs[i].owner) { 02336 owned = 1; 02337 } 02338 } 02339 if (!owned) { 02340 if (prev) { 02341 prev->next = cur->next; 02342 if (prev->next) 02343 prev->next->prev = prev; 02344 else 02345 ifend = prev; 02346 } else { 02347 iflist = cur->next; 02348 if (iflist) 02349 iflist->prev = NULL; 02350 else 02351 ifend = NULL; 02352 } 02353 if (cur->subs[SUB_REAL].zfd > -1) { 02354 zt_close(cur->subs[SUB_REAL].zfd); 02355 } 02356 destroy_zt_pvt(&cur); 02357 } 02358 } else { 02359 if (prev) { 02360 prev->next = cur->next; 02361 if (prev->next) 02362 prev->next->prev = prev; 02363 else 02364 ifend = prev; 02365 } else { 02366 iflist = cur->next; 02367 if (iflist) 02368 iflist->prev = NULL; 02369 else 02370 ifend = NULL; 02371 } 02372 if (cur->subs[SUB_REAL].zfd > -1) { 02373 zt_close(cur->subs[SUB_REAL].zfd); 02374 } 02375 destroy_zt_pvt(&cur); 02376 } 02377 return 0; 02378 }
static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2309 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().
02310 { 02311 struct zt_pvt *p = *pvt; 02312 /* Remove channel from the list */ 02313 if (p->prev) 02314 p->prev->next = p->next; 02315 if (p->next) 02316 p->next->prev = p->prev; 02317 if (p->use_smdi) 02318 ast_smdi_interface_unref(p->smdi_iface); 02319 ast_mutex_destroy(&p->lock); 02320 free(p); 02321 *pvt = NULL; 02322 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 1043 of file chan_zap.c.
Referenced by zt_digit_begin().
01044 { 01045 if (isdigit(digit)) 01046 return ZT_TONE_DTMF_BASE + (digit - '0'); 01047 else if (digit >= 'A' && digit <= 'D') 01048 return ZT_TONE_DTMF_A + (digit - 'A'); 01049 else if (digit >= 'a' && digit <= 'd') 01050 return ZT_TONE_DTMF_A + (digit - 'a'); 01051 else if (digit == '*') 01052 return ZT_TONE_DTMF_s; 01053 else if (digit == '#') 01054 return ZT_TONE_DTMF_p; 01055 else 01056 return -1; 01057 }
static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3255 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(), and zt_call().
03256 { 03257 #ifdef ZT_TONEDETECT 03258 int val; 03259 #endif 03260 03261 p->ignoredtmf = 1; 03262 03263 #ifdef ZT_TONEDETECT 03264 val = 0; 03265 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03266 #endif 03267 if (!p->hardwaredtmf && p->dsp) { 03268 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03269 ast_dsp_set_features(p->dsp, p->dsp_features); 03270 } 03271 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 7009 of file chan_zap.c.
References ast_app_has_voicemail(), ast_calloc, ast_fdisset(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), zt_pvt::channel, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, errno, event2str(), pollfd::events, pollfd::fd, free, handle_init_event(), iflist, last, LOG_DEBUG, LOG_WARNING, zt_pvt::mailbox, MAX_CALLERID_SIZE, zt_pvt::msgstate, zt_pvt::next, zt_pvt::onhooktime, option_debug, zt_subchannel::owner, zt_pvt::owner, poll(), POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, vmwi_generate(), zt_subchannel::zfd, and zt_get_event().
07010 { 07011 int count, res, res2, spoint, pollres=0; 07012 struct zt_pvt *i; 07013 struct zt_pvt *last = NULL; 07014 time_t thispass = 0, lastpass = 0; 07015 int found; 07016 char buf[1024]; 07017 struct pollfd *pfds=NULL; 07018 int lastalloc = -1; 07019 /* This thread monitors all the frame relay interfaces which are not yet in use 07020 (and thus do not have a separate thread) indefinitely */ 07021 /* From here on out, we die whenever asked */ 07022 #if 0 07023 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 07024 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 07025 return NULL; 07026 } 07027 ast_log(LOG_DEBUG, "Monitor starting...\n"); 07028 #endif 07029 for (;;) { 07030 /* Lock the interface list */ 07031 ast_mutex_lock(&iflock); 07032 if (!pfds || (lastalloc != ifcount)) { 07033 if (pfds) { 07034 free(pfds); 07035 pfds = NULL; 07036 } 07037 if (ifcount) { 07038 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 07039 ast_mutex_unlock(&iflock); 07040 return NULL; 07041 } 07042 } 07043 lastalloc = ifcount; 07044 } 07045 /* Build the stuff we're going to poll on, that is the socket of every 07046 zt_pvt that does not have an associated owner channel */ 07047 count = 0; 07048 i = iflist; 07049 while (i) { 07050 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 07051 if (!i->owner && !i->subs[SUB_REAL].owner) { 07052 /* This needs to be watched, as it lacks an owner */ 07053 pfds[count].fd = i->subs[SUB_REAL].zfd; 07054 pfds[count].events = POLLPRI; 07055 pfds[count].revents = 0; 07056 /* Message waiting or r2 channels also get watched for reading */ 07057 if (i->cidspill) 07058 pfds[count].events |= POLLIN; 07059 count++; 07060 } 07061 } 07062 i = i->next; 07063 } 07064 /* Okay, now that we know what to do, release the interface lock */ 07065 ast_mutex_unlock(&iflock); 07066 07067 pthread_testcancel(); 07068 /* Wait at least a second for something to happen */ 07069 res = poll(pfds, count, 1000); 07070 pthread_testcancel(); 07071 /* Okay, poll has finished. Let's see what happened. */ 07072 if (res < 0) { 07073 if ((errno != EAGAIN) && (errno != EINTR)) 07074 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 07075 continue; 07076 } 07077 /* Alright, lock the interface list again, and let's look and see what has 07078 happened */ 07079 ast_mutex_lock(&iflock); 07080 found = 0; 07081 spoint = 0; 07082 lastpass = thispass; 07083 thispass = time(NULL); 07084 i = iflist; 07085 while (i) { 07086 if (thispass != lastpass) { 07087 if (!found && ((i == last) || ((i == iflist) && !last))) { 07088 last = i; 07089 if (last) { 07090 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 07091 (last->sig & __ZT_SIG_FXO)) { 07092 res = ast_app_has_voicemail(last->mailbox, NULL); 07093 if (last->msgstate != res) { 07094 int x; 07095 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 07096 x = ZT_FLUSH_BOTH; 07097 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 07098 if (res2) 07099 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 07100 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 07101 /* Turn on on hook transfer for 4 seconds */ 07102 x = 4000; 07103 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 07104 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 07105 last->cidpos = 0; 07106 last->msgstate = res; 07107 last->onhooktime = thispass; 07108 } 07109 found ++; 07110 } 07111 } 07112 last = last->next; 07113 } 07114 } 07115 } 07116 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 07117 if (i->radio && !i->owner) 07118 { 07119 res = zt_get_event(i->subs[SUB_REAL].zfd); 07120 if (res) 07121 { 07122 if (option_debug) 07123 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 07124 /* Don't hold iflock while handling init events */ 07125 ast_mutex_unlock(&iflock); 07126 handle_init_event(i, res); 07127 ast_mutex_lock(&iflock); 07128 } 07129 i = i->next; 07130 continue; 07131 } 07132 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 07133 if (pollres & POLLIN) { 07134 if (i->owner || i->subs[SUB_REAL].owner) { 07135 #ifdef HAVE_PRI 07136 if (!i->pri) 07137 #endif 07138 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 07139 i = i->next; 07140 continue; 07141 } 07142 if (!i->cidspill) { 07143 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 07144 i = i->next; 07145 continue; 07146 } 07147 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 07148 if (res > 0) { 07149 /* We read some number of bytes. Write an equal amount of data */ 07150 if (res > i->cidlen - i->cidpos) 07151 res = i->cidlen - i->cidpos; 07152 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 07153 if (res2 > 0) { 07154 i->cidpos += res2; 07155 if (i->cidpos >= i->cidlen) { 07156 free(i->cidspill); 07157 i->cidspill = 0; 07158 i->cidpos = 0; 07159 i->cidlen = 0; 07160 } 07161 } else { 07162 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 07163 i->msgstate = -1; 07164 } 07165 } else { 07166 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 07167 } 07168 } 07169 if (pollres & POLLPRI) { 07170 if (i->owner || i->subs[SUB_REAL].owner) { 07171 #ifdef HAVE_PRI 07172 if (!i->pri) 07173 #endif 07174 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 07175 i = i->next; 07176 continue; 07177 } 07178 res = zt_get_event(i->subs[SUB_REAL].zfd); 07179 if (option_debug) 07180 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 07181 /* Don't hold iflock while handling init events */ 07182 ast_mutex_unlock(&iflock); 07183 handle_init_event(i, res); 07184 ast_mutex_lock(&iflock); 07185 } 07186 } 07187 i=i->next; 07188 } 07189 ast_mutex_unlock(&iflock); 07190 } 07191 /* Never reached */ 07192 return NULL; 07193 07194 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3273 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_answer(), and zt_bridge().
03274 { 03275 #ifdef ZT_TONEDETECT 03276 int val; 03277 #endif 03278 03279 if (p->channel == CHAN_PSEUDO) 03280 return; 03281 03282 p->ignoredtmf = 0; 03283 03284 #ifdef ZT_TONEDETECT 03285 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03286 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03287 #endif 03288 if (!p->hardwaredtmf && p->dsp) { 03289 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03290 ast_dsp_set_features(p->dsp, p->dsp_features); 03291 } 03292 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1200 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
01201 { 01202 static char buf[256]; 01203 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01204 return events[event]; 01205 sprintf(buf, "Event %d", event); /* safe */ 01206 return buf; 01207 }
static void fill_rxgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1571 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01572 { 01573 int j; 01574 int k; 01575 float linear_gain = pow(10.0, gain / 20.0); 01576 01577 switch (law) { 01578 case ZT_LAW_ALAW: 01579 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01580 if (gain) { 01581 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01582 if (k > 32767) k = 32767; 01583 if (k < -32767) k = -32767; 01584 g->rxgain[j] = AST_LIN2A(k); 01585 } else { 01586 g->rxgain[j] = j; 01587 } 01588 } 01589 break; 01590 case ZT_LAW_MULAW: 01591 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01592 if (gain) { 01593 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01594 if (k > 32767) k = 32767; 01595 if (k < -32767) k = -32767; 01596 g->rxgain[j] = AST_LIN2MU(k); 01597 } else { 01598 g->rxgain[j] = j; 01599 } 01600 } 01601 break; 01602 } 01603 }
static void fill_txgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1537 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01538 { 01539 int j; 01540 int k; 01541 float linear_gain = pow(10.0, gain / 20.0); 01542 01543 switch (law) { 01544 case ZT_LAW_ALAW: 01545 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01546 if (gain) { 01547 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01548 if (k > 32767) k = 32767; 01549 if (k < -32767) k = -32767; 01550 g->txgain[j] = AST_LIN2A(k); 01551 } else { 01552 g->txgain[j] = j; 01553 } 01554 } 01555 break; 01556 case ZT_LAW_MULAW: 01557 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01558 if (gain) { 01559 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01560 if (k > 32767) k = 32767; 01561 if (k < -32767) k = -32767; 01562 g->txgain[j] = AST_LIN2MU(k); 01563 } else { 01564 g->txgain[j] = j; 01565 } 01566 } 01567 break; 01568 } 01569 }
static struct zt_pvt* find_channel | ( | int | channel | ) | [static, read] |
Definition at line 11566 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().
11567 { 11568 struct zt_pvt *p = iflist; 11569 while (p) { 11570 if (p->channel == channel) { 11571 break; 11572 } 11573 p = p->next; 11574 } 11575 return p; 11576 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3748 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::span, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03749 { 03750 int res; 03751 ZT_SPANINFO zi; 03752 memset(&zi, 0, sizeof(zi)); 03753 zi.spanno = p->span; 03754 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03755 if (res < 0) { 03756 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03757 return 0; 03758 } 03759 return zi.alarms; 03760 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6761 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, LOG_WARNING, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_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().
Referenced by do_monitor().
06762 { 06763 int res; 06764 pthread_t threadid; 06765 pthread_attr_t attr; 06766 struct ast_channel *chan; 06767 pthread_attr_init(&attr); 06768 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06769 /* Handle an event on a given channel for the monitor thread. */ 06770 switch (event) { 06771 case ZT_EVENT_NONE: 06772 case ZT_EVENT_BITSCHANGED: 06773 break; 06774 case ZT_EVENT_WINKFLASH: 06775 case ZT_EVENT_RINGOFFHOOK: 06776 if (i->inalarm) break; 06777 if (i->radio) break; 06778 /* Got a ring/answer. What kind of channel are we? */ 06779 switch (i->sig) { 06780 case SIG_FXOLS: 06781 case SIG_FXOGS: 06782 case SIG_FXOKS: 06783 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06784 if (res && (errno == EBUSY)) 06785 break; 06786 if (i->cidspill) { 06787 /* Cancel VMWI spill */ 06788 free(i->cidspill); 06789 i->cidspill = NULL; 06790 } 06791 if (i->immediate) { 06792 zt_enable_ec(i); 06793 /* The channel is immediately up. Start right away */ 06794 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06795 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06796 if (!chan) { 06797 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06798 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06799 if (res < 0) 06800 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06801 } 06802 } else { 06803 /* Check for callerid, digits, etc */ 06804 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06805 if (chan) { 06806 if (has_voicemail(i)) 06807 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06808 else 06809 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06810 if (res < 0) 06811 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 06812 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06813 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06814 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06815 if (res < 0) 06816 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06817 ast_hangup(chan); 06818 } 06819 } else 06820 ast_log(LOG_WARNING, "Unable to create channel\n"); 06821 } 06822 break; 06823 case SIG_FXSLS: 06824 case SIG_FXSGS: 06825 case SIG_FXSKS: 06826 i->ringt = i->ringt_base; 06827 /* Fall through */ 06828 case SIG_EMWINK: 06829 case SIG_FEATD: 06830 case SIG_FEATDMF: 06831 case SIG_FEATDMF_TA: 06832 case SIG_E911: 06833 case SIG_FGC_CAMA: 06834 case SIG_FGC_CAMAMF: 06835 case SIG_FEATB: 06836 case SIG_EM: 06837 case SIG_EM_E1: 06838 case SIG_SFWINK: 06839 case SIG_SF_FEATD: 06840 case SIG_SF_FEATDMF: 06841 case SIG_SF_FEATB: 06842 case SIG_SF: 06843 /* Check for callerid, digits, etc */ 06844 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06845 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06846 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06847 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06848 if (res < 0) 06849 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06850 ast_hangup(chan); 06851 } else if (!chan) { 06852 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06853 } 06854 break; 06855 default: 06856 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06857 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06858 if (res < 0) 06859 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06860 return -1; 06861 } 06862 break; 06863 case ZT_EVENT_NOALARM: 06864 i->inalarm = 0; 06865 if (!i->unknown_alarm) { 06866 #ifdef HAVE_PRI 06867 if (i->pri) { 06868 if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { 06869 /* dont annoy BRI TE mode users with layer2layer alarms */ 06870 } else { 06871 #endif 06872 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06873 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06874 "Channel: %d\r\n", i->channel); 06875 #ifdef HAVE_PRI 06876 } 06877 } 06878 #endif 06879 06880 } else { 06881 i->unknown_alarm = 0; 06882 } 06883 break; 06884 case ZT_EVENT_ALARM: 06885 i->inalarm = 1; 06886 res = get_alarms(i); 06887 do { 06888 #ifdef HAVE_PRI 06889 if (i->pri) { 06890 if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { 06891 /* dont annoy BRI TE mode users with layer2layer alarms */ 06892 } else { 06893 #endif 06894 const char *alarm_str = alarm2str(res); 06895 06896 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 06897 * doesn't know what to do with it. Don't confuse users with log messages. */ 06898 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 06899 i->unknown_alarm = 1; 06900 break; 06901 } else { 06902 i->unknown_alarm = 0; 06903 } 06904 06905 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str); 06906 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06907 "Alarm: %s\r\n" 06908 "Channel: %d\r\n", 06909 alarm_str, i->channel); 06910 #ifdef HAVE_PRI 06911 } 06912 } 06913 #endif 06914 } while (0); 06915 /* fall thru intentionally */ 06916 case ZT_EVENT_ONHOOK: 06917 if (i->radio) 06918 break; 06919 /* Back on hook. Hang up. */ 06920 switch (i->sig) { 06921 case SIG_FXOLS: 06922 case SIG_FXOGS: 06923 case SIG_FEATD: 06924 case SIG_FEATDMF: 06925 case SIG_FEATDMF_TA: 06926 case SIG_E911: 06927 case SIG_FGC_CAMA: 06928 case SIG_FGC_CAMAMF: 06929 case SIG_FEATB: 06930 case SIG_EM: 06931 case SIG_EM_E1: 06932 case SIG_EMWINK: 06933 case SIG_SF_FEATD: 06934 case SIG_SF_FEATDMF: 06935 case SIG_SF_FEATB: 06936 case SIG_SF: 06937 case SIG_SFWINK: 06938 case SIG_FXSLS: 06939 case SIG_FXSGS: 06940 case SIG_FXSKS: 06941 case SIG_GR303FXSKS: 06942 zt_disable_ec(i); 06943 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06944 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06945 break; 06946 case SIG_GR303FXOKS: 06947 case SIG_FXOKS: 06948 zt_disable_ec(i); 06949 /* Diddle the battery for the zhone */ 06950 #ifdef ZHONE_HACK 06951 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06952 usleep(1); 06953 #endif 06954 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06955 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06956 break; 06957 case SIG_PRI: 06958 if (event != ZT_EVENT_ALARM) { 06959 zt_disable_ec(i); 06960 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06961 } 06962 break; 06963 default: 06964 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06965 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06966 return -1; 06967 } 06968 break; 06969 case ZT_EVENT_POLARITY: 06970 switch (i->sig) { 06971 case SIG_FXSLS: 06972 case SIG_FXSKS: 06973 case SIG_FXSGS: 06974 /* We have already got a PR before the channel was 06975 created, but it wasn't handled. We need polarity 06976 to be REV for remote hangup detection to work. 06977 At least in Spain */ 06978 if (i->hanguponpolarityswitch) 06979 i->polarity = POLARITY_REV; 06980 06981 if (i->cid_start == CID_START_POLARITY) { 06982 i->polarity = POLARITY_REV; 06983 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06984 "CID detection on channel %d\n", 06985 i->channel); 06986 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06987 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06988 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06989 } 06990 } 06991 break; 06992 default: 06993 ast_log(LOG_WARNING, "handle_init_event detected " 06994 "polarity reversal on non-FXO (SIG_FXS) " 06995 "interface %d\n", i->channel); 06996 } 06997 break; 06998 case ZT_EVENT_REMOVED: /* destroy channel */ 06999 ast_log(LOG_NOTICE, 07000 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 07001 i->channel); 07002 zap_destroy_channel_bynum(i->channel); 07003 break; 07004 } 07005 pthread_attr_destroy(&attr); 07006 return 0; 07007 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11410 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
11411 { 11412 int i, j; 11413 for (i = 0; i < num_cadence; i++) { 11414 char output[1024]; 11415 char tmp[16], tmp2[64]; 11416 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 11417 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 11418 11419 for (j = 0; j < 16; j++) { 11420 if (cadences[i].ringcadence[j] == 0) 11421 break; 11422 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 11423 if (cidrings[i] * 2 - 1 == j) 11424 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 11425 else 11426 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 11427 if (j != 0) 11428 strncat(output, ",", sizeof(output) - strlen(output) - 1); 11429 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 11430 } 11431 ast_cli(fd,"%s\n",output); 11432 } 11433 return 0; 11434 }
static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1768 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01769 { 01770 01771 return ast_app_has_voicemail(p->mailbox, NULL); 01772 }
static int isourconf | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c | |||
) | [static] |
Definition at line 1321 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01322 { 01323 /* If they're listening to our channel, they're ours */ 01324 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01325 return 1; 01326 /* If they're a talker on our (allocated) conference, they're ours */ 01327 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01328 return 1; 01329 return 0; 01330 }
Definition at line 1354 of file chan_zap.c.
References zt_subchannel::inthreeway, zt_pvt::law, MAX_SLAVES, zt_pvt::slaves, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by update_conf().
01355 { 01356 int x; 01357 int useslavenative; 01358 struct zt_pvt *slave = NULL; 01359 /* Start out optimistic */ 01360 useslavenative = 1; 01361 /* Update conference state in a stateless fashion */ 01362 for (x = 0; x < 3; x++) { 01363 /* Any three-way calling makes slave native mode *definitely* out 01364 of the question */ 01365 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01366 useslavenative = 0; 01367 } 01368 /* If we don't have any 3-way calls, check to see if we have 01369 precisely one slave */ 01370 if (useslavenative) { 01371 for (x = 0; x < MAX_SLAVES; x++) { 01372 if (p->slaves[x]) { 01373 if (slave) { 01374 /* Whoops already have a slave! No 01375 slave native and stop right away */ 01376 slave = NULL; 01377 useslavenative = 0; 01378 break; 01379 } else { 01380 /* We have one slave so far */ 01381 slave = p->slaves[x]; 01382 } 01383 } 01384 } 01385 } 01386 /* If no slave, slave native definitely out */ 01387 if (!slave) 01388 useslavenative = 0; 01389 else if (slave->law != p->law) { 01390 useslavenative = 0; 01391 slave = NULL; 01392 } 01393 if (out) 01394 *out = slave; 01395 return useslavenative; 01396 }
static int load_module | ( | void | ) | [static] |
Definition at line 12758 of file chan_zap.c.
References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), app_zapEC(), ast_channel_register(), ast_cli_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, and setup_zap().
12759 { 12760 int res; 12761 12762 #ifdef HAVE_PRI 12763 int y,i; 12764 memset(pris, 0, sizeof(pris)); 12765 for (y = 0; y < NUM_SPANS; y++) { 12766 ast_mutex_init(&pris[y].lock); 12767 pris[y].offset = -1; 12768 pris[y].master = AST_PTHREADT_NULL; 12769 for (i = 0; i < NUM_DCHANS; i++) 12770 pris[y].fds[i] = -1; 12771 } 12772 pri_set_error(zt_pri_error); 12773 pri_set_message(zt_pri_message); 12774 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 12775 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 12776 #endif 12777 #ifdef HAVE_GSMAT 12778 gsm_set_error(zt_gsm_error); 12779 gsm_set_message(zt_gsm_message); 12780 #endif 12781 res = setup_zap(0); 12782 /* Make sure we can register our Zap channel type */ 12783 if (res) 12784 return AST_MODULE_LOAD_DECLINE; 12785 if (ast_channel_register(&zap_tech)) { 12786 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 12787 __unload_module(); 12788 return -1; 12789 } 12790 #ifdef HAVE_PRI 12791 ast_string_field_init(&inuse, 16); 12792 ast_string_field_set(&inuse, name, "GR-303InUse"); 12793 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 12794 ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc); 12795 ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc); 12796 #endif 12797 ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc); 12798 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 12799 #ifdef HAVE_GSMAT 12800 ast_cli_register(&gsm_send_sms); 12801 ast_cli_register(&gsm_send_pdu); 12802 ast_cli_register(&gsm_show_status); 12803 ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); 12804 #endif 12805 12806 memset(round_robin, 0, sizeof(round_robin)); 12807 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 12808 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 12809 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 12810 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 12811 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 12812 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 12813 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 12814 12815 return res; 12816 }
static struct zt_pvt* mkintf | ( | int | channel, | |
const struct zt_chan_conf * | conf, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static, read] |
Definition at line 7347 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_calloc, ast_dsp_digitmode(), ast_log(), ast_mutex_init(), ast_pthread_create, ast_smdi_interface_find(), ast_strlen_zero(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, CHAN_PSEUDO, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_SMDI, zt_pvt::cid_signalling, zt_pvt::cid_start, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, DCHAN_AVAILABLE, zt_pvt::defcontext, zt_pvt::destroy, destroy_zt_pvt(), drings, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, errno, zt_pvt::exten, zt_pvt::firstradio, zt_pvt::group, gsm_new(), zt_pvt::hanguponpolarityswitch, zt_pvt::hidecallerid, iflist, zt_pvt::immediate, zt_pvt::inalarm, zt_pvt::language, zt_pvt::law, zt_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, zt_pvt::mailbox, zt_pvt::master, MAX_CHANNELS, zt_pvt::mohinterpret, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::outsigmod, zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::prev, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pritransfer, zt_pvt::propconfno, zt_pvt::pulse, zt_pvt::radio, zt_pvt::restrictcid, zt_pvt::ringt_base, zt_pvt::rxgain, zt_pvt::sendcalleridafter, set_actual_gain(), 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_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, zt_chan_conf::smdi_port, zt_pvt::span, zt_pvt::stripmsd, SUB_REAL, zt_pvt::subs, zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, update_conf(), zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_close(), zt_open(), and zt_set_hook().
Referenced by build_channels(), and process_zap().
07348 { 07349 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07350 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07351 char fn[80]; 07352 #if 1 07353 struct zt_bufferinfo bi; 07354 #endif 07355 struct zt_spaninfo si; 07356 int res; 07357 int span=0; 07358 int here = 0; 07359 int x; 07360 struct zt_pvt **wlist; 07361 struct zt_pvt **wend; 07362 ZT_PARAMS p; 07363 07364 wlist = &iflist; 07365 wend = &ifend; 07366 07367 #ifdef HAVE_PRI 07368 if (pri) { 07369 wlist = &pri->crvs; 07370 wend = &pri->crvend; 07371 } 07372 #endif 07373 07374 tmp2 = *wlist; 07375 prev = NULL; 07376 07377 while (tmp2) { 07378 if (!tmp2->destroy) { 07379 if (tmp2->channel == channel) { 07380 tmp = tmp2; 07381 here = 1; 07382 break; 07383 } 07384 if (tmp2->channel > channel) { 07385 break; 07386 } 07387 } 07388 prev = tmp2; 07389 tmp2 = tmp2->next; 07390 } 07391 07392 if (!here && !reloading) { 07393 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07394 destroy_zt_pvt(&tmp); 07395 return NULL; 07396 } 07397 ast_mutex_init(&tmp->lock); 07398 ifcount++; 07399 for (x = 0; x < 3; x++) 07400 tmp->subs[x].zfd = -1; 07401 tmp->channel = channel; 07402 } 07403 07404 if (tmp) { 07405 int chan_sig = conf->chan.sig; 07406 if (!here) { 07407 if ((channel != CHAN_PSEUDO) && !pri) { 07408 snprintf(fn, sizeof(fn), "%d", channel); 07409 /* Open non-blocking */ 07410 if (!here) 07411 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07412 /* Allocate a zapata structure */ 07413 if (tmp->subs[SUB_REAL].zfd < 0) { 07414 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); 07415 destroy_zt_pvt(&tmp); 07416 return NULL; 07417 } 07418 memset(&p, 0, sizeof(p)); 07419 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07420 if (res < 0) { 07421 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07422 destroy_zt_pvt(&tmp); 07423 return NULL; 07424 } 07425 if (p.sigtype != (conf->chan.sig & 0x3ffff)) { 07426 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)); 07427 destroy_zt_pvt(&tmp); 07428 return NULL; 07429 } 07430 tmp->law = p.curlaw; 07431 tmp->span = p.spanno; 07432 span = p.spanno - 1; 07433 } else { 07434 if (channel == CHAN_PSEUDO) 07435 chan_sig = 0; 07436 else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) { 07437 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07438 return NULL; 07439 } 07440 } 07441 #ifdef HAVE_PRI 07442 if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) { 07443 int offset; 07444 int myswitchtype; 07445 int matchesdchan; 07446 int x,y; 07447 offset = 0; 07448 if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07449 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07450 destroy_zt_pvt(&tmp); 07451 return NULL; 07452 } 07453 if (span >= NUM_SPANS) { 07454 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07455 destroy_zt_pvt(&tmp); 07456 return NULL; 07457 } else { 07458 si.spanno = 0; 07459 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07460 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07461 destroy_zt_pvt(&tmp); 07462 return NULL; 07463 } 07464 /* Store the logical span first based upon the real span */ 07465 tmp->logicalspan = pris[span].prilogicalspan; 07466 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07467 if (span < 0) { 07468 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07469 destroy_zt_pvt(&tmp); 07470 return NULL; 07471 } 07472 if (chan_sig == SIG_PRI) 07473 myswitchtype = conf->pri.switchtype; 07474 else 07475 myswitchtype = PRI_SWITCH_GR303_TMC; 07476 /* Make sure this isn't a d-channel */ 07477 matchesdchan=0; 07478 for (x = 0; x < NUM_SPANS; x++) { 07479 for (y = 0; y < NUM_DCHANS; y++) { 07480 if (pris[x].dchannels[y] == tmp->channel) { 07481 matchesdchan = 1; 07482 break; 07483 } 07484 } 07485 } 07486 offset = p.chanpos; 07487 if (!matchesdchan) { 07488 if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) { 07489 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07490 destroy_zt_pvt(&tmp); 07491 return NULL; 07492 } 07493 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07494 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07495 destroy_zt_pvt(&tmp); 07496 return NULL; 07497 } 07498 if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) { 07499 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07500 destroy_zt_pvt(&tmp); 07501 return NULL; 07502 } 07503 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) { 07504 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial); 07505 destroy_zt_pvt(&tmp); 07506 return NULL; 07507 } 07508 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) { 07509 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext); 07510 destroy_zt_pvt(&tmp); 07511 return NULL; 07512 } 07513 if ((pris[span].localdialplan) && (pris[span].localdialplan != conf->pri.localdialplan)) { 07514 ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan)); 07515 destroy_zt_pvt(&tmp); 07516 return NULL; 07517 } 07518 if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) { 07519 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused); 07520 destroy_zt_pvt(&tmp); 07521 return NULL; 07522 } 07523 if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) { 07524 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle); 07525 destroy_zt_pvt(&tmp); 07526 return NULL; 07527 } 07528 if (pris[span].numchans >= MAX_CHANNELS) { 07529 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07530 pris[span].trunkgroup); 07531 destroy_zt_pvt(&tmp); 07532 return NULL; 07533 } 07534 pris[span].nodetype = conf->pri.nodetype; 07535 07536 if (conf->pri.nodetype == BRI_NETWORK_PTMP) { 07537 pris[span].dchanavail[0] = DCHAN_AVAILABLE; 07538 pri_find_dchan(&pris[span]); 07539 } 07540 pris[span].switchtype = myswitchtype; 07541 pris[span].nsf = conf->pri.nsf; 07542 pris[span].dialplan = conf->pri.dialplan; 07543 pris[span].localdialplan = conf->pri.localdialplan; 07544 pris[span].pvts[pris[span].numchans++] = tmp; 07545 pris[span].minunused = conf->pri.minunused; 07546 pris[span].minidle = conf->pri.minidle; 07547 pris[span].overlapdial = conf->pri.overlapdial; 07548 pris[span].usercid = conf->pri.usercid; 07549 pris[span].suspended_calls = NULL; 07550 pris[span].facilityenable = conf->pri.facilityenable; 07551 ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial)); 07552 ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext)); 07553 ast_copy_string(pris[span].nocid, conf->pri.nocid, sizeof(pris[span].nocid)); 07554 ast_copy_string(pris[span].withheldcid, conf->pri.withheldcid, sizeof(pris[span].withheldcid)); 07555 ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07556 ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07557 ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix)); 07558 ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix)); 07559 ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07560 pris[span].resetinterval = conf->pri.resetinterval; 07561 07562 tmp->pri = &pris[span]; 07563 tmp->prioffset = offset; 07564 tmp->call = NULL; 07565 } else { 07566 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07567 destroy_zt_pvt(&tmp); 07568 return NULL; 07569 } 07570 } 07571 } else { 07572 tmp->prioffset = 0; 07573 } 07574 #endif 07575 #ifdef HAVE_GSMAT 07576 if (conf->chan.sig == SIG_GSM) { 07577 struct zt_bufferinfo bi; 07578 ast_mutex_init(&tmp->gsm.lock); 07579 strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1); 07580 strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1); 07581 tmp->gsm.available = 0; 07582 snprintf(fn, sizeof(fn), "%d", channel + 1); 07583 /* Open non-blocking */ 07584 tmp->gsm.fd = zt_open(fn); 07585 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07586 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07587 bi.numbufs = 16; 07588 bi.bufsize = 1024; 07589 if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) { 07590 ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno)); 07591 return NULL; 07592 } 07593 tmp->gsm.pvt = tmp; 07594 tmp->gsm.span = tmp->span; 07595 tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel); 07596 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) { 07597 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno)); 07598 destroy_zt_pvt(&tmp); 07599 return NULL; 07600 } 07601 if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) { 07602 zt_close(tmp->gsm.fd); 07603 } 07604 } 07605 #endif 07606 } else { 07607 chan_sig = tmp->sig; 07608 memset(&p, 0, sizeof(p)); 07609 if (tmp->subs[SUB_REAL].zfd > -1) 07610 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07611 } 07612 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07613 switch (chan_sig) { 07614 case SIG_FXSKS: 07615 case SIG_FXSLS: 07616 case SIG_EM: 07617 case SIG_EM_E1: 07618 case SIG_EMWINK: 07619 case SIG_FEATD: 07620 case SIG_FEATDMF: 07621 case SIG_FEATDMF_TA: 07622 case SIG_FEATB: 07623 case SIG_E911: 07624 case SIG_SF: 07625 case SIG_SFWINK: 07626 case SIG_FGC_CAMA: 07627 case SIG_FGC_CAMAMF: 07628 case SIG_SF_FEATD: 07629 case SIG_SF_FEATDMF: 07630 case SIG_SF_FEATB: 07631 p.starttime = 250; 07632 break; 07633 } 07634 07635 if (tmp->radio) { 07636 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07637 p.channo = channel; 07638 p.rxwinktime = 1; 07639 p.rxflashtime = 1; 07640 p.starttime = 1; 07641 p.debouncetime = 5; 07642 } 07643 if (!tmp->radio) { 07644 p.channo = channel; 07645 /* Override timing settings based on config file */ 07646 if (conf->timing.prewinktime >= 0) 07647 p.prewinktime = conf->timing.prewinktime; 07648 if (conf->timing.preflashtime >= 0) 07649 p.preflashtime = conf->timing.preflashtime; 07650 if (conf->timing.winktime >= 0) 07651 p.winktime = conf->timing.winktime; 07652 if (conf->timing.flashtime >= 0) 07653 p.flashtime = conf->timing.flashtime; 07654 if (conf->timing.starttime >= 0) 07655 p.starttime = conf->timing.starttime; 07656 if (conf->timing.rxwinktime >= 0) 07657 p.rxwinktime = conf->timing.rxwinktime; 07658 if (conf->timing.rxflashtime >= 0) 07659 p.rxflashtime = conf->timing.rxflashtime; 07660 if (conf->timing.debouncetime >= 0) 07661 p.debouncetime = conf->timing.debouncetime; 07662 } 07663 07664 /* dont set parms on a pseudo-channel (or CRV) */ 07665 if (tmp->subs[SUB_REAL].zfd >= 0) 07666 { 07667 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07668 if (res < 0) { 07669 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07670 destroy_zt_pvt(&tmp); 07671 return NULL; 07672 } 07673 } 07674 #if 1 07675 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07676 memset(&bi, 0, sizeof(bi)); 07677 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07678 if (!res) { 07679 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07680 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07681 bi.numbufs = numbufs; 07682 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07683 if (res < 0) { 07684 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07685 } 07686 } else 07687 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07688 } 07689 #endif 07690 tmp->immediate = conf->chan.immediate; 07691 tmp->transfertobusy = conf->chan.transfertobusy; 07692 tmp->sig = chan_sig; 07693 tmp->outsigmod = conf->chan.outsigmod; 07694 tmp->ringt_base = ringt_base; 07695 tmp->firstradio = 0; 07696 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 07697 tmp->permcallwaiting = conf->chan.callwaiting; 07698 else 07699 tmp->permcallwaiting = 0; 07700 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07701 tmp->destroy = 0; 07702 tmp->drings = drings; 07703 tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection; 07704 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 07705 tmp->threewaycalling = conf->chan.threewaycalling; 07706 tmp->adsi = conf->chan.adsi; 07707 tmp->use_smdi = conf->chan.use_smdi; 07708 tmp->permhidecallerid = conf->chan.hidecallerid; 07709 tmp->callreturn = conf->chan.callreturn; 07710 tmp->echocancel = conf->chan.echocancel; 07711 tmp->echotraining = conf->chan.echotraining; 07712 tmp->pulse = conf->chan.pulse; 07713 if (tmp->echocancel) 07714 tmp->echocanbridged = conf->chan.echocanbridged; 07715 else { 07716 if (conf->chan.echocanbridged) 07717 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 07718 tmp->echocanbridged = 0; 07719 } 07720 tmp->busydetect = conf->chan.busydetect; 07721 tmp->busycount = conf->chan.busycount; 07722 tmp->busy_tonelength = conf->chan.busy_tonelength; 07723 tmp->busy_quietlength = conf->chan.busy_quietlength; 07724 tmp->callprogress = conf->chan.callprogress; 07725 tmp->cancallforward = conf->chan.cancallforward; 07726 tmp->dtmfrelax = conf->chan.dtmfrelax; 07727 tmp->callwaiting = tmp->permcallwaiting; 07728 tmp->hidecallerid = tmp->permhidecallerid; 07729 tmp->channel = channel; 07730 tmp->stripmsd = conf->chan.stripmsd; 07731 tmp->use_callerid = conf->chan.use_callerid; 07732 tmp->cid_signalling = conf->chan.cid_signalling; 07733 tmp->cid_start = conf->chan.cid_start; 07734 tmp->zaptrcallerid = conf->chan.zaptrcallerid; 07735 tmp->restrictcid = conf->chan.restrictcid; 07736 tmp->use_callingpres = conf->chan.use_callingpres; 07737 tmp->priindication_oob = conf->chan.priindication_oob; 07738 tmp->pritransfer = conf->chan.pritransfer; 07739 tmp->priexclusive = conf->chan.priexclusive; 07740 if (tmp->usedistinctiveringdetection) { 07741 if (!tmp->use_callerid) { 07742 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07743 tmp->use_callerid = 1; 07744 } 07745 } 07746 07747 if (tmp->cid_signalling == CID_SIG_SMDI) { 07748 if (!tmp->use_smdi) { 07749 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07750 tmp->use_smdi = 1; 07751 } 07752 } 07753 if (tmp->use_smdi) { 07754 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 07755 if (!(tmp->smdi_iface)) { 07756 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07757 tmp->use_smdi = 0; 07758 } 07759 } 07760 07761 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 07762 tmp->amaflags = conf->chan.amaflags; 07763 if (!here) { 07764 tmp->confno = -1; 07765 tmp->propconfno = -1; 07766 } 07767 tmp->canpark = conf->chan.canpark; 07768 tmp->transfer = conf->chan.transfer; 07769 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 07770 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 07771 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 07772 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 07773 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 07774 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 07775 tmp->cid_ton = 0; 07776 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 07777 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 07778 tmp->msgstate = -1; 07779 tmp->group = conf->chan.group; 07780 tmp->callgroup = conf->chan.callgroup; 07781 tmp->pickupgroup= conf->chan.pickupgroup; 07782 tmp->rxgain = conf->chan.rxgain; 07783 tmp->txgain = conf->chan.txgain; 07784 tmp->tonezone = conf->chan.tonezone; 07785 tmp->onhooktime = time(NULL); 07786 if (tmp->subs[SUB_REAL].zfd > -1) { 07787 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07788 if (tmp->dsp) 07789 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07790 update_conf(tmp); 07791 if (!here) { 07792 if (chan_sig != SIG_PRI) 07793 /* Hang it up to be sure it's good */ 07794 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07795 } 07796 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07797 #ifdef HAVE_PRI 07798 /* the dchannel is down so put the channel in alarm */ 07799 if (tmp->pri && !pri_is_up(tmp->pri)) 07800 tmp->inalarm = 1; 07801 else 07802 tmp->inalarm = 0; 07803 #endif 07804 memset(&si, 0, sizeof(si)); 07805 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07806 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07807 destroy_zt_pvt(&tmp); 07808 return NULL; 07809 } 07810 if (si.alarms) tmp->inalarm = 1; 07811 } 07812 07813 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 07814 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 07815 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 07816 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 07817 07818 } 07819 if (tmp && !here) { 07820 /* nothing on the iflist */ 07821 if (!*wlist) { 07822 *wlist = tmp; 07823 tmp->prev = NULL; 07824 tmp->next = NULL; 07825 *wend = tmp; 07826 } else { 07827 /* at least one member on the iflist */ 07828 struct zt_pvt *working = *wlist; 07829 07830 /* check if we maybe have to put it on the begining */ 07831 if (working->channel > tmp->channel) { 07832 tmp->next = *wlist; 07833 tmp->prev = NULL; 07834 (*wlist)->prev = tmp; 07835 *wlist = tmp; 07836 } else { 07837 /* go through all the members and put the member in the right place */ 07838 while (working) { 07839 /* in the middle */ 07840 if (working->next) { 07841 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07842 tmp->next = working->next; 07843 tmp->prev = working; 07844 working->next->prev = tmp; 07845 working->next = tmp; 07846 break; 07847 } 07848 } else { 07849 /* the last */ 07850 if (working->channel < tmp->channel) { 07851 working->next = tmp; 07852 tmp->next = NULL; 07853 tmp->prev = working; 07854 *wend = tmp; 07855 break; 07856 } 07857 } 07858 working = working->next; 07859 } 07860 } 07861 } 07862 } 07863 return tmp; 07864 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5550 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05551 { 05552 char c; 05553 05554 *str = 0; /* start with empty output buffer */ 05555 for (;;) 05556 { 05557 /* Wait for the first digit (up to specified ms). */ 05558 c = ast_waitfordigit(chan, ms); 05559 /* if timeout, hangup or error, return as such */ 05560 if (c < 1) 05561 return c; 05562 *str++ = c; 05563 *str = 0; 05564 if (strchr(term, c)) 05565 return 1; 05566 } 05567 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 5077 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().
05078 { 05079 int sent=0; 05080 int size; 05081 int res; 05082 int fd; 05083 fd = p->subs[index].zfd; 05084 while (len) { 05085 size = len; 05086 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 05087 size = (linear ? READ_SIZE * 2 : READ_SIZE); 05088 res = write(fd, buf, size); 05089 if (res != size) { 05090 if (option_debug) 05091 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 05092 return sent; 05093 } 05094 len -= size; 05095 buf += size; 05096 } 05097 return sent; 05098 }
static int process_zap | ( | struct zt_chan_conf * | confp, | |
struct ast_variable * | v, | |||
int | reload, | |||
int | skipchannels | |||
) | [static] |
Definition at line 11913 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, CHAN_PSEUDO, 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, LOG_WARNING, zt_pvt::mailbox, MAX_CHANLIST_LEN, mkintf(), zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, NUM_CADENCE_MAX, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pritransfer, 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_GSM, 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().
11914 { 11915 struct zt_pvt *tmp; 11916 char *ringc; /* temporary string for parsing the dring number. */ 11917 int y; 11918 int found_pseudo = 0; 11919 char zapchan[MAX_CHANLIST_LEN] = {}; 11920 11921 for (; v; v = v->next) { 11922 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 11923 continue; 11924 11925 /* Create the interface list */ 11926 if (!strcasecmp(v->name, "channel") 11927 #ifdef HAVE_PRI 11928 || !strcasecmp(v->name, "crv") 11929 #endif 11930 ) { 11931 int iscrv; 11932 if (skipchannels) 11933 continue; 11934 iscrv = !strcasecmp(v->name, "crv"); 11935 if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 11936 return -1; 11937 } else if (!strcasecmp(v->name, "zapchan")) { 11938 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 11939 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 11940 if (ast_true(v->value)) 11941 confp->chan.usedistinctiveringdetection = 1; 11942 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 11943 if (ast_true(v->value)) 11944 distinctiveringaftercid = 1; 11945 } else if (!strcasecmp(v->name, "dring1context")) { 11946 ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData)); 11947 } else if (!strcasecmp(v->name, "dring2context")) { 11948 ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData)); 11949 } else if (!strcasecmp(v->name, "dring3context")) { 11950 ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData)); 11951 } else if (!strcasecmp(v->name, "dring1")) { 11952 ringc = v->value; 11953 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 11954 } else if (!strcasecmp(v->name, "dring2")) { 11955 ringc = v->value; 11956 sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 11957 } else if (!strcasecmp(v->name, "dring3")) { 11958 ringc = v->value; 11959 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 11960 } else if (!strcasecmp(v->name, "usecallerid")) { 11961 confp->chan.use_callerid = ast_true(v->value); 11962 } else if (!strcasecmp(v->name, "cidsignalling")) { 11963 if (!strcasecmp(v->value, "bell")) 11964 confp->chan.cid_signalling = CID_SIG_BELL; 11965 else if (!strcasecmp(v->value, "v23")) 11966 confp->chan.cid_signalling = CID_SIG_V23; 11967 else if (!strcasecmp(v->value, "dtmf")) 11968 confp->chan.cid_signalling = CID_SIG_DTMF; 11969 else if (!strcasecmp(v->value, "smdi")) 11970 confp->chan.cid_signalling = CID_SIG_SMDI; 11971 else if (!strcasecmp(v->value, "v23_jp")) 11972 confp->chan.cid_signalling = CID_SIG_V23_JP; 11973 else if (ast_true(v->value)) 11974 confp->chan.cid_signalling = CID_SIG_BELL; 11975 } else if (!strcasecmp(v->name, "cidstart")) { 11976 if (!strcasecmp(v->value, "ring")) 11977 confp->chan.cid_start = CID_START_RING; 11978 else if (!strcasecmp(v->value, "polarity")) 11979 confp->chan.cid_start = CID_START_POLARITY; 11980 else if (ast_true(v->value)) 11981 confp->chan.cid_start = CID_START_RING; 11982 } else if (!strcasecmp(v->name, "threewaycalling")) { 11983 confp->chan.threewaycalling = ast_true(v->value); 11984 } else if (!strcasecmp(v->name, "cancallforward")) { 11985 confp->chan.cancallforward = ast_true(v->value); 11986 } else if (!strcasecmp(v->name, "relaxdtmf")) { 11987 if (ast_true(v->value)) 11988 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 11989 else 11990 confp->chan.dtmfrelax = 0; 11991 } else if (!strcasecmp(v->name, "mailbox")) { 11992 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 11993 } else if (!strcasecmp(v->name, "adsi")) { 11994 confp->chan.adsi = ast_true(v->value); 11995 } else if (!strcasecmp(v->name, "usesmdi")) { 11996 confp->chan.use_smdi = ast_true(v->value); 11997 } else if (!strcasecmp(v->name, "smdiport")) { 11998 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 11999 } else if (!strcasecmp(v->name, "transfer")) { 12000 confp->chan.transfer = ast_true(v->value); 12001 } else if (!strcasecmp(v->name, "canpark")) { 12002 confp->chan.canpark = ast_true(v->value); 12003 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 12004 confp->chan.echocanbridged = ast_true(v->value); 12005 } else if (!strcasecmp(v->name, "busydetect")) { 12006 confp->chan.busydetect = ast_true(v->value); 12007 } else if (!strcasecmp(v->name, "busycount")) { 12008 confp->chan.busycount = atoi(v->value); 12009 } else if (!strcasecmp(v->name, "busypattern")) { 12010 if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 12011 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 12012 } 12013 } else if (!strcasecmp(v->name, "callprogress")) { 12014 if (ast_true(v->value)) 12015 confp->chan.callprogress |= 1; 12016 else 12017 confp->chan.callprogress &= ~1; 12018 } else if (!strcasecmp(v->name, "faxdetect")) { 12019 if (!strcasecmp(v->value, "incoming")) { 12020 confp->chan.callprogress |= 4; 12021 confp->chan.callprogress &= ~2; 12022 } else if (!strcasecmp(v->value, "outgoing")) { 12023 confp->chan.callprogress &= ~4; 12024 confp->chan.callprogress |= 2; 12025 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 12026 confp->chan.callprogress |= 6; 12027 else 12028 confp->chan.callprogress &= ~6; 12029 } else if (!strcasecmp(v->name, "echocancel")) { 12030 if (!ast_strlen_zero(v->value)) { 12031 y = atoi(v->value); 12032 } else 12033 y = 0; 12034 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 12035 confp->chan.echocancel = y; 12036 else { 12037 confp->chan.echocancel = ast_true(v->value); 12038 if (confp->chan.echocancel) 12039 confp->chan.echocancel=128; 12040 } 12041 } else if (!strcasecmp(v->name, "echotraining")) { 12042 if (sscanf(v->value, "%d", &y) == 1) { 12043 if ((y < 10) || (y > 4000)) { 12044 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 12045 } else { 12046 confp->chan.echotraining = y; 12047 } 12048 } else if (ast_true(v->value)) { 12049 confp->chan.echotraining = 400; 12050 } else 12051 confp->chan.echotraining = 0; 12052 } else if (!strcasecmp(v->name, "hidecallerid")) { 12053 confp->chan.hidecallerid = ast_true(v->value); 12054 } else if (!strcasecmp(v->name, "hidecalleridname")) { 12055 confp->chan.hidecalleridname = ast_true(v->value); 12056 } else if (!strcasecmp(v->name, "pulsedial")) { 12057 confp->chan.pulse = ast_true(v->value); 12058 } else if (!strcasecmp(v->name, "callreturn")) { 12059 confp->chan.callreturn = ast_true(v->value); 12060 } else if (!strcasecmp(v->name, "callwaiting")) { 12061 confp->chan.callwaiting = ast_true(v->value); 12062 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 12063 confp->chan.callwaitingcallerid = ast_true(v->value); 12064 } else if (!strcasecmp(v->name, "context")) { 12065 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 12066 } else if (!strcasecmp(v->name, "language")) { 12067 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 12068 } else if (!strcasecmp(v->name, "progzone")) { 12069 ast_copy_string(progzone, v->value, sizeof(progzone)); 12070 } else if (!strcasecmp(v->name, "mohinterpret") 12071 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 12072 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 12073 } else if (!strcasecmp(v->name, "mohsuggest")) { 12074 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 12075 } else if (!strcasecmp(v->name, "stripmsd")) { 12076 confp->chan.stripmsd = atoi(v->value); 12077 } else if (!strcasecmp(v->name, "jitterbuffers")) { 12078 numbufs = atoi(v->value); 12079 } else if (!strcasecmp(v->name, "group")) { 12080 confp->chan.group = ast_get_group(v->value); 12081 } else if (!strcasecmp(v->name, "callgroup")) { 12082 confp->chan.callgroup = ast_get_group(v->value); 12083 } else if (!strcasecmp(v->name, "pickupgroup")) { 12084 confp->chan.pickupgroup = ast_get_group(v->value); 12085 } else if (!strcasecmp(v->name, "immediate")) { 12086 confp->chan.immediate = ast_true(v->value); 12087 } else if (!strcasecmp(v->name, "transfertobusy")) { 12088 confp->chan.transfertobusy = ast_true(v->value); 12089 } else if (!strcasecmp(v->name, "rxgain")) { 12090 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 12091 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 12092 } 12093 } else if (!strcasecmp(v->name, "txgain")) { 12094 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 12095 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 12096 } 12097 } else if (!strcasecmp(v->name, "tonezone")) { 12098 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 12099 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 12100 } 12101 } else if (!strcasecmp(v->name, "callerid")) { 12102 if (!strcasecmp(v->value, "asreceived")) { 12103 confp->chan.cid_num[0] = '\0'; 12104 confp->chan.cid_name[0] = '\0'; 12105 } else { 12106 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 12107 } 12108 } else if (!strcasecmp(v->name, "fullname")) { 12109 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 12110 } else if (!strcasecmp(v->name, "cid_number")) { 12111 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 12112 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 12113 confp->chan.zaptrcallerid = ast_true(v->value); 12114 } else if (!strcasecmp(v->name, "restrictcid")) { 12115 confp->chan.restrictcid = ast_true(v->value); 12116 } else if (!strcasecmp(v->name, "usecallingpres")) { 12117 confp->chan.use_callingpres = ast_true(v->value); 12118 } else if (!strcasecmp(v->name, "accountcode")) { 12119 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 12120 } else if (!strcasecmp(v->name, "amaflags")) { 12121 y = ast_cdr_amaflags2int(v->value); 12122 if (y < 0) 12123 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 12124 else 12125 confp->chan.amaflags = y; 12126 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 12127 confp->chan.polarityonanswerdelay = atoi(v->value); 12128 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 12129 confp->chan.answeronpolarityswitch = ast_true(v->value); 12130 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 12131 confp->chan.hanguponpolarityswitch = ast_true(v->value); 12132 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 12133 confp->chan.sendcalleridafter = atoi(v->value); 12134 } else if (!reload){ 12135 if (!strcasecmp(v->name, "signalling")) { 12136 confp->chan.outsigmod = -1; 12137 if (!strcasecmp(v->value, "em")) { 12138 confp->chan.sig = SIG_EM; 12139 } else if (!strcasecmp(v->value, "em_e1")) { 12140 confp->chan.sig = SIG_EM_E1; 12141 } else if (!strcasecmp(v->value, "em_w")) { 12142 confp->chan.sig = SIG_EMWINK; 12143 confp->chan.radio = 0; 12144 } else if (!strcasecmp(v->value, "fxs_ls")) { 12145 confp->chan.sig = SIG_FXSLS; 12146 confp->chan.radio = 0; 12147 } else if (!strcasecmp(v->value, "fxs_gs")) { 12148 confp->chan.sig = SIG_FXSGS; 12149 confp->chan.radio = 0; 12150 } else if (!strcasecmp(v->value, "fxs_ks")) { 12151 confp->chan.sig = SIG_FXSKS; 12152 confp->chan.radio = 0; 12153 } else if (!strcasecmp(v->value, "fxo_ls")) { 12154 confp->chan.sig = SIG_FXOLS; 12155 confp->chan.radio = 0; 12156 } else if (!strcasecmp(v->value, "fxo_gs")) { 12157 confp->chan.sig = SIG_FXOGS; 12158 confp->chan.radio = 0; 12159 } else if (!strcasecmp(v->value, "fxo_ks")) { 12160 confp->chan.sig = SIG_FXOKS; 12161 confp->chan.radio = 0; 12162 } else if (!strcasecmp(v->value, "fxs_rx")) { 12163 confp->chan.sig = SIG_FXSKS; 12164 confp->chan.radio = 1; 12165 } else if (!strcasecmp(v->value, "fxo_rx")) { 12166 confp->chan.sig = SIG_FXOLS; 12167 confp->chan.radio = 1; 12168 } else if (!strcasecmp(v->value, "fxs_tx")) { 12169 confp->chan.sig = SIG_FXSLS; 12170 confp->chan.radio = 1; 12171 } else if (!strcasecmp(v->value, "fxo_tx")) { 12172 confp->chan.sig = SIG_FXOGS; 12173 confp->chan.radio = 1; 12174 } else if (!strcasecmp(v->value, "em_rx")) { 12175 confp->chan.sig = SIG_EM; 12176 confp->chan.radio = 1; 12177 } else if (!strcasecmp(v->value, "em_tx")) { 12178 confp->chan.sig = SIG_EM; 12179 confp->chan.radio = 1; 12180 } else if (!strcasecmp(v->value, "em_rxtx")) { 12181 confp->chan.sig = SIG_EM; 12182 confp->chan.radio = 2; 12183 } else if (!strcasecmp(v->value, "em_txrx")) { 12184 confp->chan.sig = SIG_EM; 12185 confp->chan.radio = 2; 12186 } else if (!strcasecmp(v->value, "sf")) { 12187 confp->chan.sig = SIG_SF; 12188 confp->chan.radio = 0; 12189 } else if (!strcasecmp(v->value, "sf_w")) { 12190 confp->chan.sig = SIG_SFWINK; 12191 confp->chan.radio = 0; 12192 } else if (!strcasecmp(v->value, "sf_featd")) { 12193 confp->chan.sig = SIG_FEATD; 12194 confp->chan.radio = 0; 12195 } else if (!strcasecmp(v->value, "sf_featdmf")) { 12196 confp->chan.sig = SIG_FEATDMF; 12197 confp->chan.radio = 0; 12198 } else if (!strcasecmp(v->value, "sf_featb")) { 12199 confp->chan.sig = SIG_SF_FEATB; 12200 confp->chan.radio = 0; 12201 } else if (!strcasecmp(v->value, "sf")) { 12202 confp->chan.sig = SIG_SF; 12203 confp->chan.radio = 0; 12204 } else if (!strcasecmp(v->value, "sf_rx")) { 12205 confp->chan.sig = SIG_SF; 12206 confp->chan.radio = 1; 12207 } else if (!strcasecmp(v->value, "sf_tx")) { 12208 confp->chan.sig = SIG_SF; 12209 confp->chan.radio = 1; 12210 } else if (!strcasecmp(v->value, "sf_rxtx")) { 12211 confp->chan.sig = SIG_SF; 12212 confp->chan.radio = 2; 12213 } else if (!strcasecmp(v->value, "sf_txrx")) { 12214 confp->chan.sig = SIG_SF; 12215 confp->chan.radio = 2; 12216 } else if (!strcasecmp(v->value, "featd")) { 12217 confp->chan.sig = SIG_FEATD; 12218 confp->chan.radio = 0; 12219 } else if (!strcasecmp(v->value, "featdmf")) { 12220 confp->chan.sig = SIG_FEATDMF; 12221 confp->chan.radio = 0; 12222 } else if (!strcasecmp(v->value, "featdmf_ta")) { 12223 confp->chan.sig = SIG_FEATDMF_TA; 12224 confp->chan.radio = 0; 12225 } else if (!strcasecmp(v->value, "e911")) { 12226 confp->chan.sig = SIG_E911; 12227 confp->chan.radio = 0; 12228 } else if (!strcasecmp(v->value, "fgccama")) { 12229 confp->chan.sig = SIG_FGC_CAMA; 12230 confp->chan.radio = 0; 12231 } else if (!strcasecmp(v->value, "fgccamamf")) { 12232 confp->chan.sig = SIG_FGC_CAMAMF; 12233 confp->chan.radio = 0; 12234 } else if (!strcasecmp(v->value, "featb")) { 12235 confp->chan.sig = SIG_FEATB; 12236 confp->chan.radio = 0; 12237 #ifdef HAVE_PRI 12238 } else if (!strcasecmp(v->value, "pri_net")) { 12239 confp->chan.radio = 0; 12240 confp->chan.sig = SIG_PRI; 12241 confp->pri.nodetype = PRI_NETWORK; 12242 } else if (!strcasecmp(v->value, "pri_cpe")) { 12243 confp->chan.sig = SIG_PRI; 12244 confp->chan.radio = 0; 12245 confp->pri.nodetype = PRI_CPE; 12246 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 12247 confp->chan.sig = SIG_GR303FXOKS; 12248 confp->chan.radio = 0; 12249 confp->pri.nodetype = PRI_NETWORK; 12250 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 12251 confp->chan.sig = SIG_GR303FXSKS; 12252 confp->chan.radio = 0; 12253 confp->pri.nodetype = PRI_CPE; 12254 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 12255 confp->chan.radio = 0; 12256 confp->chan.sig = SIG_PRI; 12257 confp->pri.nodetype = BRI_NETWORK_PTMP; 12258 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 12259 confp->chan.sig = SIG_PRI; 12260 confp->chan.radio = 0; 12261 confp->pri.nodetype = BRI_CPE_PTMP; 12262 } else if (!strcasecmp(v->value, "bri_net")) { 12263 confp->chan.radio = 0; 12264 confp->chan.sig = SIG_PRI; 12265 confp->pri.nodetype = BRI_NETWORK; 12266 } else if (!strcasecmp(v->value, "bri_cpe")) { 12267 confp->chan.sig = SIG_PRI; 12268 confp->chan.radio = 0; 12269 confp->pri.nodetype = BRI_CPE; 12270 #endif 12271 #ifdef HAVE_GSMAT 12272 } else if (!strcasecmp(v->value, "gsm")) { 12273 confp->chan.sig = SIG_GSM; 12274 confp->chan.radio = 0; 12275 #endif 12276 } else { 12277 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 12278 } 12279 } else if (!strcasecmp(v->name, "outsignalling")) { 12280 if (!strcasecmp(v->value, "em")) { 12281 confp->chan.outsigmod = SIG_EM; 12282 } else if (!strcasecmp(v->value, "em_e1")) { 12283 confp->chan.outsigmod = SIG_EM_E1; 12284 } else if (!strcasecmp(v->value, "em_w")) { 12285 confp->chan.outsigmod = SIG_EMWINK; 12286 } else if (!strcasecmp(v->value, "sf")) { 12287 confp->chan.outsigmod = SIG_SF; 12288 } else if (!strcasecmp(v->value, "sf_w")) { 12289 confp->chan.outsigmod = SIG_SFWINK; 12290 } else if (!strcasecmp(v->value, "sf_featd")) { 12291 confp->chan.outsigmod = SIG_FEATD; 12292 } else if (!strcasecmp(v->value, "sf_featdmf")) { 12293 confp->chan.outsigmod = SIG_FEATDMF; 12294 } else if (!strcasecmp(v->value, "sf_featb")) { 12295 confp->chan.outsigmod = SIG_SF_FEATB; 12296 } else if (!strcasecmp(v->value, "sf")) { 12297 confp->chan.outsigmod = SIG_SF; 12298 } else if (!strcasecmp(v->value, "featd")) { 12299 confp->chan.outsigmod = SIG_FEATD; 12300 } else if (!strcasecmp(v->value, "featdmf")) { 12301 confp->chan.outsigmod = SIG_FEATDMF; 12302 } else if (!strcasecmp(v->value, "featdmf_ta")) { 12303 confp->chan.outsigmod = SIG_FEATDMF_TA; 12304 } else if (!strcasecmp(v->value, "e911")) { 12305 confp->chan.outsigmod = SIG_E911; 12306 } else if (!strcasecmp(v->value, "fgccama")) { 12307 confp->chan.outsigmod = SIG_FGC_CAMA; 12308 } else if (!strcasecmp(v->value, "fgccamamf")) { 12309 confp->chan.outsigmod = SIG_FGC_CAMAMF; 12310 } else if (!strcasecmp(v->value, "featb")) { 12311 confp->chan.outsigmod = SIG_FEATB; 12312 } else { 12313 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 12314 } 12315 #ifdef HAVE_PRI 12316 } else if (!strcasecmp(v->name, "pridialplan")) { 12317 if (!strcasecmp(v->value, "national")) { 12318 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 12319 } else if (!strcasecmp(v->value, "unknown")) { 12320 confp->pri.dialplan = PRI_UNKNOWN + 1; 12321 } else if (!strcasecmp(v->value, "private")) { 12322 confp->pri.dialplan = PRI_PRIVATE + 1; 12323 } else if (!strcasecmp(v->value, "international")) { 12324 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 12325 } else if (!strcasecmp(v->value, "local")) { 12326 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 12327 } else if (!strcasecmp(v->value, "dynamic")) { 12328 confp->pri.dialplan = -1; 12329 } else { 12330 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 12331 } 12332 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 12333 if (!strcasecmp(v->value, "national")) { 12334 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 12335 } else if (!strcasecmp(v->value, "unknown")) { 12336 confp->pri.localdialplan = PRI_UNKNOWN + 1; 12337 } else if (!strcasecmp(v->value, "private")) { 12338 confp->pri.localdialplan = PRI_PRIVATE + 1; 12339 } else if (!strcasecmp(v->value, "international")) { 12340 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 12341 } else if (!strcasecmp(v->value, "local")) { 12342 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 12343 } else if (!strcasecmp(v->value, "dynamic")) { 12344 confp->pri.localdialplan = -1; 12345 } else { 12346 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 12347 } 12348 } else if (!strcasecmp(v->name, "switchtype")) { 12349 if (!strcasecmp(v->value, "national")) 12350 confp->pri.switchtype = PRI_SWITCH_NI2; 12351 else if (!strcasecmp(v->value, "ni1")) 12352 confp->pri.switchtype = PRI_SWITCH_NI1; 12353 else if (!strcasecmp(v->value, "dms100")) 12354 confp->pri.switchtype = PRI_SWITCH_DMS100; 12355 else if (!strcasecmp(v->value, "4ess")) 12356 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 12357 else if (!strcasecmp(v->value, "5ess")) 12358 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 12359 else if (!strcasecmp(v->value, "euroisdn")) 12360 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 12361 else if (!strcasecmp(v->value, "qsig")) 12362 confp->pri.switchtype = PRI_SWITCH_QSIG; 12363 else { 12364 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 12365 return -1; 12366 } 12367 } else if (!strcasecmp(v->name, "nsf")) { 12368 if (!strcasecmp(v->value, "sdn")) 12369 confp->pri.nsf = PRI_NSF_SDN; 12370 else if (!strcasecmp(v->value, "megacom")) 12371 confp->pri.nsf = PRI_NSF_MEGACOM; 12372 else if (!strcasecmp(v->value, "tollfreemegacom")) 12373 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 12374 else if (!strcasecmp(v->value, "accunet")) 12375 confp->pri.nsf = PRI_NSF_ACCUNET; 12376 else if (!strcasecmp(v->value, "none")) 12377 confp->pri.nsf = PRI_NSF_NONE; 12378 else { 12379 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 12380 confp->pri.nsf = PRI_NSF_NONE; 12381 } 12382 } else if (!strcasecmp(v->name, "priindication")) { 12383 if (!strcasecmp(v->value, "outofband")) 12384 confp->chan.priindication_oob = 1; 12385 else if (!strcasecmp(v->value, "inband")) 12386 confp->chan.priindication_oob = 0; 12387 else if (!strcasecmp(v->value, "passthrough")) 12388 confp->chan.priindication_oob = 2; 12389 else 12390 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n", 12391 v->value, v->lineno); 12392 } else if (!strcasecmp(v->name, "pritransfer")) { 12393 if (!strcasecmp(v->value, "no")) 12394 confp->chan.pritransfer = 0; 12395 else if (!strcasecmp(v->value, "ect")) 12396 confp->chan.pritransfer = 1; 12397 else if (!strcasecmp(v->value, "hangup")) 12398 confp->chan.pritransfer = 2; 12399 else 12400 ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n", 12401 v->value, v->lineno); 12402 } else if (!strcasecmp(v->name, "priexclusive")) { 12403 confp->chan.priexclusive = ast_true(v->value); 12404 } else if (!strcasecmp(v->name, "internationalprefix")) { 12405 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 12406 } else if (!strcasecmp(v->name, "nationalprefix")) { 12407 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 12408 } else if (!strcasecmp(v->name, "localprefix")) { 12409 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 12410 } else if (!strcasecmp(v->name, "privateprefix")) { 12411 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 12412 } else if (!strcasecmp(v->name, "unknownprefix")) { 12413 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 12414 } else if (!strcasecmp(v->name, "nocid")) { 12415 ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid)); 12416 } else if (!strcasecmp(v->name, "withheldcid")) { 12417 ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid)); 12418 } else if (!strcasecmp(v->name, "pin")) { 12419 ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1); 12420 } else if (!strcasecmp(v->name, "exten")) { 12421 ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1); 12422 } else if (!strcasecmp(v->name, "resetinterval")) { 12423 if (!strcasecmp(v->value, "never")) 12424 confp->pri.resetinterval = -1; 12425 else if (atoi(v->value) >= 60) 12426 confp->pri.resetinterval = atoi(v->value); 12427 else 12428 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 12429 v->value, v->lineno); 12430 } else if (!strcasecmp(v->name, "minunused")) { 12431 confp->pri.minunused = atoi(v->value); 12432 } else if (!strcasecmp(v->name, "minidle")) { 12433 confp->pri.minidle = atoi(v->value); 12434 } else if (!strcasecmp(v->name, "idleext")) { 12435 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 12436 } else if (!strcasecmp(v->name, "idledial")) { 12437 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 12438 } else if (!strcasecmp(v->name, "pritrustusercid")) { 12439 confp->pri.usercid = ast_true(v->value); 12440 } else if (!strcasecmp(v->name, "overlapdial")) { 12441 confp->pri.overlapdial = ast_true(v->value); 12442 } else if (!strcasecmp(v->name, "pritimer")) { 12443 #ifdef PRI_GETSET_TIMERS 12444 char *timerc, *c; 12445 int timer, timeridx; 12446 c = v->value; 12447 timerc = strsep(&c, ","); 12448 if (timerc) { 12449 timer = atoi(c); 12450 if (!timer) 12451 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 12452 else { 12453 if ((timeridx = pri_timer2idx(timerc)) >= 0) 12454 pritimers[timeridx] = timer; 12455 else 12456 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 12457 } 12458 } else 12459 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 12460 12461 } else if (!strcasecmp(v->name, "facilityenable")) { 12462 confp->pri.facilityenable = ast_true(v->value); 12463 #endif /* PRI_GETSET_TIMERS */ 12464 #endif /* HAVE_PRI */ 12465 } else if (!strcasecmp(v->name, "cadence")) { 12466 /* setup to scan our argument */ 12467 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 12468 int i; 12469 struct zt_ring_cadence new_cadence; 12470 int cid_location = -1; 12471 int firstcadencepos = 0; 12472 char original_args[80]; 12473 int cadence_is_ok = 1; 12474 12475 ast_copy_string(original_args, v->value, sizeof(original_args)); 12476 /* 16 cadences allowed (8 pairs) */ 12477 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]); 12478 12479 /* Cadence must be even (on/off) */ 12480 if (element_count % 2 == 1) { 12481 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 12482 cadence_is_ok = 0; 12483 } 12484 12485 /* Ring cadences cannot be negative */ 12486 for (i = 0; i < element_count; i++) { 12487 if (c[i] == 0) { 12488 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 12489 cadence_is_ok = 0; 12490 break; 12491 } else if (c[i] < 0) { 12492 if (i % 2 == 1) { 12493 /* Silence duration, negative possibly okay */ 12494 if (cid_location == -1) { 12495 cid_location = i; 12496 c[i] *= -1; 12497 } else { 12498 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 12499 cadence_is_ok = 0; 12500 break; 12501 } 12502 } else { 12503 if (firstcadencepos == 0) { 12504 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 12505 /* duration will be passed negative to the zaptel driver */ 12506 } else { 12507 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 12508 cadence_is_ok = 0; 12509 break; 12510 } 12511 } 12512 } 12513 } 12514 12515 /* Substitute our scanned cadence */ 12516 for (i = 0; i < 16; i++) { 12517 new_cadence.ringcadence[i] = c[i]; 12518 } 12519 12520 if (cadence_is_ok) { 12521 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 12522 if (element_count < 2) { 12523 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 12524 } else { 12525 if (cid_location == -1) { 12526 /* user didn't say; default to first pause */ 12527 cid_location = 1; 12528 } else { 12529 /* convert element_index to cidrings value */ 12530 cid_location = (cid_location + 1) / 2; 12531 } 12532 /* ---we like their cadence; try to install it--- */ 12533 if (!user_has_defined_cadences++) 12534 /* this is the first user-defined cadence; clear the default user cadences */ 12535 num_cadence = 0; 12536 if ((num_cadence+1) >= NUM_CADENCE_MAX) 12537 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 12538 else { 12539 cadences[num_cadence] = new_cadence; 12540 cidrings[num_cadence++] = cid_location; 12541 if (option_verbose > 2) 12542 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 12543 } 12544 } 12545 } 12546 } else if (!strcasecmp(v->name, "ringtimeout")) { 12547 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 12548 } else if (!strcasecmp(v->name, "prewink")) { 12549 confp->timing.prewinktime = atoi(v->value); 12550 } else if (!strcasecmp(v->name, "preflash")) { 12551 confp->timing.preflashtime = atoi(v->value); 12552 } else if (!strcasecmp(v->name, "wink")) { 12553 confp->timing.winktime = atoi(v->value); 12554 } else if (!strcasecmp(v->name, "flash")) { 12555 confp->timing.flashtime = atoi(v->value); 12556 } else if (!strcasecmp(v->name, "start")) { 12557 confp->timing.starttime = atoi(v->value); 12558 } else if (!strcasecmp(v->name, "rxwink")) { 12559 confp->timing.rxwinktime = atoi(v->value); 12560 } else if (!strcasecmp(v->name, "rxflash")) { 12561 confp->timing.rxflashtime = atoi(v->value); 12562 } else if (!strcasecmp(v->name, "debounce")) { 12563 confp->timing.debouncetime = atoi(v->value); 12564 } else if (!strcasecmp(v->name, "toneduration")) { 12565 int toneduration; 12566 int ctlfd; 12567 int res; 12568 struct zt_dialparams dps; 12569 12570 ctlfd = open("/dev/zap/ctl", O_RDWR); 12571 if (ctlfd == -1) { 12572 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 12573 return -1; 12574 } 12575 12576 toneduration = atoi(v->value); 12577 if (toneduration > -1) { 12578 memset(&dps, 0, sizeof(dps)); 12579 12580 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 12581 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 12582 if (res < 0) { 12583 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 12584 return -1; 12585 } 12586 } 12587 close(ctlfd); 12588 } else if (!strcasecmp(v->name, "defaultcic")) { 12589 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 12590 } else if (!strcasecmp(v->name, "defaultozz")) { 12591 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 12592 } 12593 } else if (!skipchannels) 12594 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12595 } 12596 if (zapchan[0]) { 12597 /* The user has set 'zapchan' */ 12598 /*< \todo pass proper line number instead of 0 */ 12599 if (build_channels(confp, 0, zapchan, reload, 0, &found_pseudo)) { 12600 return -1; 12601 } 12602 } 12603 /*< \todo why check for the pseudo in the per-channel section. 12604 * Any actual use for manual setup of the pseudo channel? */ 12605 if (!found_pseudo && reload == 0) { 12606 /* Make sure pseudo isn't a member of any groups if 12607 we're automatically making it. */ 12608 12609 confp->chan.group = 0; 12610 confp->chan.callgroup = 0; 12611 confp->chan.pickupgroup = 0; 12612 12613 tmp = mkintf(CHAN_PSEUDO, confp, NULL, reload); 12614 12615 if (tmp) { 12616 if (option_verbose > 2) 12617 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 12618 } else { 12619 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 12620 } 12621 } 12622 return 0; 12623 }
static int reload | ( | void | ) | [static] |
Definition at line 12979 of file chan_zap.c.
References ast_log(), LOG_WARNING, and setup_zap().
12980 { 12981 int res = 0; 12982 12983 res = setup_zap(1); 12984 if (res) { 12985 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 12986 return -1; 12987 } 12988 return 0; 12989 }
static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1398 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().
01399 { 01400 ZT_CONFINFO zi; 01401 memset(&zi, 0, sizeof(zi)); 01402 p->confno = -1; 01403 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01404 if (p->subs[SUB_REAL].zfd > -1) { 01405 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01406 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01407 } 01408 return 0; 01409 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 7196 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(), LOG_ERROR, and LOG_WARNING.
07197 { 07198 pthread_attr_t attr; 07199 pthread_attr_init(&attr); 07200 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07201 /* If we're supposed to be stopped -- stay stopped */ 07202 if (monitor_thread == AST_PTHREADT_STOP) 07203 return 0; 07204 ast_mutex_lock(&monlock); 07205 if (monitor_thread == pthread_self()) { 07206 ast_mutex_unlock(&monlock); 07207 ast_log(LOG_WARNING, "Cannot kill myself\n"); 07208 return -1; 07209 } 07210 if (monitor_thread != AST_PTHREADT_NULL) { 07211 /* Wake up the thread */ 07212 pthread_kill(monitor_thread, SIGURG); 07213 } else { 07214 /* Start a new monitor */ 07215 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 07216 ast_mutex_unlock(&monlock); 07217 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 07218 pthread_attr_destroy(&attr); 07219 return -1; 07220 } 07221 } 07222 ast_mutex_unlock(&monlock); 07223 pthread_attr_destroy(&attr); 07224 return 0; 07225 }
static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1734 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().
01735 { 01736 int res; 01737 if (p->saveconf.confmode) { 01738 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01739 p->saveconf.confmode = 0; 01740 if (res) { 01741 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01742 return -1; 01743 } 01744 } 01745 if (option_debug) 01746 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01747 return 0; 01748 }
static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1661 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().
01662 { 01663 int res; 01664 01665 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01666 if (res) { 01667 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01668 return -1; 01669 } 01670 01671 return 0; 01672 }
static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1706 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().
01707 { 01708 struct zt_confinfo c; 01709 int res; 01710 if (p->saveconf.confmode) { 01711 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01712 return -1; 01713 } 01714 p->saveconf.chan = 0; 01715 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01716 if (res) { 01717 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01718 p->saveconf.confmode = 0; 01719 return -1; 01720 } 01721 c.chan = 0; 01722 c.confno = 0; 01723 c.confmode = ZT_CONF_NORMAL; 01724 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01725 if (res) { 01726 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01727 return -1; 01728 } 01729 if (option_debug) 01730 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01731 return 0; 01732 }
static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1774 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().
01775 { 01776 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01777 int res; 01778 /* Take out of linear mode if necessary */ 01779 if (p->subs[SUB_REAL].linear) { 01780 p->subs[SUB_REAL].linear = 0; 01781 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01782 } 01783 while (p->cidpos < p->cidlen) { 01784 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01785 if (res < 0) { 01786 if (errno == EAGAIN) 01787 return 0; 01788 else { 01789 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01790 return -1; 01791 } 01792 } 01793 if (!res) 01794 return 0; 01795 p->cidpos += res; 01796 } 01797 free(p->cidspill); 01798 p->cidspill = NULL; 01799 if (p->callwaitcas) { 01800 /* Wait for CID/CW to expire */ 01801 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01802 } else 01803 restore_conference(p); 01804 return 0; 01805 }
static int send_cwcidspill | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1752 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().
01753 { 01754 p->callwaitcas = 0; 01755 p->cidcwexpire = 0; 01756 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 01757 return -1; 01758 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01759 /* Make sure we account for the end */ 01760 p->cidlen += READ_SIZE * 4; 01761 p->cidpos = 0; 01762 send_callerid(p); 01763 if (option_verbose > 2) 01764 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01765 return 0; 01766 }
static int set_actual_gain | ( | int | fd, | |
int | chan, | |||
float | rxgain, | |||
float | txgain, | |||
int | law | |||
) | [static] |
Definition at line 1642 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), mkintf(), restore_gains(), and zt_call().
01643 { 01644 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01645 }
static int set_actual_rxgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1624 of file chan_zap.c.
References ast_log(), errno, fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01625 { 01626 struct zt_gains g; 01627 int res; 01628 01629 memset(&g, 0, sizeof(g)); 01630 g.chan = chan; 01631 res = ioctl(fd, ZT_GETGAINS, &g); 01632 if (res) { 01633 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01634 return res; 01635 } 01636 01637 fill_rxgain(&g, gain, law); 01638 01639 return ioctl(fd, ZT_SETGAINS, &g); 01640 }
static int set_actual_txgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1605 of file chan_zap.c.
References ast_log(), errno, fill_txgain(), LOG_DEBUG, and option_debug.
Referenced by set_actual_gain(), and zt_setoption().
01606 { 01607 struct zt_gains g; 01608 int res; 01609 01610 memset(&g, 0, sizeof(g)); 01611 g.chan = chan; 01612 res = ioctl(fd, ZT_GETGAINS, &g); 01613 if (res) { 01614 if (option_debug) 01615 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01616 return res; 01617 } 01618 01619 fill_txgain(&g, gain, law); 01620 01621 return ioctl(fd, ZT_SETGAINS, &g); 01622 }
static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 12625 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(), global_jbconf, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, 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().
12626 { 12627 struct ast_config *cfg; 12628 struct ast_variable *v; 12629 struct zt_chan_conf conf = zt_chan_conf_default(); 12630 int res; 12631 12632 #ifdef HAVE_PRI 12633 char *c; 12634 int spanno; 12635 int i, x; 12636 int logicalspan; 12637 int trunkgroup; 12638 int dchannels[NUM_DCHANS]; 12639 #endif 12640 12641 cfg = ast_config_load(config); 12642 12643 /* Error if we have no config file */ 12644 if (!cfg) { 12645 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 12646 return 0; 12647 } 12648 12649 /* It's a little silly to lock it, but we mind as well just to be sure */ 12650 ast_mutex_lock(&iflock); 12651 #ifdef HAVE_PRI 12652 if (!reload) { 12653 /* Process trunkgroups first */ 12654 v = ast_variable_browse(cfg, "trunkgroups"); 12655 while (v) { 12656 if (!strcasecmp(v->name, "trunkgroup")) { 12657 trunkgroup = atoi(v->value); 12658 if (trunkgroup > 0) { 12659 if ((c = strchr(v->value, ','))) { 12660 i = 0; 12661 memset(dchannels, 0, sizeof(dchannels)); 12662 while (c && (i < NUM_DCHANS)) { 12663 dchannels[i] = atoi(c + 1); 12664 if (dchannels[i] < 0) { 12665 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); 12666 } else 12667 i++; 12668 c = strchr(c + 1, ','); 12669 } 12670 if (i) { 12671 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 12672 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); 12673 } else if (option_verbose > 1) 12674 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"); 12675 } else 12676 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 12677 } else 12678 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 12679 } else 12680 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 12681 } else if (!strcasecmp(v->name, "spanmap")) { 12682 spanno = atoi(v->value); 12683 if (spanno > 0) { 12684 if ((c = strchr(v->value, ','))) { 12685 trunkgroup = atoi(c + 1); 12686 if (trunkgroup > 0) { 12687 if ((c = strchr(c + 1, ','))) 12688 logicalspan = atoi(c + 1); 12689 else 12690 logicalspan = 0; 12691 if (logicalspan >= 0) { 12692 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 12693 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 12694 } else if (option_verbose > 1) 12695 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 12696 } else 12697 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 12698 } else 12699 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 12700 } else 12701 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 12702 } else 12703 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 12704 } else { 12705 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 12706 } 12707 v = v->next; 12708 } 12709 } 12710 #endif 12711 12712 /* Copy the default jb config over global_jbconf */ 12713 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 12714 12715 v = ast_variable_browse(cfg, "channels"); 12716 res = process_zap(&conf, v, reload, 0); 12717 ast_mutex_unlock(&iflock); 12718 ast_config_destroy(cfg); 12719 if (res) 12720 return res; 12721 cfg = ast_config_load("users.conf"); 12722 if (cfg) { 12723 char *cat; 12724 const char *chans; 12725 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 12726 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 12727 if (!strcasecmp(cat, "general")) 12728 continue; 12729 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 12730 if (!ast_strlen_zero(chans)) { 12731 struct zt_chan_conf sect_conf; 12732 memcpy(§_conf, &conf, sizeof(sect_conf)); 12733 12734 process_zap(§_conf, ast_variable_browse(cfg, cat), reload, 0); 12735 } 12736 } 12737 ast_config_destroy(cfg); 12738 } 12739 #ifdef HAVE_PRI 12740 if (!reload) { 12741 for (x = 0; x < NUM_SPANS; x++) { 12742 pris[x].debugfd = -1; 12743 if (pris[x].pvts[0]) { 12744 if (start_pri(pris + x)) { 12745 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 12746 return -1; 12747 } else if (option_verbose > 1) 12748 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 12749 } 12750 } 12751 } 12752 #endif 12753 /* And start the monitor for the first time */ 12754 restart_monitor(); 12755 return 0; 12756 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5587 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_shrink_phone_number(), ast_smdi_md_message_destroy(), 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(), ASTOBJ_UNREF, 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, CID_START_RING, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, errno, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, ast_frame::frametype, free, func, ast_smdi_md_message::fwd_st, ast_channel::hangupcause, zt_pvt::hanguponpolarityswitch, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, zt_pvt::lastcid_num, len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), my_getsigstr(), name, NEED_MFDETECT, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_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, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, 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, 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().
05588 { 05589 struct ast_channel *chan = data; 05590 struct zt_pvt *p = chan->tech_pvt; 05591 char exten[AST_MAX_EXTENSION] = ""; 05592 char exten2[AST_MAX_EXTENSION] = ""; 05593 unsigned char buf[256]; 05594 char dtmfcid[300]; 05595 char dtmfbuf[300]; 05596 struct callerid_state *cs = NULL; 05597 char *name = NULL, *number = NULL; 05598 int distMatches; 05599 int curRingData[3]; 05600 int receivedRingT; 05601 int counter1; 05602 int counter; 05603 int samples = 0; 05604 struct ast_smdi_md_message *smdi_msg = NULL; 05605 int flags; 05606 int i; 05607 int timeout; 05608 int getforward = 0; 05609 char *s1, *s2; 05610 int len = 0; 05611 int res; 05612 int index; 05613 int network; 05614 05615 /* in the bizarre case where the channel has become a zombie before we 05616 even get started here, abort safely 05617 */ 05618 if (!p) { 05619 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05620 ast_hangup(chan); 05621 return NULL; 05622 } 05623 05624 if (option_verbose > 2) 05625 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05626 index = zt_get_index(chan, p, 1); 05627 if (index < 0) { 05628 ast_log(LOG_WARNING, "Huh?\n"); 05629 ast_hangup(chan); 05630 return NULL; 05631 } 05632 if (p->dsp) 05633 ast_dsp_digitreset(p->dsp); 05634 switch (p->sig) { 05635 #ifdef HAVE_PRI 05636 case SIG_PRI: 05637 /* Now loop looking for an extension */ 05638 ast_copy_string(exten, p->exten, sizeof(exten)); 05639 len = strlen(exten); 05640 res = 0; 05641 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05642 if (len && !ast_ignore_pattern(chan->context, exten)) { 05643 tone_zone_play_tone(p->subs[index].zfd, -1); 05644 } else { 05645 network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP; 05646 if (network) { 05647 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05648 } else { 05649 /* cpe be quiet */ 05650 tone_zone_play_tone(p->subs[index].zfd, -1); 05651 } 05652 } 05653 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05654 timeout = matchdigittimeout; 05655 else 05656 timeout = gendigittimeout; 05657 res = ast_waitfordigit(chan, timeout); 05658 if (res < 0) { 05659 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05660 ast_hangup(chan); 05661 return NULL; 05662 } else if (res) { 05663 exten[len++] = res; 05664 exten[len] = '\0'; 05665 } else 05666 break; 05667 } 05668 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05669 if (ast_strlen_zero(exten)) { 05670 if (option_verbose > 2) 05671 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05672 exten[0] = 's'; 05673 exten[1] = '\0'; 05674 } 05675 tone_zone_play_tone(p->subs[index].zfd, -1); 05676 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05677 /* Start the real PBX */ 05678 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05679 if (p->dsp) ast_dsp_digitreset(p->dsp); 05680 zt_enable_ec(p); 05681 ast_setstate(chan, AST_STATE_RING); 05682 res = ast_pbx_run(chan); 05683 if (res) { 05684 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05685 } 05686 } else { 05687 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05688 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05689 ast_hangup(chan); 05690 p->exten[0] = '\0'; 05691 /* Since we send release complete here, we won't get one */ 05692 p->call = NULL; 05693 } 05694 return NULL; 05695 break; 05696 #endif 05697 case SIG_FEATD: 05698 case SIG_FEATDMF: 05699 case SIG_FEATDMF_TA: 05700 case SIG_E911: 05701 case SIG_FGC_CAMAMF: 05702 case SIG_FEATB: 05703 case SIG_EMWINK: 05704 case SIG_SF_FEATD: 05705 case SIG_SF_FEATDMF: 05706 case SIG_SF_FEATB: 05707 case SIG_SFWINK: 05708 if (zt_wink(p, index)) 05709 return NULL; 05710 /* Fall through */ 05711 case SIG_EM: 05712 case SIG_EM_E1: 05713 case SIG_SF: 05714 case SIG_FGC_CAMA: 05715 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05716 if (p->dsp) 05717 ast_dsp_digitreset(p->dsp); 05718 /* set digit mode appropriately */ 05719 if (p->dsp) { 05720 if (NEED_MFDETECT(p)) 05721 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05722 else 05723 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05724 } 05725 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05726 /* Wait for the first digit only if immediate=no */ 05727 if (!p->immediate) 05728 /* Wait for the first digit (up to 5 seconds). */ 05729 res = ast_waitfordigit(chan, 5000); 05730 else 05731 res = 0; 05732 if (res > 0) { 05733 /* save first char */ 05734 dtmfbuf[0] = res; 05735 switch (p->sig) { 05736 case SIG_FEATD: 05737 case SIG_SF_FEATD: 05738 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05739 if (res > 0) 05740 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05741 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05742 break; 05743 case SIG_FEATDMF_TA: 05744 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05745 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05746 if (zt_wink(p, index)) return NULL; 05747 dtmfbuf[0] = 0; 05748 /* Wait for the first digit (up to 5 seconds). */ 05749 res = ast_waitfordigit(chan, 5000); 05750 if (res <= 0) break; 05751 dtmfbuf[0] = res; 05752 /* fall through intentionally */ 05753 case SIG_FEATDMF: 05754 case SIG_E911: 05755 case SIG_FGC_CAMAMF: 05756 case SIG_SF_FEATDMF: 05757 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05758 /* if international caca, do it again to get real ANO */ 05759 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05760 { 05761 if (zt_wink(p, index)) return NULL; 05762 dtmfbuf[0] = 0; 05763 /* Wait for the first digit (up to 5 seconds). */ 05764 res = ast_waitfordigit(chan, 5000); 05765 if (res <= 0) break; 05766 dtmfbuf[0] = res; 05767 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05768 } 05769 if (res > 0) { 05770 /* if E911, take off hook */ 05771 if (p->sig == SIG_E911) 05772 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05773 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05774 } 05775 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05776 break; 05777 case SIG_FEATB: 05778 case SIG_SF_FEATB: 05779 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05780 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05781 break; 05782 case SIG_EMWINK: 05783 /* if we received a '*', we are actually receiving Feature Group D 05784 dial syntax, so use that mode; otherwise, fall through to normal 05785 mode 05786 */ 05787 if (res == '*') { 05788 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05789 if (res > 0) 05790 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05791 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05792 break; 05793 } 05794 default: 05795 /* If we got the first digit, get the rest */ 05796 len = 1; 05797 dtmfbuf[len] = '\0'; 05798 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05799 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05800 timeout = matchdigittimeout; 05801 } else { 05802 timeout = gendigittimeout; 05803 } 05804 res = ast_waitfordigit(chan, timeout); 05805 if (res < 0) { 05806 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05807 ast_hangup(chan); 05808 return NULL; 05809 } else if (res) { 05810 dtmfbuf[len++] = res; 05811 dtmfbuf[len] = '\0'; 05812 } else { 05813 break; 05814 } 05815 } 05816 break; 05817 } 05818 } 05819 if (res == -1) { 05820 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05821 ast_hangup(chan); 05822 return NULL; 05823 } else if (res < 0) { 05824 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05825 ast_hangup(chan); 05826 return NULL; 05827 } 05828 05829 if (p->sig == SIG_FGC_CAMA) { 05830 char anibuf[100]; 05831 05832 if (ast_safe_sleep(chan,1000) == -1) { 05833 ast_hangup(chan); 05834 return NULL; 05835 } 05836 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05837 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05838 res = my_getsigstr(chan, anibuf, "#", 10000); 05839 if ((res > 0) && (strlen(anibuf) > 2)) { 05840 if (anibuf[strlen(anibuf) - 1] == '#') 05841 anibuf[strlen(anibuf) - 1] = 0; 05842 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05843 } 05844 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05845 } 05846 05847 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05848 if (ast_strlen_zero(exten)) 05849 ast_copy_string(exten, "s", sizeof(exten)); 05850 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05851 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05852 if (exten[0] == '*') { 05853 char *stringp=NULL; 05854 ast_copy_string(exten2, exten, sizeof(exten2)); 05855 /* Parse out extension and callerid */ 05856 stringp=exten2 +1; 05857 s1 = strsep(&stringp, "*"); 05858 s2 = strsep(&stringp, "*"); 05859 if (s2) { 05860 if (!ast_strlen_zero(p->cid_num)) 05861 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05862 else 05863 ast_set_callerid(chan, s1, NULL, s1); 05864 ast_copy_string(exten, s2, sizeof(exten)); 05865 } else 05866 ast_copy_string(exten, s1, sizeof(exten)); 05867 } else if (p->sig == SIG_FEATD) 05868 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05869 } 05870 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05871 if (exten[0] == '*') { 05872 char *stringp=NULL; 05873 ast_copy_string(exten2, exten, sizeof(exten2)); 05874 /* Parse out extension and callerid */ 05875 stringp=exten2 +1; 05876 s1 = strsep(&stringp, "#"); 05877 s2 = strsep(&stringp, "#"); 05878 if (s2) { 05879 if (!ast_strlen_zero(p->cid_num)) 05880 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05881 else 05882 if (*(s1 + 2)) 05883 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05884 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05885 } else 05886 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05887 } else 05888 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05889 } 05890 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05891 if (exten[0] == '*') { 05892 char *stringp=NULL; 05893 ast_copy_string(exten2, exten, sizeof(exten2)); 05894 /* Parse out extension and callerid */ 05895 stringp=exten2 +1; 05896 s1 = strsep(&stringp, "#"); 05897 s2 = strsep(&stringp, "#"); 05898 if (s2 && (*(s2 + 1) == '0')) { 05899 if (*(s2 + 2)) 05900 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05901 } 05902 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05903 else ast_copy_string(exten, "911", sizeof(exten)); 05904 } else 05905 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 05906 } 05907 if (p->sig == SIG_FEATB) { 05908 if (exten[0] == '*') { 05909 char *stringp=NULL; 05910 ast_copy_string(exten2, exten, sizeof(exten2)); 05911 /* Parse out extension and callerid */ 05912 stringp=exten2 +1; 05913 s1 = strsep(&stringp, "#"); 05914 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05915 } else 05916 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05917 } 05918 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05919 zt_wink(p, index); 05920 /* some switches require a minimum guard time between 05921 the last FGD wink and something that answers 05922 immediately. This ensures it */ 05923 if (ast_safe_sleep(chan,100)) return NULL; 05924 } 05925 zt_enable_ec(p); 05926 if (NEED_MFDETECT(p)) { 05927 if (p->dsp) { 05928 if (!p->hardwaredtmf) 05929 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05930 else { 05931 ast_dsp_free(p->dsp); 05932 p->dsp = NULL; 05933 } 05934 } 05935 } 05936 05937 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05938 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05939 if (p->dsp) ast_dsp_digitreset(p->dsp); 05940 res = ast_pbx_run(chan); 05941 if (res) { 05942 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05943 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05944 } 05945 return NULL; 05946 } else { 05947 if (option_verbose > 2) 05948 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05949 sleep(2); 05950 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05951 if (res < 0) 05952 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05953 else 05954 sleep(1); 05955 res = ast_streamfile(chan, "ss-noservice", chan->language); 05956 if (res >= 0) 05957 ast_waitstream(chan, ""); 05958 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05959 ast_hangup(chan); 05960 return NULL; 05961 } 05962 break; 05963 case SIG_FXOLS: 05964 case SIG_FXOGS: 05965 case SIG_FXOKS: 05966 /* Read the first digit */ 05967 timeout = firstdigittimeout; 05968 /* If starting a threeway call, never timeout on the first digit so someone 05969 can use flash-hook as a "hold" feature */ 05970 if (p->subs[SUB_THREEWAY].owner) 05971 timeout = 999999; 05972 while (len < AST_MAX_EXTENSION-1) { 05973 /* Read digit unless it's supposed to be immediate, in which case the 05974 only answer is 's' */ 05975 if (p->immediate) 05976 res = 's'; 05977 else 05978 res = ast_waitfordigit(chan, timeout); 05979 timeout = 0; 05980 if (res < 0) { 05981 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05982 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05983 ast_hangup(chan); 05984 return NULL; 05985 } else if (res) { 05986 exten[len++]=res; 05987 exten[len] = '\0'; 05988 } 05989 if (!ast_ignore_pattern(chan->context, exten)) 05990 tone_zone_play_tone(p->subs[index].zfd, -1); 05991 else 05992 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05993 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05994 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05995 if (getforward) { 05996 /* Record this as the forwarding extension */ 05997 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05998 if (option_verbose > 2) 05999 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 06000 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06001 if (res) 06002 break; 06003 usleep(500000); 06004 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06005 sleep(1); 06006 memset(exten, 0, sizeof(exten)); 06007 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 06008 len = 0; 06009 getforward = 0; 06010 } else { 06011 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06012 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06013 if (!ast_strlen_zero(p->cid_num)) { 06014 if (!p->hidecallerid) 06015 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 06016 else 06017 ast_set_callerid(chan, NULL, NULL, p->cid_num); 06018 } 06019 if (!ast_strlen_zero(p->cid_name)) { 06020 if (!p->hidecallerid) 06021 ast_set_callerid(chan, NULL, p->cid_name, NULL); 06022 } 06023 ast_setstate(chan, AST_STATE_RING); 06024 zt_enable_ec(p); 06025 res = ast_pbx_run(chan); 06026 if (res) { 06027 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06028 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06029 } 06030 return NULL; 06031 } 06032 } else { 06033 /* It's a match, but they just typed a digit, and there is an ambiguous match, 06034 so just set the timeout to matchdigittimeout and wait some more */ 06035 timeout = matchdigittimeout; 06036 } 06037 } else if (res == 0) { 06038 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 06039 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06040 zt_wait_event(p->subs[index].zfd); 06041 ast_hangup(chan); 06042 return NULL; 06043 } else if (p->callwaiting && !strcmp(exten, "*70")) { 06044 if (option_verbose > 2) 06045 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 06046 /* Disable call waiting if enabled */ 06047 p->callwaiting = 0; 06048 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06049 if (res) { 06050 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06051 chan->name, strerror(errno)); 06052 } 06053 len = 0; 06054 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 06055 memset(exten, 0, sizeof(exten)); 06056 timeout = firstdigittimeout; 06057 06058 } else if (!strcmp(exten,ast_pickup_ext())) { 06059 /* Scan all channels and see if there are any 06060 * ringing channels that have call groups 06061 * that equal this channels pickup group 06062 */ 06063 if (index == SUB_REAL) { 06064 /* Switch us from Third call to Call Wait */ 06065 if (p->subs[SUB_THREEWAY].owner) { 06066 /* If you make a threeway call and the *8# a call, it should actually 06067 look like a callwait */ 06068 alloc_sub(p, SUB_CALLWAIT); 06069 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06070 unalloc_sub(p, SUB_THREEWAY); 06071 } 06072 zt_enable_ec(p); 06073 if (ast_pickup_call(chan)) { 06074 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 06075 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06076 zt_wait_event(p->subs[index].zfd); 06077 } 06078 ast_hangup(chan); 06079 return NULL; 06080 } else { 06081 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 06082 ast_hangup(chan); 06083 return NULL; 06084 } 06085 06086 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 06087 if (option_verbose > 2) 06088 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 06089 /* Disable Caller*ID if enabled */ 06090 p->hidecallerid = 1; 06091 if (chan->cid.cid_num) 06092 free(chan->cid.cid_num); 06093 chan->cid.cid_num = NULL; 06094 if (chan->cid.cid_name) 06095 free(chan->cid.cid_name); 06096 chan->cid.cid_name = NULL; 06097 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06098 if (res) { 06099 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06100 chan->name, strerror(errno)); 06101 } 06102 len = 0; 06103 memset(exten, 0, sizeof(exten)); 06104 timeout = firstdigittimeout; 06105 } else if (p->callreturn && !strcmp(exten, "*69")) { 06106 res = 0; 06107 if (!ast_strlen_zero(p->lastcid_num)) { 06108 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 06109 } 06110 if (!res) 06111 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06112 break; 06113 } else if (!strcmp(exten, "*78")) { 06114 /* Do not disturb */ 06115 if (option_verbose > 2) 06116 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 06117 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 06118 "Channel: Zap/%d\r\n" 06119 "Status: enabled\r\n", p->channel); 06120 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06121 p->dnd = 1; 06122 getforward = 0; 06123 memset(exten, 0, sizeof(exten)); 06124 len = 0; 06125 } else if (!strcmp(exten, "*79")) { 06126 /* Do not disturb */ 06127 if (option_verbose > 2) 06128 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 06129 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 06130 "Channel: Zap/%d\r\n" 06131 "Status: disabled\r\n", p->channel); 06132 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06133 p->dnd = 0; 06134 getforward = 0; 06135 memset(exten, 0, sizeof(exten)); 06136 len = 0; 06137 } else if (p->cancallforward && !strcmp(exten, "*72")) { 06138 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06139 getforward = 1; 06140 memset(exten, 0, sizeof(exten)); 06141 len = 0; 06142 } else if (p->cancallforward && !strcmp(exten, "*73")) { 06143 if (option_verbose > 2) 06144 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 06145 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06146 memset(p->call_forward, 0, sizeof(p->call_forward)); 06147 getforward = 0; 06148 memset(exten, 0, sizeof(exten)); 06149 len = 0; 06150 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 06151 p->subs[SUB_THREEWAY].owner && 06152 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06153 /* This is a three way call, the main call being a real channel, 06154 and we're parking the first call. */ 06155 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 06156 if (option_verbose > 2) 06157 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 06158 break; 06159 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 06160 if (option_verbose > 2) 06161 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 06162 res = ast_db_put("blacklist", p->lastcid_num, "1"); 06163 if (!res) { 06164 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06165 memset(exten, 0, sizeof(exten)); 06166 len = 0; 06167 } 06168 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 06169 if (option_verbose > 2) 06170 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 06171 /* Enable Caller*ID if enabled */ 06172 p->hidecallerid = 0; 06173 if (chan->cid.cid_num) 06174 free(chan->cid.cid_num); 06175 chan->cid.cid_num = NULL; 06176 if (chan->cid.cid_name) 06177 free(chan->cid.cid_name); 06178 chan->cid.cid_name = NULL; 06179 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 06180 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06181 if (res) { 06182 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06183 chan->name, strerror(errno)); 06184 } 06185 len = 0; 06186 memset(exten, 0, sizeof(exten)); 06187 timeout = firstdigittimeout; 06188 } else if (!strcmp(exten, "*0")) { 06189 struct ast_channel *nbridge = 06190 p->subs[SUB_THREEWAY].owner; 06191 struct zt_pvt *pbridge = NULL; 06192 /* set up the private struct of the bridged one, if any */ 06193 if (nbridge && ast_bridged_channel(nbridge)) 06194 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 06195 if (nbridge && pbridge && 06196 (nbridge->tech == &zap_tech) && 06197 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 06198 ISTRUNK(pbridge)) { 06199 int func = ZT_FLASH; 06200 /* Clear out the dial buffer */ 06201 p->dop.dialstr[0] = '\0'; 06202 /* flash hookswitch */ 06203 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 06204 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 06205 nbridge->name, strerror(errno)); 06206 } 06207 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06208 unalloc_sub(p, SUB_THREEWAY); 06209 p->owner = p->subs[SUB_REAL].owner; 06210 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06211 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06212 ast_hangup(chan); 06213 return NULL; 06214 } else { 06215 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06216 zt_wait_event(p->subs[index].zfd); 06217 tone_zone_play_tone(p->subs[index].zfd, -1); 06218 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06219 unalloc_sub(p, SUB_THREEWAY); 06220 p->owner = p->subs[SUB_REAL].owner; 06221 ast_hangup(chan); 06222 return NULL; 06223 } 06224 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06225 ((exten[0] != '*') || (strlen(exten) > 2))) { 06226 if (option_debug) 06227 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); 06228 break; 06229 } 06230 if (!timeout) 06231 timeout = gendigittimeout; 06232 if (len && !ast_ignore_pattern(chan->context, exten)) 06233 tone_zone_play_tone(p->subs[index].zfd, -1); 06234 } 06235 break; 06236 case SIG_FXSLS: 06237 case SIG_FXSGS: 06238 case SIG_FXSKS: 06239 #ifdef HAVE_PRI 06240 if (p->pri) { 06241 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06242 struct ast_frame *f; 06243 int res; 06244 time_t start; 06245 06246 time(&start); 06247 ast_setstate(chan, AST_STATE_RING); 06248 while (time(NULL) < start + 3) { 06249 res = ast_waitfor(chan, 1000); 06250 if (res) { 06251 f = ast_read(chan); 06252 if (!f) { 06253 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06254 ast_hangup(chan); 06255 return NULL; 06256 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06257 res = 1; 06258 } else 06259 res = 0; 06260 ast_frfree(f); 06261 if (res) { 06262 ast_log(LOG_DEBUG, "Got ring!\n"); 06263 res = 0; 06264 break; 06265 } 06266 } 06267 } 06268 } 06269 #endif 06270 /* check for SMDI messages */ 06271 if (p->use_smdi && p->smdi_iface) { 06272 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06273 06274 if (smdi_msg != NULL) { 06275 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06276 06277 if (smdi_msg->type == 'B') 06278 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06279 else if (smdi_msg->type == 'N') 06280 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06281 06282 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06283 } else { 06284 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06285 } 06286 } 06287 06288 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06289 number = smdi_msg->calling_st; 06290 06291 /* If we want caller id, we're in a prering state due to a polarity reversal 06292 * and we're set to use a polarity reversal to trigger the start of caller id, 06293 * grab the caller id and wait for ringing to start... */ 06294 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06295 /* If set to use DTMF CID signalling, listen for DTMF */ 06296 if (p->cid_signalling == CID_SIG_DTMF) { 06297 int i = 0; 06298 cs = NULL; 06299 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06300 "channel %s\n", chan->name); 06301 zt_setlinear(p->subs[index].zfd, 0); 06302 res = 2000; 06303 for (;;) { 06304 struct ast_frame *f; 06305 res = ast_waitfor(chan, res); 06306 if (res <= 0) { 06307 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06308 "Exiting simple switch\n"); 06309 ast_hangup(chan); 06310 return NULL; 06311 } 06312 f = ast_read(chan); 06313 if (!f) 06314 break; 06315 if (f->frametype == AST_FRAME_DTMF) { 06316 dtmfbuf[i++] = f->subclass; 06317 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06318 res = 2000; 06319 } 06320 ast_frfree(f); 06321 if (chan->_state == AST_STATE_RING || 06322 chan->_state == AST_STATE_RINGING) 06323 break; /* Got ring */ 06324 } 06325 dtmfbuf[i] = '\0'; 06326 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06327 /* Got cid and ring. */ 06328 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06329 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06330 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06331 dtmfcid, flags); 06332 /* If first byte is NULL, we have no cid */ 06333 if (!ast_strlen_zero(dtmfcid)) 06334 number = dtmfcid; 06335 else 06336 number = NULL; 06337 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06338 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06339 cs = callerid_new(p->cid_signalling); 06340 if (cs) { 06341 samples = 0; 06342 #if 1 06343 bump_gains(p); 06344 #endif 06345 /* Take out of linear mode for Caller*ID processing */ 06346 zt_setlinear(p->subs[index].zfd, 0); 06347 06348 /* First we wait and listen for the Caller*ID */ 06349 for (;;) { 06350 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06351 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06352 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06353 callerid_free(cs); 06354 ast_hangup(chan); 06355 return NULL; 06356 } 06357 if (i & ZT_IOMUX_SIGEVENT) { 06358 res = zt_get_event(p->subs[index].zfd); 06359 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06360 06361 if (p->cid_signalling == CID_SIG_V23_JP) { 06362 #ifdef ZT_EVENT_RINGBEGIN 06363 if (res == ZT_EVENT_RINGBEGIN) { 06364 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06365 usleep(1); 06366 } 06367 #endif 06368 } else { 06369 res = 0; 06370 break; 06371 } 06372 } else if (i & ZT_IOMUX_READ) { 06373 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06374 if (res < 0) { 06375 if (errno != ELAST) { 06376 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06377 callerid_free(cs); 06378 ast_hangup(chan); 06379 return NULL; 06380 } 06381 break; 06382 } 06383 samples += res; 06384 06385 if (p->cid_signalling == CID_SIG_V23_JP) { 06386 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06387 } else { 06388 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06389 } 06390 06391 if (res < 0) { 06392 ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name); 06393 break; 06394 } else if (res) 06395 break; 06396 else if (samples > (8000 * 10)) 06397 break; 06398 } 06399 } 06400 if (res == 1) { 06401 callerid_get(cs, &name, &number, &flags); 06402 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06403 } 06404 06405 if (p->cid_signalling == CID_SIG_V23_JP) { 06406 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06407 usleep(1); 06408 res = 4000; 06409 } else { 06410 06411 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06412 res = 2000; 06413 } 06414 06415 for (;;) { 06416 struct ast_frame *f; 06417 res = ast_waitfor(chan, res); 06418 if (res <= 0) { 06419 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06420 "Exiting simple switch\n"); 06421 ast_hangup(chan); 06422 return NULL; 06423 } 06424 f = ast_read(chan); 06425 ast_frfree(f); 06426 if (chan->_state == AST_STATE_RING || 06427 chan->_state == AST_STATE_RINGING) 06428 break; /* Got ring */ 06429 } 06430 06431 /* We must have a ring by now, so, if configured, lets try to listen for 06432 * distinctive ringing */ 06433 if (p->usedistinctiveringdetection == 1) { 06434 len = 0; 06435 distMatches = 0; 06436 /* Clear the current ring data array so we dont have old data in it. */ 06437 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06438 curRingData[receivedRingT] = 0; 06439 receivedRingT = 0; 06440 counter = 0; 06441 counter1 = 0; 06442 /* Check to see if context is what it should be, if not set to be. */ 06443 if (strcmp(p->context,p->defcontext) != 0) { 06444 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06445 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06446 } 06447 06448 for (;;) { 06449 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06450 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06451 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06452 callerid_free(cs); 06453 ast_hangup(chan); 06454 return NULL; 06455 } 06456 if (i & ZT_IOMUX_SIGEVENT) { 06457 res = zt_get_event(p->subs[index].zfd); 06458 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06459 res = 0; 06460 /* Let us detect distinctive ring */ 06461 06462 curRingData[receivedRingT] = p->ringt; 06463 06464 if (p->ringt < p->ringt_base/2) 06465 break; 06466 /* Increment the ringT counter so we can match it against 06467 values in zapata.conf for distinctive ring */ 06468 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06469 break; 06470 } else if (i & ZT_IOMUX_READ) { 06471 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06472 if (res < 0) { 06473 if (errno != ELAST) { 06474 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06475 callerid_free(cs); 06476 ast_hangup(chan); 06477 return NULL; 06478 } 06479 break; 06480 } 06481 if (p->ringt) 06482 p->ringt--; 06483 if (p->ringt == 1) { 06484 res = -1; 06485 break; 06486 } 06487 } 06488 } 06489 if (option_verbose > 2) 06490 /* this only shows up if you have n of the dring patterns filled in */ 06491 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06492 06493 for (counter = 0; counter < 3; counter++) { 06494 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06495 channel */ 06496 distMatches = 0; 06497 for (counter1 = 0; counter1 < 3; counter1++) { 06498 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06499 (p->drings.ringnum[counter].ring[counter1]-10)) { 06500 distMatches++; 06501 } 06502 } 06503 if (distMatches == 3) { 06504 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06505 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06506 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06507 if (option_verbose > 2) 06508 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06509 break; 06510 } 06511 } 06512 } 06513 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06514 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06515 #if 1 06516 restore_gains(p); 06517 #endif 06518 } else 06519 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06520 } else { 06521 ast_log(LOG_WARNING, "Channel %s in prering " 06522 "state, but I have nothing to do. " 06523 "Terminating simple switch, should be " 06524 "restarted by the actual ring.\n", 06525 chan->name); 06526 ast_hangup(chan); 06527 return NULL; 06528 } 06529 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06530 /* FSK Bell202 callerID */ 06531 cs = callerid_new(p->cid_signalling); 06532 if (cs) { 06533 #if 1 06534 bump_gains(p); 06535 #endif 06536 samples = 0; 06537 len = 0; 06538 distMatches = 0; 06539 /* Clear the current ring data array so we dont have old data in it. */ 06540 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06541 curRingData[receivedRingT] = 0; 06542 receivedRingT = 0; 06543 counter = 0; 06544 counter1 = 0; 06545 /* Check to see if context is what it should be, if not set to be. */ 06546 if (strcmp(p->context,p->defcontext) != 0) { 06547 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06548 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06549 } 06550 06551 /* Take out of linear mode for Caller*ID processing */ 06552 zt_setlinear(p->subs[index].zfd, 0); 06553 for (;;) { 06554 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06555 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06556 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06557 callerid_free(cs); 06558 ast_hangup(chan); 06559 return NULL; 06560 } 06561 if (i & ZT_IOMUX_SIGEVENT) { 06562 res = zt_get_event(p->subs[index].zfd); 06563 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06564 /* If we get a PR event, they hung up while processing calerid */ 06565 if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 06566 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 06567 p->polarity = POLARITY_IDLE; 06568 callerid_free(cs); 06569 ast_hangup(chan); 06570 return NULL; 06571 } 06572 res = 0; 06573 /* Let us detect callerid when the telco uses distinctive ring */ 06574 06575 curRingData[receivedRingT] = p->ringt; 06576 06577 if (p->ringt < p->ringt_base/2) 06578 break; 06579 /* Increment the ringT counter so we can match it against 06580 values in zapata.conf for distinctive ring */ 06581 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06582 break; 06583 } else if (i & ZT_IOMUX_READ) { 06584 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06585 if (res < 0) { 06586 if (errno != ELAST) { 06587 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06588 callerid_free(cs); 06589 ast_hangup(chan); 06590 return NULL; 06591 } 06592 break; 06593 } 06594 if (p->ringt) 06595 p->ringt--; 06596 if (p->ringt == 1) { 06597 res = -1; 06598 break; 06599 } 06600 samples += res; 06601 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06602 if (res < 0) { 06603 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06604 break; 06605 } else if (res) 06606 break; 06607 else if (samples > (8000 * 10)) 06608 break; 06609 } 06610 } 06611 if (res == 1) { 06612 callerid_get(cs, &name, &number, &flags); 06613 if (option_debug) 06614 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06615 } 06616 if (distinctiveringaftercid == 1) { 06617 /* Clear the current ring data array so we dont have old data in it. */ 06618 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06619 curRingData[receivedRingT] = 0; 06620 } 06621 receivedRingT = 0; 06622 if (option_verbose > 2) 06623 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06624 for (;;) { 06625 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06626 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06627 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06628 callerid_free(cs); 06629 ast_hangup(chan); 06630 return NULL; 06631 } 06632 if (i & ZT_IOMUX_SIGEVENT) { 06633 res = zt_get_event(p->subs[index].zfd); 06634 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06635 res = 0; 06636 /* Let us detect callerid when the telco uses distinctive ring */ 06637 06638 curRingData[receivedRingT] = p->ringt; 06639 06640 if (p->ringt < p->ringt_base/2) 06641 break; 06642 /* Increment the ringT counter so we can match it against 06643 values in zapata.conf for distinctive ring */ 06644 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06645 break; 06646 } else if (i & ZT_IOMUX_READ) { 06647 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06648 if (res < 0) { 06649 if (errno != ELAST) { 06650 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06651 callerid_free(cs); 06652 ast_hangup(chan); 06653 return NULL; 06654 } 06655 break; 06656 } 06657 if (p->ringt) 06658 p->ringt--; 06659 if (p->ringt == 1) { 06660 res = -1; 06661 break; 06662 } 06663 } 06664 } 06665 } 06666 if (p->usedistinctiveringdetection == 1) { 06667 if (option_verbose > 2) 06668 /* this only shows up if you have n of the dring patterns filled in */ 06669 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06670 06671 for (counter = 0; counter < 3; counter++) { 06672 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06673 channel */ 06674 if (option_verbose > 2) 06675 /* this only shows up if you have n of the dring patterns filled in */ 06676 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06677 p->drings.ringnum[counter].ring[0], 06678 p->drings.ringnum[counter].ring[1], 06679 p->drings.ringnum[counter].ring[2]); 06680 distMatches = 0; 06681 for (counter1 = 0; counter1 < 3; counter1++) { 06682 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06683 (p->drings.ringnum[counter].ring[counter1]-10)) { 06684 distMatches++; 06685 } 06686 } 06687 if (distMatches == 3) { 06688 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06689 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06690 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06691 if (option_verbose > 2) 06692 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06693 break; 06694 } 06695 } 06696 } 06697 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06698 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06699 #if 1 06700 restore_gains(p); 06701 #endif 06702 if (res < 0) { 06703 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06704 } 06705 } else 06706 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06707 } 06708 else 06709 cs = NULL; 06710 06711 if (number) 06712 ast_shrink_phone_number(number); 06713 ast_set_callerid(chan, number, name, number); 06714 06715 if (smdi_msg) 06716 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06717 06718 if (cs) 06719 callerid_free(cs); 06720 06721 ast_setstate(chan, AST_STATE_RING); 06722 chan->rings = 1; 06723 p->ringt = p->ringt_base; 06724 res = ast_pbx_run(chan); 06725 if (res) { 06726 ast_hangup(chan); 06727 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06728 } 06729 return NULL; 06730 default: 06731 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06732 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06733 if (res < 0) 06734 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06735 } 06736 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06737 if (res < 0) 06738 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06739 ast_hangup(chan); 06740 return NULL; 06741 }
static void swap_subs | ( | struct zt_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 897 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().
00898 { 00899 int tchan; 00900 int tinthreeway; 00901 struct ast_channel *towner; 00902 00903 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 00904 00905 tchan = p->subs[a].chan; 00906 towner = p->subs[a].owner; 00907 tinthreeway = p->subs[a].inthreeway; 00908 00909 p->subs[a].chan = p->subs[b].chan; 00910 p->subs[a].owner = p->subs[b].owner; 00911 p->subs[a].inthreeway = p->subs[b].inthreeway; 00912 00913 p->subs[b].chan = tchan; 00914 p->subs[b].owner = towner; 00915 p->subs[b].inthreeway = tinthreeway; 00916 00917 if (p->subs[a].owner) 00918 p->subs[a].owner->fds[0] = p->subs[a].zfd; 00919 if (p->subs[b].owner) 00920 p->subs[b].owner->fds[0] = p->subs[b].zfd; 00921 wakeup_sub(p, a, NULL); 00922 wakeup_sub(p, b, NULL); 00923 }
static int unalloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 1023 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().
01024 { 01025 if (!x) { 01026 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 01027 return -1; 01028 } 01029 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 01030 if (p->subs[x].zfd > -1) { 01031 zt_close(p->subs[x].zfd); 01032 } 01033 p->subs[x].zfd = -1; 01034 p->subs[x].linear = 0; 01035 p->subs[x].chan = 0; 01036 p->subs[x].owner = NULL; 01037 p->subs[x].inthreeway = 0; 01038 p->polarity = POLARITY_IDLE; 01039 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 01040 return 0; 01041 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11810 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
11811 { 11812 #ifdef HAVE_PRI 11813 int y; 11814 for (y = 0; y < NUM_SPANS; y++) 11815 ast_mutex_destroy(&pris[y].lock); 11816 #endif 11817 return __unload_module(); 11818 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1411 of file chan_zap.c.
References ast_log(), zt_pvt::channel, conf_add(), conf_del(), zt_pvt::confno, GET_CHANNEL, zt_pvt::inconference, zt_subchannel::inthreeway, isslavenative(), LOG_DEBUG, zt_pvt::master, MAX_SLAVES, option_debug, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), mkintf(), zt_bridge(), zt_fixup(), zt_handle_event(), zt_hangup(), and zt_unlink().
01412 { 01413 int needconf = 0; 01414 int x; 01415 int useslavenative; 01416 struct zt_pvt *slave = NULL; 01417 01418 useslavenative = isslavenative(p, &slave); 01419 /* Start with the obvious, general stuff */ 01420 for (x = 0; x < 3; x++) { 01421 /* Look for three way calls */ 01422 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01423 conf_add(p, &p->subs[x], x, 0); 01424 needconf++; 01425 } else { 01426 conf_del(p, &p->subs[x], x); 01427 } 01428 } 01429 /* If we have a slave, add him to our conference now. or DAX 01430 if this is slave native */ 01431 for (x = 0; x < MAX_SLAVES; x++) { 01432 if (p->slaves[x]) { 01433 if (useslavenative) 01434 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01435 else { 01436 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01437 needconf++; 01438 } 01439 } 01440 } 01441 /* If we're supposed to be in there, do so now */ 01442 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01443 if (useslavenative) 01444 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01445 else { 01446 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01447 needconf++; 01448 } 01449 } 01450 /* If we have a master, add ourselves to his conference */ 01451 if (p->master) { 01452 if (isslavenative(p->master, NULL)) { 01453 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01454 } else { 01455 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01456 } 01457 } 01458 if (!needconf) { 01459 /* Nobody is left (or should be left) in our conference. 01460 Kill it. */ 01461 p->confno = -1; 01462 } 01463 if (option_debug) 01464 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01465 return 0; 01466 }
static void wakeup_sub | ( | struct zt_pvt * | p, | |
int | a, | |||
void * | pri | |||
) | [static] |
Definition at line 841 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), DEADLOCK_AVOIDANCE, zt_pvt::lock, ast_channel::lock, zt_subchannel::owner, and zt_pvt::subs.
Referenced by swap_subs().
00843 { 00844 #ifdef HAVE_PRI 00845 if (pri) 00846 ast_mutex_unlock(&pri->lock); 00847 #endif 00848 for (;;) { 00849 if (p->subs[a].owner) { 00850 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00851 DEADLOCK_AVOIDANCE(&p->lock); 00852 } else { 00853 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 00854 ast_mutex_unlock(&p->subs[a].owner->lock); 00855 break; 00856 } 00857 } else 00858 break; 00859 } 00860 #ifdef HAVE_PRI 00861 if (pri) 00862 ast_mutex_lock(&pri->lock); 00863 #endif 00864 }
static int zap_destroy_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11162 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
11163 { 11164 int channel; 11165 11166 if (argc != 4) 11167 return RESULT_SHOWUSAGE; 11168 11169 channel = atoi(argv[3]); 11170 11171 return zap_destroy_channel_bynum(channel); 11172 }
static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6744 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().
06745 { 06746 struct zt_pvt *tmp = NULL; 06747 struct zt_pvt *prev = NULL; 06748 06749 tmp = iflist; 06750 while (tmp) { 06751 if (tmp->channel == channel) { 06752 destroy_channel(prev, tmp, 1); 06753 return RESULT_SUCCESS; 06754 } 06755 prev = tmp; 06756 tmp = tmp->next; 06757 } 06758 return RESULT_FAILURE; 06759 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 11550 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, LOG_WARNING, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
11551 { 11552 if (p) { 11553 switch (mode) { 11554 case TRANSFER: 11555 p->fake_event = ZT_EVENT_WINKFLASH; 11556 break; 11557 case HANGUP: 11558 p->fake_event = ZT_EVENT_ONHOOK; 11559 break; 11560 default: 11561 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 11562 } 11563 } 11564 return 0; 11565 }
Definition at line 869 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.
Referenced by action_zapdialoffhook().
00871 { 00872 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00873 #ifdef HAVE_PRI 00874 if (pri) 00875 ast_mutex_unlock(&pri->lock); 00876 #endif 00877 for (;;) { 00878 if (p->owner) { 00879 if (ast_mutex_trylock(&p->owner->lock)) { 00880 DEADLOCK_AVOIDANCE(&p->lock); 00881 } else { 00882 ast_queue_frame(p->owner, f); 00883 ast_mutex_unlock(&p->owner->lock); 00884 break; 00885 } 00886 } else 00887 break; 00888 } 00889 #ifdef HAVE_PRI 00890 if (pri) 00891 ast_mutex_lock(&pri->lock); 00892 #endif 00893 }
static int zap_restart | ( | void | ) | [static] |
Definition at line 11175 of file chan_zap.c.
References ast_log(), ast_verbose(), destroy_channel(), iflist, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.
Referenced by action_zaprestart(), and zap_restart_cmd().
11176 { 11177 if (option_verbose > 0) 11178 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 11179 while (iflist) { 11180 if (option_debug) 11181 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 11182 /* Also updates iflist: */ 11183 destroy_channel(NULL, iflist, 1); 11184 } 11185 if (option_debug) 11186 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 11187 if (setup_zap(0) != 0) { 11188 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 11189 return 1; 11190 } 11191 return 0; 11192 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11194 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
11195 { 11196 if (argc != 2) { 11197 return RESULT_SHOWUSAGE; 11198 } 11199 11200 if (zap_restart() != 0) 11201 return RESULT_FAILURE; 11202 return RESULT_SUCCESS; 11203 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11276 of file chan_zap.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::callwaitcas, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::destroy, zt_pvt::dialing, zt_pvt::dsp, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::exten, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, lock, LOG_WARNING, zt_pvt::master, MAX_SLAVES, 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_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
11277 { 11278 int channel; 11279 struct zt_pvt *tmp = NULL; 11280 ZT_CONFINFO ci; 11281 ZT_PARAMS ps; 11282 int x; 11283 ast_mutex_t *lock; 11284 struct zt_pvt *start; 11285 #ifdef HAVE_PRI 11286 char *c; 11287 int trunkgroup; 11288 struct zt_pri *pri=NULL; 11289 #endif 11290 11291 lock = &iflock; 11292 start = iflist; 11293 11294 if (argc != 4) 11295 return RESULT_SHOWUSAGE; 11296 #ifdef HAVE_PRI 11297 if ((c = strchr(argv[3], ':'))) { 11298 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 11299 return RESULT_SHOWUSAGE; 11300 if ((trunkgroup < 1) || (channel < 1)) 11301 return RESULT_SHOWUSAGE; 11302 for (x = 0; x < NUM_SPANS; x++) { 11303 if (pris[x].trunkgroup == trunkgroup) { 11304 pri = pris + x; 11305 break; 11306 } 11307 } 11308 if (pri) { 11309 start = pri->crvs; 11310 lock = &pri->lock; 11311 } else { 11312 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 11313 return RESULT_FAILURE; 11314 } 11315 } else 11316 #endif 11317 channel = atoi(argv[3]); 11318 11319 ast_mutex_lock(lock); 11320 tmp = start; 11321 while (tmp) { 11322 if (tmp->channel == channel) { 11323 #ifdef HAVE_PRI 11324 if (pri) 11325 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 11326 else 11327 #endif 11328 ast_cli(fd, "Channel: %d\n", tmp->channel); 11329 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 11330 ast_cli(fd, "Span: %d\n", tmp->span); 11331 ast_cli(fd, "Extension: %s\n", tmp->exten); 11332 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 11333 ast_cli(fd, "Context: %s\n", tmp->context); 11334 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 11335 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 11336 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 11337 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 11338 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 11339 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 11340 ast_cli(fd, "Radio: %d\n", tmp->radio); 11341 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 11342 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)" : ""); 11343 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)" : ""); 11344 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)" : ""); 11345 ast_cli(fd, "Confno: %d\n", tmp->confno); 11346 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 11347 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 11348 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 11349 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 11350 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 11351 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 11352 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 11353 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 11354 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 11355 if (tmp->master) 11356 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 11357 for (x = 0; x < MAX_SLAVES; x++) { 11358 if (tmp->slaves[x]) 11359 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 11360 } 11361 #ifdef HAVE_PRI 11362 if (tmp->pri) { 11363 ast_cli(fd, "PRI Flags: "); 11364 if (tmp->resetting) 11365 ast_cli(fd, "Resetting "); 11366 if (tmp->call) 11367 ast_cli(fd, "Call "); 11368 if (tmp->bearer) 11369 ast_cli(fd, "Bearer "); 11370 ast_cli(fd, "\n"); 11371 if (tmp->logicalspan) 11372 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 11373 else 11374 ast_cli(fd, "PRI Logical Span: Implicit\n"); 11375 } 11376 11377 #endif 11378 memset(&ci, 0, sizeof(ci)); 11379 ps.channo = tmp->channel; 11380 if (tmp->subs[SUB_REAL].zfd > -1) { 11381 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 11382 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 11383 } 11384 #ifdef ZT_GETCONFMUTE 11385 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 11386 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 11387 } 11388 #endif 11389 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 11390 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 11391 } else { 11392 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 11393 } 11394 } 11395 ast_mutex_unlock(lock); 11396 return RESULT_SUCCESS; 11397 } 11398 tmp = tmp->next; 11399 } 11400 11401 ast_cli(fd, "Unable to find given channel %d\n", channel); 11402 ast_mutex_unlock(lock); 11403 return RESULT_FAILURE; 11404 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11215 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.
11216 { 11217 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 11218 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 11219 struct zt_pvt *tmp = NULL; 11220 char tmps[20] = ""; 11221 ast_mutex_t *lock; 11222 struct zt_pvt *start; 11223 #ifdef HAVE_PRI 11224 int trunkgroup; 11225 struct zt_pri *pri = NULL; 11226 int x; 11227 #endif 11228 11229 lock = &iflock; 11230 start = iflist; 11231 11232 #ifdef HAVE_PRI 11233 if (argc == 4) { 11234 if ((trunkgroup = atoi(argv[3])) < 1) 11235 return RESULT_SHOWUSAGE; 11236 for (x = 0; x < NUM_SPANS; x++) { 11237 if (pris[x].trunkgroup == trunkgroup) { 11238 pri = pris + x; 11239 break; 11240 } 11241 } 11242 if (pri) { 11243 start = pri->crvs; 11244 lock = &pri->lock; 11245 } else { 11246 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 11247 return RESULT_FAILURE; 11248 } 11249 } else 11250 #endif 11251 if (argc != 3) 11252 return RESULT_SHOWUSAGE; 11253 11254 ast_mutex_lock(lock); 11255 #ifdef HAVE_PRI 11256 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 11257 #else 11258 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 11259 #endif 11260 11261 tmp = start; 11262 while (tmp) { 11263 if (tmp->channel > 0) { 11264 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 11265 } else 11266 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 11267 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 11268 tmp = tmp->next; 11269 } 11270 ast_mutex_unlock(lock); 11271 return RESULT_SUCCESS; 11272 #undef FORMAT 11273 #undef FORMAT2 11274 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11437 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), errno, FORMAT, FORMAT2, LOG_WARNING, RESULT_FAILURE, and RESULT_SUCCESS.
11437 { 11438 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 11439 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 11440 11441 int span; 11442 int res; 11443 char alarms[50]; 11444 11445 int ctl; 11446 ZT_SPANINFO s; 11447 11448 ctl = open("/dev/zap/ctl", O_RDWR); 11449 if (ctl < 0) { 11450 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 11451 ast_cli(fd, "No Zaptel interface found.\n"); 11452 return RESULT_FAILURE; 11453 } 11454 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 11455 11456 for (span = 1; span < ZT_MAX_SPANS; ++span) { 11457 s.spanno = span; 11458 res = ioctl(ctl, ZT_SPANSTAT, &s); 11459 if (res) { 11460 continue; 11461 } 11462 alarms[0] = '\0'; 11463 if (s.alarms > 0) { 11464 if (s.alarms & ZT_ALARM_BLUE) 11465 strcat(alarms, "BLU/"); 11466 if (s.alarms & ZT_ALARM_YELLOW) 11467 strcat(alarms, "YEL/"); 11468 if (s.alarms & ZT_ALARM_RED) 11469 strcat(alarms, "RED/"); 11470 if (s.alarms & ZT_ALARM_LOOPBACK) 11471 strcat(alarms, "LB/"); 11472 if (s.alarms & ZT_ALARM_RECOVER) 11473 strcat(alarms, "REC/"); 11474 if (s.alarms & ZT_ALARM_NOTOPEN) 11475 strcat(alarms, "NOP/"); 11476 if (!strlen(alarms)) 11477 strcat(alarms, "UUU/"); 11478 if (strlen(alarms)) { 11479 /* Strip trailing / */ 11480 alarms[strlen(alarms) - 1] = '\0'; 11481 } 11482 } else { 11483 if (s.numchans) 11484 strcpy(alarms, "OK"); 11485 else 11486 strcpy(alarms, "UNCONFIGURED"); 11487 } 11488 11489 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 11490 } 11491 close(ctl); 11492 11493 return RESULT_SUCCESS; 11494 #undef FORMAT 11495 #undef FORMAT2 11496 }
static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1219 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_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01220 { 01221 static char buf[256]; 01222 switch (sig) { 01223 case SIG_EM: 01224 return "E & M Immediate"; 01225 case SIG_EMWINK: 01226 return "E & M Wink"; 01227 case SIG_EM_E1: 01228 return "E & M E1"; 01229 case SIG_FEATD: 01230 return "Feature Group D (DTMF)"; 01231 case SIG_FEATDMF: 01232 return "Feature Group D (MF)"; 01233 case SIG_FEATDMF_TA: 01234 return "Feature Groud D (MF) Tandem Access"; 01235 case SIG_FEATB: 01236 return "Feature Group B (MF)"; 01237 case SIG_E911: 01238 return "E911 (MF)"; 01239 case SIG_FGC_CAMA: 01240 return "FGC/CAMA (Dialpulse)"; 01241 case SIG_FGC_CAMAMF: 01242 return "FGC/CAMA (MF)"; 01243 case SIG_FXSLS: 01244 return "FXS Loopstart"; 01245 case SIG_FXSGS: 01246 return "FXS Groundstart"; 01247 case SIG_FXSKS: 01248 return "FXS Kewlstart"; 01249 case SIG_FXOLS: 01250 return "FXO Loopstart"; 01251 case SIG_FXOGS: 01252 return "FXO Groundstart"; 01253 case SIG_FXOKS: 01254 return "FXO Kewlstart"; 01255 case SIG_PRI: 01256 return "ISDN PRI"; 01257 case SIG_SF: 01258 return "SF (Tone) Immediate"; 01259 case SIG_SFWINK: 01260 return "SF (Tone) Wink"; 01261 case SIG_SF_FEATD: 01262 return "SF (Tone) with Feature Group D (DTMF)"; 01263 case SIG_SF_FEATDMF: 01264 return "SF (Tone) with Feature Group D (MF)"; 01265 case SIG_SF_FEATB: 01266 return "SF (Tone) with Feature Group B (MF)"; 01267 case SIG_GR303FXOKS: 01268 return "GR-303 with FXOKS"; 01269 case SIG_GR303FXSKS: 01270 return "GR-303 with FXSKS"; 01271 case SIG_GSM: 01272 return "GSM"; 01273 case 0: 01274 return "Pseudo"; 01275 default: 01276 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01277 return buf; 01278 } 01279 }
static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2876 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, enable_dtmf_detect(), 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_GSM, 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().
02877 { 02878 struct zt_pvt *p = ast->tech_pvt; 02879 int res = 0; 02880 int index; 02881 int oldstate = ast->_state; 02882 ast_setstate(ast, AST_STATE_UP); 02883 ast_mutex_lock(&p->lock); 02884 index = zt_get_index(ast, p, 0); 02885 if (index < 0) 02886 index = SUB_REAL; 02887 /* nothing to do if a radio channel */ 02888 if ((p->radio || (p->oprmode < 0))) { 02889 ast_mutex_unlock(&p->lock); 02890 return 0; 02891 } 02892 switch (p->sig) { 02893 case SIG_FXSLS: 02894 case SIG_FXSGS: 02895 case SIG_FXSKS: 02896 p->ringt = 0; 02897 /* Fall through */ 02898 case SIG_EM: 02899 case SIG_EM_E1: 02900 case SIG_EMWINK: 02901 case SIG_FEATD: 02902 case SIG_FEATDMF: 02903 case SIG_FEATDMF_TA: 02904 case SIG_E911: 02905 case SIG_FGC_CAMA: 02906 case SIG_FGC_CAMAMF: 02907 case SIG_FEATB: 02908 case SIG_SF: 02909 case SIG_SFWINK: 02910 case SIG_SF_FEATD: 02911 case SIG_SF_FEATDMF: 02912 case SIG_SF_FEATB: 02913 case SIG_FXOLS: 02914 case SIG_FXOGS: 02915 case SIG_FXOKS: 02916 /* Pick up the line */ 02917 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02918 if (p->hanguponpolarityswitch) { 02919 gettimeofday(&p->polaritydelaytv, NULL); 02920 } 02921 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02922 tone_zone_play_tone(p->subs[index].zfd, -1); 02923 p->dialing = 0; 02924 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02925 if (oldstate == AST_STATE_RINGING) { 02926 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02927 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02928 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02929 p->owner = p->subs[SUB_REAL].owner; 02930 } 02931 } 02932 if (p->sig & __ZT_SIG_FXS) { 02933 zt_enable_ec(p); 02934 zt_train_ec(p); 02935 } 02936 break; 02937 #ifdef HAVE_PRI 02938 case SIG_PRI: 02939 /* Send a pri acknowledge */ 02940 if (!pri_grab(p, p->pri)) { 02941 p->proceeding = 1; 02942 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02943 pri_rel(p->pri); 02944 /* stop ignoring inband dtmf */ 02945 enable_dtmf_detect(p); 02946 } else { 02947 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02948 res = -1; 02949 } 02950 /* the audio path is complete now, train the echo canceler */ 02951 zt_train_ec(p); 02952 break; 02953 #endif 02954 #ifdef HAVE_GSMAT 02955 case SIG_GSM: 02956 if (p->gsm.modul) { 02957 gsm_answer(p->gsm.modul); 02958 } 02959 break; 02960 #endif 02961 case 0: 02962 ast_mutex_unlock(&p->lock); 02963 return 0; 02964 default: 02965 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02966 res = -1; 02967 } 02968 ast_mutex_unlock(&p->lock); 02969 return res; 02970 }
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 3294 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, DEADLOCK_AVOIDANCE, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), ast_channel::fds, ast_frame::frametype, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, master, 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().
03295 { 03296 struct ast_channel *who; 03297 struct zt_pvt *p0, *p1, *op0, *op1; 03298 struct zt_pvt *master = NULL, *slave = NULL; 03299 struct ast_frame *f; 03300 int inconf = 0; 03301 int nothingok = 1; 03302 int ofd0, ofd1; 03303 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03304 int os0 = -1, os1 = -1; 03305 int priority = 0; 03306 struct ast_channel *oc0, *oc1; 03307 enum ast_bridge_result res; 03308 03309 #ifdef PRI_2BCT 03310 int triedtopribridge = 0; 03311 q931_call *q931c0 = NULL, *q931c1 = NULL; 03312 #endif 03313 03314 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03315 There is code below to handle it properly until DTMF is actually seen, 03316 but due to currently unresolved issues it's ignored... 03317 */ 03318 03319 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03320 return AST_BRIDGE_FAILED_NOWARN; 03321 03322 ast_mutex_lock(&c0->lock); 03323 while (ast_mutex_trylock(&c1->lock)) { 03324 DEADLOCK_AVOIDANCE(&c0->lock); 03325 } 03326 03327 p0 = c0->tech_pvt; 03328 p1 = c1->tech_pvt; 03329 /* cant do pseudo-channels here */ 03330 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03331 ast_mutex_unlock(&c0->lock); 03332 ast_mutex_unlock(&c1->lock); 03333 return AST_BRIDGE_FAILED_NOWARN; 03334 } 03335 03336 oi0 = zt_get_index(c0, p0, 0); 03337 oi1 = zt_get_index(c1, p1, 0); 03338 if ((oi0 < 0) || (oi1 < 0)) { 03339 ast_mutex_unlock(&c0->lock); 03340 ast_mutex_unlock(&c1->lock); 03341 return AST_BRIDGE_FAILED; 03342 } 03343 03344 op0 = p0 = c0->tech_pvt; 03345 op1 = p1 = c1->tech_pvt; 03346 ofd0 = c0->fds[0]; 03347 ofd1 = c1->fds[0]; 03348 oc0 = p0->owner; 03349 oc1 = p1->owner; 03350 03351 if (ast_mutex_trylock(&p0->lock)) { 03352 /* Don't block, due to potential for deadlock */ 03353 ast_mutex_unlock(&c0->lock); 03354 ast_mutex_unlock(&c1->lock); 03355 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03356 return AST_BRIDGE_RETRY; 03357 } 03358 if (ast_mutex_trylock(&p1->lock)) { 03359 /* Don't block, due to potential for deadlock */ 03360 ast_mutex_unlock(&p0->lock); 03361 ast_mutex_unlock(&c0->lock); 03362 ast_mutex_unlock(&c1->lock); 03363 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03364 return AST_BRIDGE_RETRY; 03365 } 03366 03367 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03368 if (p0->owner && p1->owner) { 03369 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03370 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03371 master = p0; 03372 slave = p1; 03373 inconf = 1; 03374 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03375 master = p1; 03376 slave = p0; 03377 inconf = 1; 03378 } else { 03379 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03380 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03381 p0->channel, 03382 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03383 p0->subs[SUB_REAL].inthreeway, p0->channel, 03384 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03385 p1->subs[SUB_REAL].inthreeway); 03386 } 03387 nothingok = 0; 03388 } 03389 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03390 if (p1->subs[SUB_THREEWAY].inthreeway) { 03391 master = p1; 03392 slave = p0; 03393 nothingok = 0; 03394 } 03395 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03396 if (p0->subs[SUB_THREEWAY].inthreeway) { 03397 master = p0; 03398 slave = p1; 03399 nothingok = 0; 03400 } 03401 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03402 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03403 don't put us in anything */ 03404 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03405 master = p1; 03406 slave = p0; 03407 nothingok = 0; 03408 } 03409 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03410 /* Same as previous */ 03411 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03412 master = p0; 03413 slave = p1; 03414 nothingok = 0; 03415 } 03416 } 03417 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03418 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03419 if (master && slave) { 03420 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03421 in an active threeway call with a channel that is ringing, we should 03422 indicate ringing. */ 03423 if ((oi1 == SUB_THREEWAY) && 03424 p1->subs[SUB_THREEWAY].inthreeway && 03425 p1->subs[SUB_REAL].owner && 03426 p1->subs[SUB_REAL].inthreeway && 03427 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03428 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03429 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03430 os1 = p1->subs[SUB_REAL].owner->_state; 03431 } else { 03432 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03433 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03434 } 03435 if ((oi0 == SUB_THREEWAY) && 03436 p0->subs[SUB_THREEWAY].inthreeway && 03437 p0->subs[SUB_REAL].owner && 03438 p0->subs[SUB_REAL].inthreeway && 03439 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03440 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03441 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03442 os0 = p0->subs[SUB_REAL].owner->_state; 03443 } else { 03444 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03445 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03446 } 03447 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03448 if (!p0->echocanbridged || !p1->echocanbridged) { 03449 /* Disable echo cancellation if appropriate */ 03450 zt_disable_ec(p0); 03451 zt_disable_ec(p1); 03452 } 03453 } 03454 zt_link(slave, master); 03455 master->inconference = inconf; 03456 } else if (!nothingok) 03457 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03458 03459 update_conf(p0); 03460 update_conf(p1); 03461 t0 = p0->subs[SUB_REAL].inthreeway; 03462 t1 = p1->subs[SUB_REAL].inthreeway; 03463 03464 ast_mutex_unlock(&p0->lock); 03465 ast_mutex_unlock(&p1->lock); 03466 03467 ast_mutex_unlock(&c0->lock); 03468 ast_mutex_unlock(&c1->lock); 03469 03470 /* Native bridge failed */ 03471 if ((!master || !slave) && !nothingok) { 03472 zt_enable_ec(p0); 03473 zt_enable_ec(p1); 03474 return AST_BRIDGE_FAILED; 03475 } 03476 03477 if (option_verbose > 2) 03478 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03479 03480 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03481 disable_dtmf_detect(op0); 03482 03483 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03484 disable_dtmf_detect(op1); 03485 03486 for (;;) { 03487 struct ast_channel *c0_priority[2] = {c0, c1}; 03488 struct ast_channel *c1_priority[2] = {c1, c0}; 03489 03490 /* Here's our main loop... Start by locking things, looking for private parts, 03491 and then balking if anything is wrong */ 03492 ast_mutex_lock(&c0->lock); 03493 while (ast_mutex_trylock(&c1->lock)) { 03494 DEADLOCK_AVOIDANCE(&c0->lock); 03495 } 03496 03497 p0 = c0->tech_pvt; 03498 p1 = c1->tech_pvt; 03499 03500 if (op0 == p0) 03501 i0 = zt_get_index(c0, p0, 1); 03502 if (op1 == p1) 03503 i1 = zt_get_index(c1, p1, 1); 03504 ast_mutex_unlock(&c0->lock); 03505 ast_mutex_unlock(&c1->lock); 03506 03507 if (!timeoutms || 03508 (op0 != p0) || 03509 (op1 != p1) || 03510 (ofd0 != c0->fds[0]) || 03511 (ofd1 != c1->fds[0]) || 03512 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03513 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03514 (oc0 != p0->owner) || 03515 (oc1 != p1->owner) || 03516 (t0 != p0->subs[SUB_REAL].inthreeway) || 03517 (t1 != p1->subs[SUB_REAL].inthreeway) || 03518 (oi0 != i0) || 03519 (oi1 != i1)) { 03520 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03521 op0->channel, oi0, op1->channel, oi1); 03522 res = AST_BRIDGE_RETRY; 03523 goto return_from_bridge; 03524 } 03525 03526 #ifdef PRI_2BCT 03527 q931c0 = p0->call; 03528 q931c1 = p1->call; 03529 if (p0->transfer && p1->transfer 03530 && q931c0 && q931c1 03531 && !triedtopribridge) { 03532 pri_channel_bridge(q931c0, q931c1); 03533 triedtopribridge = 1; 03534 } 03535 #endif 03536 03537 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03538 if (!who) { 03539 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03540 continue; 03541 } 03542 f = ast_read(who); 03543 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03544 *fo = f; 03545 *rc = who; 03546 res = AST_BRIDGE_COMPLETE; 03547 goto return_from_bridge; 03548 } 03549 if (f->frametype == AST_FRAME_DTMF) { 03550 if ((who == c0) && p0->pulsedial) { 03551 ast_write(c1, f); 03552 } else if ((who == c1) && p1->pulsedial) { 03553 ast_write(c0, f); 03554 } else { 03555 *fo = f; 03556 *rc = who; 03557 res = AST_BRIDGE_COMPLETE; 03558 goto return_from_bridge; 03559 } 03560 } 03561 ast_frfree(f); 03562 03563 /* Swap who gets priority */ 03564 priority = !priority; 03565 } 03566 03567 return_from_bridge: 03568 if (op0 == p0) 03569 zt_enable_ec(p0); 03570 03571 if (op1 == p1) 03572 zt_enable_ec(p1); 03573 03574 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03575 enable_dtmf_detect(op0); 03576 03577 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03578 enable_dtmf_detect(op1); 03579 03580 zt_unlink(slave, master, 1); 03581 03582 return res; 03583 }
static int zt_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 1835 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, disable_dtmf_detect(), zt_pvt::distinctivering, zt_pvt::dnid, 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, ast_channel::lowlayercompat, 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_GSM, 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().
01836 { 01837 struct zt_pvt *p = ast->tech_pvt; 01838 int x, res, index,mysig; 01839 char *c, *n, *l; 01840 #ifdef HAVE_PRI 01841 char *s = NULL; 01842 #endif 01843 char dest[256]; /* must be same length as p->dialdest */ 01844 ast_mutex_lock(&p->lock); 01845 ast_copy_string(dest, rdest, sizeof(dest)); 01846 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01847 if ((ast->_state == AST_STATE_BUSY)) { 01848 p->subs[SUB_REAL].needbusy = 1; 01849 ast_mutex_unlock(&p->lock); 01850 return 0; 01851 } 01852 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01853 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01854 ast_mutex_unlock(&p->lock); 01855 return -1; 01856 } 01857 p->dialednone = 0; 01858 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 01859 { 01860 /* Special pseudo -- automatically up */ 01861 ast_setstate(ast, AST_STATE_UP); 01862 ast_mutex_unlock(&p->lock); 01863 return 0; 01864 } 01865 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01866 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01867 if (res) 01868 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01869 p->outgoing = 1; 01870 01871 if (IS_DIGITAL(ast->transfercapability)) { 01872 set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law); 01873 } else { 01874 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01875 } 01876 01877 01878 mysig = p->sig; 01879 if (p->outsigmod > -1) 01880 mysig = p->outsigmod; 01881 01882 switch (mysig) { 01883 case SIG_FXOLS: 01884 case SIG_FXOGS: 01885 case SIG_FXOKS: 01886 if (p->owner == ast) { 01887 /* Normal ring, on hook */ 01888 01889 /* Don't send audio while on hook, until the call is answered */ 01890 p->dialing = 1; 01891 if (p->use_callerid) { 01892 /* Generate the Caller-ID spill if desired */ 01893 if (p->cidspill) { 01894 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01895 free(p->cidspill); 01896 } 01897 p->callwaitcas = 0; 01898 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01899 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 01900 p->cidpos = 0; 01901 send_callerid(p); 01902 } 01903 } 01904 /* Choose proper cadence */ 01905 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 01906 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1])) 01907 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 01908 p->cidrings = cidrings[p->distinctivering - 1]; 01909 } else { 01910 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 01911 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 01912 p->cidrings = p->sendcalleridafter; 01913 } 01914 01915 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 01916 c = strchr(dest, '/'); 01917 if (c) 01918 c++; 01919 if (c && (strlen(c) < p->stripmsd)) { 01920 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01921 c = NULL; 01922 } 01923 if (c) { 01924 p->dop.op = ZT_DIAL_OP_REPLACE; 01925 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 01926 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 01927 } else { 01928 p->dop.dialstr[0] = '\0'; 01929 } 01930 x = ZT_RING; 01931 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 01932 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 01933 ast_mutex_unlock(&p->lock); 01934 return -1; 01935 } 01936 p->dialing = 1; 01937 } else { 01938 /* Call waiting call */ 01939 p->callwaitrings = 0; 01940 if (ast->cid.cid_num) 01941 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 01942 else 01943 p->callwait_num[0] = '\0'; 01944 if (ast->cid.cid_name) 01945 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 01946 else 01947 p->callwait_name[0] = '\0'; 01948 /* Call waiting tone instead */ 01949 if (zt_callwait(ast)) { 01950 ast_mutex_unlock(&p->lock); 01951 return -1; 01952 } 01953 /* Make ring-back */ 01954 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 01955 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 01956 01957 } 01958 n = ast->cid.cid_name; 01959 l = ast->cid.cid_num; 01960 if (l) 01961 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 01962 else 01963 p->lastcid_num[0] = '\0'; 01964 if (n) 01965 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 01966 else 01967 p->lastcid_name[0] = '\0'; 01968 ast_setstate(ast, AST_STATE_RINGING); 01969 index = zt_get_index(ast, p, 0); 01970 if (index > -1) { 01971 p->subs[index].needringing = 1; 01972 } 01973 break; 01974 case SIG_FXSLS: 01975 case SIG_FXSGS: 01976 case SIG_FXSKS: 01977 case SIG_EMWINK: 01978 case SIG_EM: 01979 case SIG_EM_E1: 01980 case SIG_FEATD: 01981 case SIG_FEATDMF: 01982 case SIG_E911: 01983 case SIG_FGC_CAMA: 01984 case SIG_FGC_CAMAMF: 01985 case SIG_FEATB: 01986 case SIG_SFWINK: 01987 case SIG_SF: 01988 case SIG_SF_FEATD: 01989 case SIG_SF_FEATDMF: 01990 case SIG_FEATDMF_TA: 01991 case SIG_SF_FEATB: 01992 c = strchr(dest, '/'); 01993 if (c) 01994 c++; 01995 else 01996 c = ""; 01997 if (strlen(c) < p->stripmsd) { 01998 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01999 ast_mutex_unlock(&p->lock); 02000 return -1; 02001 } 02002 #ifdef HAVE_PRI 02003 /* Start the trunk, if not GR-303 */ 02004 if (!p->pri) { 02005 #endif 02006 x = ZT_START; 02007 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02008 if (res < 0) { 02009 if (errno != EINPROGRESS) { 02010 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 02011 ast_mutex_unlock(&p->lock); 02012 return -1; 02013 } 02014 } 02015 #ifdef HAVE_PRI 02016 } 02017 #endif 02018 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 02019 p->dop.op = ZT_DIAL_OP_REPLACE; 02020 02021 c += p->stripmsd; 02022 02023 switch (mysig) { 02024 case SIG_FEATD: 02025 l = ast->cid.cid_num; 02026 if (l) 02027 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 02028 else 02029 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 02030 break; 02031 case SIG_FEATDMF: 02032 l = ast->cid.cid_num; 02033 if (l) 02034 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 02035 else 02036 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 02037 break; 02038 case SIG_FEATDMF_TA: 02039 { 02040 const char *cic, *ozz; 02041 02042 /* If you have to go through a Tandem Access point you need to use this */ 02043 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 02044 if (!ozz) 02045 ozz = defaultozz; 02046 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 02047 if (!cic) 02048 cic = defaultcic; 02049 if (!ozz || !cic) { 02050 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 02051 ast_mutex_unlock(&p->lock); 02052 return -1; 02053 } 02054 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 02055 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 02056 p->whichwink = 0; 02057 } 02058 break; 02059 case SIG_E911: 02060 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 02061 break; 02062 case SIG_FGC_CAMA: 02063 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 02064 break; 02065 case SIG_FGC_CAMAMF: 02066 case SIG_FEATB: 02067 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 02068 break; 02069 default: 02070 if (p->pulse) 02071 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 02072 else 02073 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 02074 break; 02075 } 02076 02077 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 02078 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02079 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02080 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02081 p->echobreak = 1; 02082 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02083 } else 02084 p->echobreak = 0; 02085 if (!res) { 02086 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 02087 x = ZT_ONHOOK; 02088 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02089 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 02090 ast_mutex_unlock(&p->lock); 02091 return -1; 02092 } 02093 } else 02094 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 02095 p->dialing = 1; 02096 if (ast_strlen_zero(c)) 02097 p->dialednone = 1; 02098 ast_setstate(ast, AST_STATE_DIALING); 02099 break; 02100 case 0: 02101 /* Special pseudo -- automatically up*/ 02102 ast_setstate(ast, AST_STATE_UP); 02103 break; 02104 case SIG_PRI: 02105 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02106 p->dialdest[0] = '\0'; 02107 disable_dtmf_detect(p); 02108 break; 02109 case SIG_GSM: 02110 #ifdef HAVE_GSMAT 02111 if (p->gsm.modul) { 02112 c = strchr(dest, '/'); 02113 if (c) 02114 c++; 02115 else 02116 c = dest; 02117 ast_mutex_lock(&p->gsm.lock); 02118 if (gsm_dial(p->gsm.modul, p->use_callingpres ? ast->cid.cid_pres : 0, c)) { 02119 ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel); 02120 ast_mutex_unlock(&p->gsm.lock); 02121 ast_mutex_unlock(&p->lock); 02122 return -1; 02123 } 02124 ast_mutex_unlock(&p->gsm.lock); 02125 } 02126 #endif 02127 break; 02128 default: 02129 ast_log(LOG_DEBUG, "not yet implemented\n"); 02130 ast_mutex_unlock(&p->lock); 02131 return -1; 02132 } 02133 #ifdef HAVE_PRI 02134 if (p->pri) { 02135 struct pri_sr *sr; 02136 #ifdef SUPPORT_USERUSER 02137 const char *useruser; 02138 #endif 02139 int pridialplan; 02140 int dp_strip; 02141 int prilocaldialplan; 02142 int ldp_strip; 02143 int exclusive; 02144 const char *rr_str; 02145 int redirect_reason; 02146 02147 if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) { 02148 // pass NO audio when ringing an isdn phone 02149 p->dialing = 1; 02150 // maybe we could allow passing audio when calling a p2p PBX, but well... ;-) 02151 } 02152 02153 c = strchr(dest, '/'); 02154 if (c) 02155 c++; 02156 else 02157 c = dest; 02158 02159 l = NULL; 02160 n = NULL; 02161 02162 if (!p->hidecallerid) { 02163 l = ast->cid.cid_num; 02164 if (!p->hidecalleridname) { 02165 n = ast->cid.cid_name; 02166 } 02167 } 02168 02169 02170 if (strlen(c) < p->stripmsd) { 02171 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02172 ast_mutex_unlock(&p->lock); 02173 return -1; 02174 } 02175 strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1); 02176 if (mysig != SIG_FXSKS) { 02177 p->dop.op = ZT_DIAL_OP_REPLACE; 02178 s = strchr(c + p->stripmsd, 'w'); 02179 if (s) { 02180 if (strlen(s) > 1) 02181 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02182 else 02183 p->dop.dialstr[0] = '\0'; 02184 *s = '\0'; 02185 } else { 02186 p->dop.dialstr[0] = '\0'; 02187 } 02188 } 02189 if (pri_grab(p, p->pri)) { 02190 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02191 ast_mutex_unlock(&p->lock); 02192 return -1; 02193 } 02194 if (!(p->call = pri_new_call(p->pri->pri))) { 02195 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02196 pri_rel(p->pri); 02197 ast_mutex_unlock(&p->lock); 02198 return -1; 02199 } else { 02200 // ast_log(LOG_NOTICE, "call %d\n", p->call); 02201 } 02202 if (!(sr = pri_sr_new())) { 02203 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02204 pri_destroycall(p->pri->pri, p->call); 02205 p->call = NULL; 02206 pri_rel(p->pri); 02207 ast_mutex_unlock(&p->lock); 02208 return -1; 02209 } 02210 if (p->bearer || (mysig == SIG_FXSKS)) { 02211 if (p->bearer) { 02212 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); 02213 p->bearer->call = p->call; 02214 } else 02215 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02216 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02217 } 02218 p->digital = IS_DIGITAL(ast->transfercapability); 02219 /* Add support for exclusive override */ 02220 if (p->priexclusive) 02221 exclusive = 1; 02222 else { 02223 /* otherwise, traditional behavior */ 02224 if (p->pri->nodetype == PRI_NETWORK) 02225 exclusive = 0; 02226 else 02227 exclusive = 1; 02228 } 02229 02230 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02231 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02232 (p->digital ? -1 : 02233 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat); 02234 if (p->pri->facilityenable) 02235 pri_facility_enable(p->pri->pri); 02236 02237 if (option_verbose > 2) 02238 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02239 dp_strip = 0; 02240 pridialplan = p->pri->dialplan - 1; 02241 if (pridialplan == -2) { /* compute dynamically */ 02242 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02243 dp_strip = strlen(p->pri->internationalprefix); 02244 pridialplan = PRI_INTERNATIONAL_ISDN; 02245 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02246 dp_strip = strlen(p->pri->nationalprefix); 02247 pridialplan = PRI_NATIONAL_ISDN; 02248 } else { 02249 pridialplan = PRI_LOCAL_ISDN; 02250 } 02251 } 02252 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02253 02254 ldp_strip = 0; 02255 prilocaldialplan = p->pri->localdialplan - 1; 02256 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02257 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02258 ldp_strip = strlen(p->pri->internationalprefix); 02259 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02260 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02261 ldp_strip = strlen(p->pri->nationalprefix); 02262 prilocaldialplan = PRI_NATIONAL_ISDN; 02263 } else { 02264 prilocaldialplan = PRI_LOCAL_ISDN; 02265 } 02266 } 02267 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02268 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02269 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { 02270 if (!strcasecmp(rr_str, "UNKNOWN")) 02271 redirect_reason = 0; 02272 else if (!strcasecmp(rr_str, "BUSY")) 02273 redirect_reason = 1; 02274 else if (!strcasecmp(rr_str, "NO_REPLY")) 02275 redirect_reason = 2; 02276 else if (!strcasecmp(rr_str, "UNCONDITIONAL")) 02277 redirect_reason = 15; 02278 else 02279 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02280 } else 02281 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02282 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); 02283 02284 #ifdef SUPPORT_USERUSER 02285 /* User-user info */ 02286 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02287 02288 if (useruser) 02289 pri_sr_set_useruser(sr, useruser); 02290 #endif 02291 02292 if (pri_setup(p->pri->pri, p->call, sr)) { 02293 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02294 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02295 pri_rel(p->pri); 02296 ast_mutex_unlock(&p->lock); 02297 pri_sr_free(sr); 02298 return -1; 02299 } 02300 pri_sr_free(sr); 02301 ast_setstate(ast, AST_STATE_DIALING); 02302 pri_rel(p->pri); 02303 } 02304 #endif 02305 ast_mutex_unlock(&p->lock); 02306 return 0; 02307 }
static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1807 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().
01808 { 01809 struct zt_pvt *p = ast->tech_pvt; 01810 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01811 if (p->cidspill) { 01812 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01813 free(p->cidspill); 01814 } 01815 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01816 return -1; 01817 save_conference(p); 01818 /* Silence */ 01819 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01820 if (!p->callwaitrings && p->callwaitingcallerid) { 01821 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01822 p->callwaitcas = 1; 01823 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01824 } else { 01825 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01826 p->callwaitcas = 0; 01827 p->cidlen = 2400 + READ_SIZE * 4; 01828 } 01829 p->cidpos = 0; 01830 send_callerid(p); 01831 01832 return 0; 01833 }
static struct zt_chan_conf zt_chan_conf_default | ( | void | ) | [static, read] |
returns a new zt_chan_conf with default values (by-value)
Definition at line 643 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().
00643 { 00644 /* recall that if a field is not included here it is initialized 00645 * to 0 or equivalent 00646 */ 00647 struct zt_chan_conf conf = { 00648 #ifdef HAVE_PRI 00649 .pri = { 00650 .nsf = PRI_NSF_NONE, 00651 .switchtype = PRI_SWITCH_NI2, 00652 .dialplan = PRI_NATIONAL_ISDN + 1, 00653 .localdialplan = PRI_NATIONAL_ISDN + 1, 00654 .nodetype = PRI_CPE, 00655 00656 .minunused = 2, 00657 .idleext = "", 00658 .idledial = "", 00659 .nocid = "No CID available", 00660 .withheldcid = "CID withheld", 00661 .internationalprefix = "", 00662 .nationalprefix = "", 00663 .localprefix = "", 00664 .privateprefix = "", 00665 .unknownprefix = "", 00666 .usercid = 0, 00667 00668 .resetinterval = 3600 00669 }, 00670 #endif 00671 .chan = { 00672 .context = "default", 00673 .cid_num = "", 00674 .cid_name = "", 00675 .mohinterpret = "default", 00676 .mohsuggest = "", 00677 .transfertobusy = 1, 00678 .priindication_oob = 0, 00679 .pritransfer = 0, 00680 00681 .cid_signalling = CID_SIG_BELL, 00682 .cid_start = CID_START_RING, 00683 .zaptrcallerid = 0, 00684 .use_callerid = 1, 00685 .sig = -1, 00686 .outsigmod = -1, 00687 00688 .tonezone = -1, 00689 00690 .echocancel = 1, 00691 00692 .busycount = 3, 00693 00694 .accountcode = "", 00695 00696 .mailbox = "", 00697 00698 00699 .polarityonanswerdelay = 600, 00700 00701 .sendcalleridafter = DEFAULT_CIDRINGS 00702 }, 00703 .timing = { 00704 .prewinktime = -1, 00705 .preflashtime = -1, 00706 .winktime = -1, 00707 .flashtime = -1, 00708 .starttime = -1, 00709 .rxwinktime = -1, 00710 .rxflashtime = -1, 00711 .debouncetime = -1 00712 }, 00713 .smdi_port = "/dev/ttyS0", 00714 }; 00715 00716 return conf; 00717 }
static void zt_close | ( | int | fd | ) | [static] |
Definition at line 972 of file chan_zap.c.
Referenced by __unload_module(), alloc_sub(), destroy_channel(), mkintf(), and unalloc_sub().
static int zt_confmute | ( | struct zt_pvt * | p, | |
int | muted | |||
) | [inline, static] |
Definition at line 1690 of file chan_zap.c.
References ast_log(), zt_pvt::channel, errno, LOG_WARNING, zt_pvt::sig, SIG_GSM, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_handle_dtmfup(), zt_handle_event(), zt_hangup(), and zt_new().
01691 { 01692 int x, y, res; 01693 x = muted; 01694 if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) { 01695 y = 1; 01696 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01697 if (res) 01698 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01699 } 01700 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01701 if (res < 0) 01702 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01703 return res; 01704 }
static int zt_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1059 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().
01060 { 01061 struct zt_pvt *pvt; 01062 int index; 01063 int dtmf = -1; 01064 01065 pvt = chan->tech_pvt; 01066 01067 ast_mutex_lock(&pvt->lock); 01068 01069 index = zt_get_index(chan, pvt, 0); 01070 01071 if ((index != SUB_REAL) || !pvt->owner) 01072 goto out; 01073 01074 #ifdef HAVE_PRI 01075 if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) { 01076 if (pvt->setup_ack) { 01077 if (!pri_grab(pvt, pvt->pri)) { 01078 pri_information(pvt->pri->pri, pvt->call, digit); 01079 pri_rel(pvt->pri); 01080 } else 01081 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span); 01082 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 01083 int res; 01084 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01085 res = strlen(pvt->dialdest); 01086 pvt->dialdest[res++] = digit; 01087 pvt->dialdest[res] = '\0'; 01088 } 01089 goto out; 01090 } 01091 #endif 01092 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 01093 goto out; 01094 01095 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) { 01096 int res; 01097 ZT_DIAL_OPERATION zo = { 01098 .op = ZT_DIAL_OP_APPEND, 01099 .dialstr[0] = 'T', 01100 .dialstr[1] = digit, 01101 .dialstr[2] = 0, 01102 }; 01103 if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01104 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01105 else 01106 pvt->dialing = 1; 01107 } else { 01108 ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit); 01109 pvt->dialing = 1; 01110 pvt->begindigit = digit; 01111 } 01112 01113 out: 01114 ast_mutex_unlock(&pvt->lock); 01115 01116 return 0; 01117 }
static int zt_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1119 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().
01120 { 01121 struct zt_pvt *pvt; 01122 int res = 0; 01123 int index; 01124 int x; 01125 01126 pvt = chan->tech_pvt; 01127 01128 ast_mutex_lock(&pvt->lock); 01129 01130 index = zt_get_index(chan, pvt, 0); 01131 01132 if ((index != SUB_REAL) || !pvt->owner || pvt->pulse) 01133 goto out; 01134 01135 #ifdef HAVE_PRI 01136 /* This means that the digit was already sent via PRI signalling */ 01137 if (pvt->sig == SIG_PRI && !pvt->begindigit) 01138 goto out; 01139 #endif 01140 01141 if (pvt->begindigit) { 01142 x = -1; 01143 ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit); 01144 res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x); 01145 pvt->dialing = 0; 01146 pvt->begindigit = 0; 01147 } 01148 01149 out: 01150 ast_mutex_unlock(&pvt->lock); 01151 01152 return res; 01153 }
static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1522 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(), app_zapEC(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01523 { 01524 int x; 01525 int res; 01526 if (p->echocancel) { 01527 x = 0; 01528 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01529 if (res) 01530 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01531 else if (option_debug) 01532 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01533 } 01534 p->echocanon = 0; 01535 }
static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1468 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, errno, zt_pvt::faxhandled, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), app_zapEC(), handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_setoption().
01469 { 01470 int x; 01471 int res; 01472 if (!p) 01473 return; 01474 if (p->faxhandled) { 01475 ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n"); 01476 return; 01477 } 01478 if (p->echocanon) { 01479 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01480 return; 01481 } 01482 if (p->digital) { 01483 ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n"); 01484 return; 01485 } 01486 if (p->echocancel) { 01487 if (p->sig == SIG_PRI) { 01488 x = 1; 01489 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01490 if (res) 01491 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno)); 01492 } 01493 x = p->echocancel; 01494 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01495 if (res) 01496 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 01497 else { 01498 p->echocanon = 1; 01499 if (option_debug) 01500 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01501 } 01502 } else if (option_debug) 01503 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01504 }
static struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4777 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, and ast_channel::tech_pvt.
04778 { 04779 struct zt_pvt *p = ast->tech_pvt; 04780 struct ast_frame *f; 04781 ast_mutex_lock(&p->lock); 04782 f = __zt_exception(ast); 04783 ast_mutex_unlock(&p->lock); 04784 return f; 04785 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3585 of file chan_zap.c.
References ast_channel::_state, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RINGING, zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, LOG_ERROR, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), zt_indicate(), and zt_unlink().
03586 { 03587 struct zt_pvt *p = newchan->tech_pvt; 03588 int x; 03589 if (newchan && newchan->tech_pvt) { 03590 p = newchan->tech_pvt; 03591 } 03592 if (!p) { 03593 if (newchan) { 03594 ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name); 03595 } 03596 return 0; 03597 } 03598 ast_mutex_lock(&p->lock); 03599 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03600 if (p->owner == oldchan) { 03601 p->owner = newchan; 03602 } 03603 for (x = 0; x < 3; x++) 03604 if (p->subs[x].owner == oldchan) { 03605 if (!x) 03606 zt_unlink(NULL, p, 0); 03607 p->subs[x].owner = newchan; 03608 } 03609 if (newchan->_state == AST_STATE_RINGING) 03610 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03611 update_conf(p); 03612 ast_mutex_unlock(&p->lock); 03613 return 0; 03614 }
static int zt_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3157 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.
03158 { 03159 struct zt_pvt *p = chan->tech_pvt; 03160 03161 if (!strcasecmp(data, "rxgain")) { 03162 ast_mutex_lock(&p->lock); 03163 snprintf(buf, len, "%f", p->rxgain); 03164 ast_mutex_unlock(&p->lock); 03165 } else if (!strcasecmp(data, "txgain")) { 03166 ast_mutex_lock(&p->lock); 03167 snprintf(buf, len, "%f", p->txgain); 03168 ast_mutex_unlock(&p->lock); 03169 } else { 03170 ast_copy_string(buf, "", len); 03171 } 03172 return 0; 03173 }
static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 263 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
00264 { 00265 int j; 00266 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00267 return -1; 00268 return j; 00269 }
static int zt_get_index | ( | struct ast_channel * | ast, | |
struct zt_pvt * | p, | |||
int | nullok | |||
) | [static] |
Definition at line 821 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_setoption(), zt_tdd_sendtext(), and zt_write().
00822 { 00823 int res; 00824 if (p->subs[0].owner == ast) 00825 res = 0; 00826 else if (p->subs[1].owner == ast) 00827 res = 1; 00828 else if (p->subs[2].owner == ast) 00829 res = 2; 00830 else { 00831 res = -1; 00832 if (!nullok) 00833 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00834 } 00835 return res; 00836 }
static void zt_handle_dtmfup | ( | struct ast_channel * | ast, | |
int | index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 3762 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, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, 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().
03763 { 03764 struct zt_pvt *p = ast->tech_pvt; 03765 struct ast_frame *f = *dest; 03766 03767 if (option_debug) 03768 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03769 03770 if (p->confirmanswer) { 03771 if (option_debug) 03772 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03773 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03774 of a DTMF digit */ 03775 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03776 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03777 *dest = &p->subs[index].f; 03778 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03779 p->confirmanswer = 0; 03780 } else if (p->callwaitcas) { 03781 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03782 if (option_debug) 03783 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03784 if (p->cidspill) 03785 free(p->cidspill); 03786 send_cwcidspill(p); 03787 } 03788 if ((f->subclass != 'm') && (f->subclass != 'u')) 03789 p->callwaitcas = 0; 03790 p->subs[index].f.frametype = AST_FRAME_NULL; 03791 p->subs[index].f.subclass = 0; 03792 *dest = &p->subs[index].f; 03793 } else if (f->subclass == 'f') { 03794 /* Fax tone -- Handle and return NULL */ 03795 if ((p->callprogress & 0x6) && !p->faxhandled) { 03796 p->faxhandled++; 03797 if (strcmp(ast->exten, "fax")) { 03798 const char *target_context = S_OR(ast->macrocontext, ast->context); 03799 03800 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03801 if (option_verbose > 2) 03802 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03803 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03804 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03805 if (ast_async_goto(ast, target_context, "fax", 1)) 03806 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03807 } else { 03808 if (option_verbose > 2) 03809 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03810 } 03811 } else if (option_debug) 03812 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03813 } else if (option_debug) 03814 ast_log(LOG_DEBUG, "Fax already handled\n"); 03815 zt_confmute(p, 0); 03816 p->subs[index].f.frametype = AST_FRAME_NULL; 03817 p->subs[index].f.subclass = 0; 03818 *dest = &p->subs[index].f; 03819 } else if (f->subclass == 'm') { 03820 /* Confmute request */ 03821 zt_confmute(p, 1); 03822 p->subs[index].f.frametype = AST_FRAME_NULL; 03823 p->subs[index].f.subclass = 0; 03824 *dest = &p->subs[index].f; 03825 } else if (f->subclass == 'u') { 03826 /* Unmute */ 03827 zt_confmute(p, 0); 03828 p->subs[index].f.frametype = AST_FRAME_NULL; 03829 p->subs[index].f.subclass = 0; 03830 *dest = &p->subs[index].f; 03831 } else 03832 zt_confmute(p, 0); 03833 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 3835 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::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, DEADLOCK_AVOIDANCE, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::dop, zt_pvt::dsp, zt_pvt::echobreak, zt_pvt::echocanon, zt_pvt::echorest, zt_pvt::echotraining, errno, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_subchannel::needanswer, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, 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().
03836 { 03837 int res, x; 03838 int index, mysig; 03839 char *c; 03840 struct zt_pvt *p = ast->tech_pvt; 03841 pthread_t threadid; 03842 pthread_attr_t attr; 03843 struct ast_channel *chan; 03844 struct ast_frame *f; 03845 03846 index = zt_get_index(ast, p, 0); 03847 mysig = p->sig; 03848 if (p->outsigmod > -1) 03849 mysig = p->outsigmod; 03850 p->subs[index].f.frametype = AST_FRAME_NULL; 03851 p->subs[index].f.subclass = 0; 03852 p->subs[index].f.datalen = 0; 03853 p->subs[index].f.samples = 0; 03854 p->subs[index].f.mallocd = 0; 03855 p->subs[index].f.offset = 0; 03856 p->subs[index].f.src = "zt_handle_event"; 03857 p->subs[index].f.data = NULL; 03858 f = &p->subs[index].f; 03859 03860 if (index < 0) 03861 return &p->subs[index].f; 03862 if (p->fake_event) { 03863 res = p->fake_event; 03864 p->fake_event = 0; 03865 } else 03866 res = zt_get_event(p->subs[index].zfd); 03867 03868 if (option_debug) 03869 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03870 03871 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03872 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 03873 03874 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03875 #ifdef HAVE_PRI 03876 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03877 /* absorb event */ 03878 } else { 03879 #endif 03880 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 03881 p->subs[index].f.subclass = res & 0xff; 03882 #ifdef HAVE_PRI 03883 } 03884 #endif 03885 zt_handle_dtmfup(ast, index, &f); 03886 return f; 03887 } 03888 03889 if (res & ZT_EVENT_DTMFDOWN) { 03890 if (option_debug) 03891 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03892 /* Mute conference */ 03893 zt_confmute(p, 1); 03894 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 03895 p->subs[index].f.subclass = res & 0xff; 03896 return &p->subs[index].f; 03897 } 03898 03899 switch (res) { 03900 #ifdef ZT_EVENT_EC_DISABLED 03901 case ZT_EVENT_EC_DISABLED: 03902 if (option_verbose > 2) 03903 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 03904 p->echocanon = 0; 03905 break; 03906 #endif 03907 case ZT_EVENT_BITSCHANGED: 03908 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03909 case ZT_EVENT_PULSE_START: 03910 /* Stop tone if there's a pulse start and the PBX isn't started */ 03911 if (!ast->pbx) 03912 tone_zone_play_tone(p->subs[index].zfd, -1); 03913 break; 03914 case ZT_EVENT_DIALCOMPLETE: 03915 if (p->inalarm) break; 03916 if ((p->radio || (p->oprmode < 0))) break; 03917 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03918 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03919 return NULL; 03920 } 03921 if (!x) { /* if not still dialing in driver */ 03922 zt_enable_ec(p); 03923 if (p->echobreak) { 03924 zt_train_ec(p); 03925 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03926 p->dop.op = ZT_DIAL_OP_REPLACE; 03927 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03928 p->echobreak = 0; 03929 } else { 03930 p->dialing = 0; 03931 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 03932 /* if thru with dialing after offhook */ 03933 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03934 ast_setstate(ast, AST_STATE_UP); 03935 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03936 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03937 break; 03938 } else { /* if to state wait for offhook to dial rest */ 03939 /* we now wait for off hook */ 03940 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03941 } 03942 } 03943 if (ast->_state == AST_STATE_DIALING) { 03944 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03945 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03946 } 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)))) { 03947 ast_setstate(ast, AST_STATE_RINGING); 03948 } else if (!p->answeronpolarityswitch) { 03949 ast_setstate(ast, AST_STATE_UP); 03950 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03951 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03952 /* If aops=0 and hops=1, this is necessary */ 03953 p->polarity = POLARITY_REV; 03954 } else { 03955 /* Start clean, so we can catch the change to REV polarity when party answers */ 03956 p->polarity = POLARITY_IDLE; 03957 } 03958 } 03959 } 03960 } 03961 break; 03962 case ZT_EVENT_ALARM: 03963 #ifdef HAVE_PRI 03964 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 03965 /* T309 is not enabled : hangup calls when alarm occurs */ 03966 if (p->call) { 03967 if (p->pri && p->pri->pri) { 03968 if (!pri_grab(p, p->pri)) { 03969 pri_hangup(p->pri->pri, p->call, -1, -1); 03970 pri_destroycall(p->pri->pri, p->call); 03971 p->call = NULL; 03972 pri_rel(p->pri); 03973 } else 03974 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03975 } else 03976 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 03977 } 03978 if (p->owner) 03979 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03980 } 03981 if (p->bearer) 03982 p->bearer->inalarm = 1; 03983 else 03984 #endif 03985 p->inalarm = 1; 03986 res = get_alarms(p); 03987 do { 03988 const char *alarm_str = alarm2str(res); 03989 03990 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 03991 * doesn't know what to do with it. Don't confuse users with log messages. */ 03992 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 03993 p->unknown_alarm = 1; 03994 break; 03995 } else { 03996 p->unknown_alarm = 0; 03997 } 03998 03999 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 04000 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 04001 "Alarm: %s\r\n" 04002 "Channel: %d\r\n", 04003 alarm_str, p->channel); 04004 } while (0); 04005 #ifdef HAVE_LIBPRI 04006 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 04007 /* fall through intentionally */ 04008 } else { 04009 break; 04010 } 04011 #endif 04012 case ZT_EVENT_ONHOOK: 04013 if (p->radio) { 04014 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04015 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04016 break; 04017 } 04018 if (p->oprmode < 0) 04019 { 04020 if (p->oprmode != -1) break; 04021 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04022 { 04023 /* Make sure it starts ringing */ 04024 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04025 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 04026 save_conference(p->oprpeer); 04027 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04028 } 04029 break; 04030 } 04031 switch (p->sig) { 04032 case SIG_FXOLS: 04033 case SIG_FXOGS: 04034 case SIG_FXOKS: 04035 p->onhooktime = time(NULL); 04036 p->msgstate = -1; 04037 /* Check for some special conditions regarding call waiting */ 04038 if (index == SUB_REAL) { 04039 /* The normal line was hung up */ 04040 if (p->subs[SUB_CALLWAIT].owner) { 04041 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 04042 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 04043 if (option_verbose > 2) 04044 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 04045 unalloc_sub(p, SUB_CALLWAIT); 04046 #if 0 04047 p->subs[index].needanswer = 0; 04048 p->subs[index].needringing = 0; 04049 #endif 04050 p->callwaitingrepeat = 0; 04051 p->cidcwexpire = 0; 04052 p->owner = NULL; 04053 /* Don't start streaming audio yet if the incoming call isn't up yet */ 04054 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 04055 p->dialing = 1; 04056 zt_ring_phone(p); 04057 } else if (p->subs[SUB_THREEWAY].owner) { 04058 unsigned int mssinceflash; 04059 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 04060 the private structure -- not especially easy or clean */ 04061 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 04062 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 04063 ast_mutex_unlock(&p->lock); 04064 DEADLOCK_AVOIDANCE(&ast->lock); 04065 /* We can grab ast and p in that order, without worry. We should make sure 04066 nothing seriously bad has happened though like some sort of bizarre double 04067 masquerade! */ 04068 ast_mutex_lock(&p->lock); 04069 if (p->owner != ast) { 04070 ast_log(LOG_WARNING, "This isn't good...\n"); 04071 return NULL; 04072 } 04073 } 04074 if (!p->subs[SUB_THREEWAY].owner) { 04075 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 04076 return NULL; 04077 } 04078 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 04079 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 04080 if (mssinceflash < MIN_MS_SINCE_FLASH) { 04081 /* It hasn't been long enough since the last flashook. This is probably a bounce on 04082 hanging up. Hangup both channels now */ 04083 if (p->subs[SUB_THREEWAY].owner) 04084 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 04085 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04086 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 04087 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04088 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 04089 if (p->transfer) { 04090 /* In any case this isn't a threeway call anymore */ 04091 p->subs[SUB_REAL].inthreeway = 0; 04092 p->subs[SUB_THREEWAY].inthreeway = 0; 04093 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 04094 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 04095 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04096 /* Swap subs and dis-own channel */ 04097 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04098 p->owner = NULL; 04099 /* Ring the phone */ 04100 zt_ring_phone(p); 04101 } else { 04102 if ((res = attempt_transfer(p)) < 0) { 04103 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04104 if (p->subs[SUB_THREEWAY].owner) 04105 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04106 } else if (res) { 04107 /* Don't actually hang up at this point */ 04108 if (p->subs[SUB_THREEWAY].owner) 04109 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04110 break; 04111 } 04112 } 04113 } else { 04114 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04115 if (p->subs[SUB_THREEWAY].owner) 04116 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04117 } 04118 } else { 04119 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04120 /* Swap subs and dis-own channel */ 04121 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04122 p->owner = NULL; 04123 /* Ring the phone */ 04124 zt_ring_phone(p); 04125 } 04126 } 04127 } else { 04128 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 04129 } 04130 /* Fall through */ 04131 default: 04132 zt_disable_ec(p); 04133 return NULL; 04134 } 04135 break; 04136 case ZT_EVENT_RINGOFFHOOK: 04137 if (p->inalarm) break; 04138 if (p->oprmode < 0) 04139 { 04140 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04141 { 04142 /* Make sure it stops ringing */ 04143 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04144 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 04145 restore_conference(p->oprpeer); 04146 } 04147 break; 04148 } 04149 if (p->radio) 04150 { 04151 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04152 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04153 break; 04154 } 04155 /* for E911, its supposed to wait for offhook then dial 04156 the second half of the dial string */ 04157 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 04158 c = strchr(p->dialdest, '/'); 04159 if (c) 04160 c++; 04161 else 04162 c = p->dialdest; 04163 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 04164 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 04165 if (strlen(p->dop.dialstr) > 4) { 04166 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 04167 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 04168 p->echorest[sizeof(p->echorest) - 1] = '\0'; 04169 p->echobreak = 1; 04170 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 04171 } else 04172 p->echobreak = 0; 04173 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 04174 x = ZT_ONHOOK; 04175 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 04176 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 04177 return NULL; 04178 } 04179 p->dialing = 1; 04180 return &p->subs[index].f; 04181 } 04182 switch (p->sig) { 04183 case SIG_FXOLS: 04184 case SIG_FXOGS: 04185 case SIG_FXOKS: 04186 switch (ast->_state) { 04187 case AST_STATE_RINGING: 04188 zt_enable_ec(p); 04189 zt_train_ec(p); 04190 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04191 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04192 /* Make sure it stops ringing */ 04193 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04194 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 04195 if (p->cidspill) { 04196 /* Cancel any running CallerID spill */ 04197 free(p->cidspill); 04198 p->cidspill = NULL; 04199 } 04200 p->dialing = 0; 04201 p->callwaitcas = 0; 04202 if (p->confirmanswer) { 04203 /* Ignore answer if "confirm answer" is enabled */ 04204 p->subs[index].f.frametype = AST_FRAME_NULL; 04205 p->subs[index].f.subclass = 0; 04206 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04207 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04208 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04209 if (res < 0) { 04210 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04211 p->dop.dialstr[0] = '\0'; 04212 return NULL; 04213 } else { 04214 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04215 p->subs[index].f.frametype = AST_FRAME_NULL; 04216 p->subs[index].f.subclass = 0; 04217 p->dialing = 1; 04218 } 04219 p->dop.dialstr[0] = '\0'; 04220 ast_setstate(ast, AST_STATE_DIALING); 04221 } else 04222 ast_setstate(ast, AST_STATE_UP); 04223 return &p->subs[index].f; 04224 case AST_STATE_DOWN: 04225 ast_setstate(ast, AST_STATE_RING); 04226 ast->rings = 1; 04227 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04228 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04229 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04230 return &p->subs[index].f; 04231 case AST_STATE_UP: 04232 /* Make sure it stops ringing */ 04233 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04234 /* Okay -- probably call waiting*/ 04235 if (ast_bridged_channel(p->owner)) 04236 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04237 p->subs[index].needunhold = 1; 04238 break; 04239 case AST_STATE_RESERVED: 04240 /* Start up dialtone */ 04241 if (has_voicemail(p)) 04242 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04243 else 04244 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04245 break; 04246 default: 04247 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04248 } 04249 break; 04250 case SIG_FXSLS: 04251 case SIG_FXSGS: 04252 case SIG_FXSKS: 04253 if (ast->_state == AST_STATE_RING) { 04254 p->ringt = p->ringt_base; 04255 } 04256 04257 /* Fall through */ 04258 case SIG_EM: 04259 case SIG_EM_E1: 04260 case SIG_EMWINK: 04261 case SIG_FEATD: 04262 case SIG_FEATDMF: 04263 case SIG_FEATDMF_TA: 04264 case SIG_E911: 04265 case SIG_FGC_CAMA: 04266 case SIG_FGC_CAMAMF: 04267 case SIG_FEATB: 04268 case SIG_SF: 04269 case SIG_SFWINK: 04270 case SIG_SF_FEATD: 04271 case SIG_SF_FEATDMF: 04272 case SIG_SF_FEATB: 04273 if (ast->_state == AST_STATE_PRERING) 04274 ast_setstate(ast, AST_STATE_RING); 04275 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04276 if (option_debug) 04277 ast_log(LOG_DEBUG, "Ring detected\n"); 04278 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04279 p->subs[index].f.subclass = AST_CONTROL_RING; 04280 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04281 if (option_debug) 04282 ast_log(LOG_DEBUG, "Line answered\n"); 04283 if (p->confirmanswer) { 04284 p->subs[index].f.frametype = AST_FRAME_NULL; 04285 p->subs[index].f.subclass = 0; 04286 } else { 04287 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04288 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04289 ast_setstate(ast, AST_STATE_UP); 04290 } 04291 } else if (ast->_state != AST_STATE_RING) 04292 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04293 break; 04294 default: 04295 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04296 } 04297 break; 04298 #ifdef ZT_EVENT_RINGBEGIN 04299 case ZT_EVENT_RINGBEGIN: 04300 switch (p->sig) { 04301 case SIG_FXSLS: 04302 case SIG_FXSGS: 04303 case SIG_FXSKS: 04304 if (ast->_state == AST_STATE_RING) { 04305 p->ringt = p->ringt_base; 04306 } 04307 break; 04308 } 04309 break; 04310 #endif 04311 case ZT_EVENT_RINGEROFF: 04312 if (p->inalarm) break; 04313 if ((p->radio || (p->oprmode < 0))) break; 04314 ast->rings++; 04315 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04316 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04317 free(p->cidspill); 04318 p->cidspill = NULL; 04319 p->callwaitcas = 0; 04320 } 04321 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04322 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04323 break; 04324 case ZT_EVENT_RINGERON: 04325 break; 04326 case ZT_EVENT_NOALARM: 04327 p->inalarm = 0; 04328 #ifdef HAVE_PRI 04329 /* Extremely unlikely but just in case */ 04330 if (p->bearer) 04331 p->bearer->inalarm = 0; 04332 #endif 04333 if (!p->unknown_alarm) { 04334 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04335 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04336 "Channel: %d\r\n", p->channel); 04337 } else { 04338 p->unknown_alarm = 0; 04339 } 04340 break; 04341 case ZT_EVENT_WINKFLASH: 04342 if (p->inalarm) break; 04343 if (p->radio) break; 04344 if (p->oprmode < 0) break; 04345 if (p->oprmode > 1) 04346 { 04347 struct zt_params par; 04348 04349 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04350 { 04351 if (!par.rxisoffhook) 04352 { 04353 /* Make sure it stops ringing */ 04354 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04355 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04356 save_conference(p); 04357 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04358 } 04359 } 04360 break; 04361 } 04362 /* Remember last time we got a flash-hook */ 04363 gettimeofday(&p->flashtime, NULL); 04364 switch (mysig) { 04365 case SIG_FXOLS: 04366 case SIG_FXOGS: 04367 case SIG_FXOKS: 04368 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04369 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04370 p->callwaitcas = 0; 04371 04372 if (index != SUB_REAL) { 04373 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04374 goto winkflashdone; 04375 } 04376 04377 if (p->subs[SUB_CALLWAIT].owner) { 04378 /* Swap to call-wait */ 04379 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04380 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04381 p->owner = p->subs[SUB_REAL].owner; 04382 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04383 if (p->owner->_state == AST_STATE_RINGING) { 04384 ast_setstate(p->owner, AST_STATE_UP); 04385 p->subs[SUB_REAL].needanswer = 1; 04386 } 04387 p->callwaitingrepeat = 0; 04388 p->cidcwexpire = 0; 04389 /* Start music on hold if appropriate */ 04390 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04391 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04392 S_OR(p->mohsuggest, NULL), 04393 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04394 } 04395 p->subs[SUB_CALLWAIT].needhold = 1; 04396 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04397 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04398 S_OR(p->mohsuggest, NULL), 04399 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04400 } 04401 p->subs[SUB_REAL].needunhold = 1; 04402 } else if (!p->subs[SUB_THREEWAY].owner) { 04403 char cid_num[256]; 04404 char cid_name[256]; 04405 04406 if (!p->threewaycalling) { 04407 /* Just send a flash if no 3-way calling */ 04408 p->subs[SUB_REAL].needflash = 1; 04409 goto winkflashdone; 04410 } else if (!check_for_conference(p)) { 04411 if (p->zaptrcallerid && p->owner) { 04412 if (p->owner->cid.cid_num) 04413 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04414 if (p->owner->cid.cid_name) 04415 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04416 } 04417 /* XXX This section needs much more error checking!!! XXX */ 04418 /* Start a 3-way call if feasible */ 04419 if (!((ast->pbx) || 04420 (ast->_state == AST_STATE_UP) || 04421 (ast->_state == AST_STATE_RING))) { 04422 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04423 goto winkflashdone; 04424 } 04425 if (alloc_sub(p, SUB_THREEWAY)) { 04426 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04427 goto winkflashdone; 04428 } 04429 /* Make new channel */ 04430 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04431 if (p->zaptrcallerid) { 04432 if (!p->origcid_num) 04433 p->origcid_num = ast_strdup(p->cid_num); 04434 if (!p->origcid_name) 04435 p->origcid_name = ast_strdup(p->cid_name); 04436 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04437 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04438 } 04439 /* Swap things around between the three-way and real call */ 04440 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04441 /* Disable echo canceller for better dialing */ 04442 zt_disable_ec(p); 04443 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04444 if (res) 04445 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04446 p->owner = chan; 04447 pthread_attr_init(&attr); 04448 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04449 if (!chan) { 04450 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04451 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04452 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04453 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04454 zt_enable_ec(p); 04455 ast_hangup(chan); 04456 } else { 04457 if (option_verbose > 2) 04458 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04459 /* Start music on hold if appropriate */ 04460 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04461 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04462 S_OR(p->mohsuggest, NULL), 04463 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04464 } 04465 p->subs[SUB_THREEWAY].needhold = 1; 04466 } 04467 pthread_attr_destroy(&attr); 04468 } 04469 } else { 04470 /* Already have a 3 way call */ 04471 if (p->subs[SUB_THREEWAY].inthreeway) { 04472 /* Call is already up, drop the last person */ 04473 if (option_debug) 04474 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04475 /* If the primary call isn't answered yet, use it */ 04476 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04477 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04478 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04479 p->owner = p->subs[SUB_REAL].owner; 04480 } 04481 /* Drop the last call and stop the conference */ 04482 if (option_verbose > 2) 04483 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04484 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04485 p->subs[SUB_REAL].inthreeway = 0; 04486 p->subs[SUB_THREEWAY].inthreeway = 0; 04487 } else { 04488 /* Lets see what we're up to */ 04489 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04490 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04491 int otherindex = SUB_THREEWAY; 04492 04493 if (option_verbose > 2) 04494 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); 04495 /* Put them in the threeway, and flip */ 04496 p->subs[SUB_THREEWAY].inthreeway = 1; 04497 p->subs[SUB_REAL].inthreeway = 1; 04498 if (ast->_state == AST_STATE_UP) { 04499 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04500 otherindex = SUB_REAL; 04501 } 04502 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04503 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04504 p->subs[otherindex].needunhold = 1; 04505 p->owner = p->subs[SUB_REAL].owner; 04506 if (ast->_state == AST_STATE_RINGING) { 04507 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04508 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04509 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04510 } 04511 } else { 04512 if (option_verbose > 2) 04513 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04514 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04515 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04516 p->owner = p->subs[SUB_REAL].owner; 04517 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04518 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04519 p->subs[SUB_REAL].needunhold = 1; 04520 zt_enable_ec(p); 04521 } 04522 04523 } 04524 } 04525 winkflashdone: 04526 update_conf(p); 04527 break; 04528 case SIG_EM: 04529 case SIG_EM_E1: 04530 case SIG_EMWINK: 04531 case SIG_FEATD: 04532 case SIG_SF: 04533 case SIG_SFWINK: 04534 case SIG_SF_FEATD: 04535 case SIG_FXSLS: 04536 case SIG_FXSGS: 04537 if (p->dialing) 04538 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04539 else 04540 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04541 break; 04542 case SIG_FEATDMF_TA: 04543 switch (p->whichwink) { 04544 case 0: 04545 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04546 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04547 break; 04548 case 1: 04549 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04550 break; 04551 case 2: 04552 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04553 return NULL; 04554 } 04555 p->whichwink++; 04556 /* Fall through */ 04557 case SIG_FEATDMF: 04558 case SIG_E911: 04559 case SIG_FGC_CAMAMF: 04560 case SIG_FGC_CAMA: 04561 case SIG_FEATB: 04562 case SIG_SF_FEATDMF: 04563 case SIG_SF_FEATB: 04564 /* FGD MF *Must* wait for wink */ 04565 if (!ast_strlen_zero(p->dop.dialstr)) { 04566 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04567 if (res < 0) { 04568 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04569 p->dop.dialstr[0] = '\0'; 04570 return NULL; 04571 } else 04572 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04573 } 04574 p->dop.dialstr[0] = '\0'; 04575 break; 04576 default: 04577 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04578 } 04579 break; 04580 case ZT_EVENT_HOOKCOMPLETE: 04581 if (p->inalarm) break; 04582 if ((p->radio || (p->oprmode < 0))) break; 04583 switch (mysig) { 04584 case SIG_FXSLS: /* only interesting for FXS */ 04585 case SIG_FXSGS: 04586 case SIG_FXSKS: 04587 case SIG_EM: 04588 case SIG_EM_E1: 04589 case SIG_EMWINK: 04590 case SIG_FEATD: 04591 case SIG_SF: 04592 case SIG_SFWINK: 04593 case SIG_SF_FEATD: 04594 if (!ast_strlen_zero(p->dop.dialstr)) { 04595 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04596 if (res < 0) { 04597 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04598 p->dop.dialstr[0] = '\0'; 04599 return NULL; 04600 } else 04601 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04602 } 04603 p->dop.dialstr[0] = '\0'; 04604 p->dop.op = ZT_DIAL_OP_REPLACE; 04605 break; 04606 case SIG_FEATDMF: 04607 case SIG_FEATDMF_TA: 04608 case SIG_E911: 04609 case SIG_FGC_CAMA: 04610 case SIG_FGC_CAMAMF: 04611 case SIG_FEATB: 04612 case SIG_SF_FEATDMF: 04613 case SIG_SF_FEATB: 04614 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04615 break; 04616 default: 04617 break; 04618 } 04619 break; 04620 case ZT_EVENT_POLARITY: 04621 /* 04622 * If we get a Polarity Switch event, check to see 04623 * if we should change the polarity state and 04624 * mark the channel as UP or if this is an indication 04625 * of remote end disconnect. 04626 */ 04627 if (p->polarity == POLARITY_IDLE) { 04628 p->polarity = POLARITY_REV; 04629 if (p->answeronpolarityswitch && 04630 ((ast->_state == AST_STATE_DIALING) || 04631 (ast->_state == AST_STATE_RINGING))) { 04632 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04633 ast_setstate(p->owner, AST_STATE_UP); 04634 if (p->hanguponpolarityswitch) { 04635 gettimeofday(&p->polaritydelaytv, NULL); 04636 } 04637 } else 04638 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04639 } 04640 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04641 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04642 if (p->hanguponpolarityswitch && 04643 (p->polarityonanswerdelay > 0) && 04644 (p->polarity == POLARITY_REV) && 04645 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04646 /* Added log_debug information below to provide a better indication of what is going on */ 04647 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) ); 04648 04649 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04650 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04651 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04652 p->polarity = POLARITY_IDLE; 04653 } else { 04654 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); 04655 } 04656 } else { 04657 p->polarity = POLARITY_IDLE; 04658 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04659 } 04660 /* Added more log_debug information below to provide a better indication of what is going on */ 04661 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) ); 04662 break; 04663 default: 04664 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04665 } 04666 return &p->subs[index].f; 04667 }
static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2520 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_DIALING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, 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_subchannel::inthreeway, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_ERROR, 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_GSM, 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().
02521 { 02522 int res; 02523 int index,x, law; 02524 /*static int restore_gains(struct zt_pvt *p);*/ 02525 struct zt_pvt *p = ast->tech_pvt; 02526 struct zt_pvt *tmp = NULL; 02527 struct zt_pvt *prev = NULL; 02528 ZT_PARAMS par; 02529 02530 if (option_debug) 02531 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02532 if (!ast->tech_pvt) { 02533 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02534 return 0; 02535 } 02536 02537 ast_mutex_lock(&p->lock); 02538 02539 index = zt_get_index(ast, p, 1); 02540 02541 if (p->sig == SIG_PRI) { 02542 x = 1; 02543 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02544 } 02545 02546 x = 0; 02547 zt_confmute(p, 0); 02548 restore_gains(p); 02549 if (p->origcid_num) { 02550 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02551 free(p->origcid_num); 02552 p->origcid_num = NULL; 02553 } 02554 if (p->origcid_name) { 02555 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02556 free(p->origcid_name); 02557 p->origcid_name = NULL; 02558 } 02559 if (p->dsp) 02560 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02561 if (p->exten) 02562 p->exten[0] = '\0'; 02563 02564 if (option_debug) 02565 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02566 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02567 02568 if (index > -1) { 02569 /* Real channel, do some fixup */ 02570 p->subs[index].owner = NULL; 02571 p->subs[index].needanswer = 0; 02572 p->subs[index].needflash = 0; 02573 p->subs[index].needringing = 0; 02574 p->subs[index].needbusy = 0; 02575 p->subs[index].needcongestion = 0; 02576 p->subs[index].linear = 0; 02577 p->subs[index].needcallerid = 0; 02578 p->polarity = POLARITY_IDLE; 02579 zt_setlinear(p->subs[index].zfd, 0); 02580 if (index == SUB_REAL) { 02581 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02582 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02583 if (p->subs[SUB_CALLWAIT].inthreeway) { 02584 /* We had flipped over to answer a callwait and now it's gone */ 02585 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02586 /* Move to the call-wait, but un-own us until they flip back. */ 02587 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02588 unalloc_sub(p, SUB_CALLWAIT); 02589 p->owner = NULL; 02590 } else { 02591 /* The three way hung up, but we still have a call wait */ 02592 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02593 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02594 unalloc_sub(p, SUB_THREEWAY); 02595 if (p->subs[SUB_REAL].inthreeway) { 02596 /* This was part of a three way call. Immediately make way for 02597 another call */ 02598 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02599 p->owner = p->subs[SUB_REAL].owner; 02600 } else { 02601 /* This call hasn't been completed yet... Set owner to NULL */ 02602 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02603 p->owner = NULL; 02604 } 02605 p->subs[SUB_REAL].inthreeway = 0; 02606 } 02607 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02608 /* Move to the call-wait and switch back to them. */ 02609 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02610 unalloc_sub(p, SUB_CALLWAIT); 02611 p->owner = p->subs[SUB_REAL].owner; 02612 if (p->owner->_state != AST_STATE_UP) 02613 p->subs[SUB_REAL].needanswer = 1; 02614 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02615 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 02616 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02617 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02618 unalloc_sub(p, SUB_THREEWAY); 02619 if (p->subs[SUB_REAL].inthreeway) { 02620 /* This was part of a three way call. Immediately make way for 02621 another call */ 02622 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02623 p->owner = p->subs[SUB_REAL].owner; 02624 } else { 02625 /* This call hasn't been completed yet... Set owner to NULL */ 02626 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02627 p->owner = NULL; 02628 } 02629 p->subs[SUB_REAL].inthreeway = 0; 02630 } 02631 } else if (index == SUB_CALLWAIT) { 02632 /* Ditch the holding callwait call, and immediately make it availabe */ 02633 if (p->subs[SUB_CALLWAIT].inthreeway) { 02634 /* This is actually part of a three way, placed on hold. Place the third part 02635 on music on hold now */ 02636 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 02637 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02638 S_OR(p->mohsuggest, NULL), 02639 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02640 } 02641 p->subs[SUB_THREEWAY].inthreeway = 0; 02642 /* Make it the call wait now */ 02643 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02644 unalloc_sub(p, SUB_THREEWAY); 02645 } else 02646 unalloc_sub(p, SUB_CALLWAIT); 02647 } else if (index == SUB_THREEWAY) { 02648 if (p->subs[SUB_CALLWAIT].inthreeway) { 02649 /* The other party of the three way call is currently in a call-wait state. 02650 Start music on hold for them, and take the main guy out of the third call */ 02651 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 02652 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02653 S_OR(p->mohsuggest, NULL), 02654 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02655 } 02656 p->subs[SUB_CALLWAIT].inthreeway = 0; 02657 } 02658 p->subs[SUB_REAL].inthreeway = 0; 02659 /* If this was part of a three way call index, let us make 02660 another three way call */ 02661 unalloc_sub(p, SUB_THREEWAY); 02662 } else { 02663 /* This wasn't any sort of call, but how are we an index? */ 02664 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02665 } 02666 } 02667 02668 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02669 int outgoing = p->outgoing; 02670 p->owner = NULL; 02671 p->ringt = 0; 02672 p->distinctivering = 0; 02673 p->confirmanswer = 0; 02674 p->cidrings = 1; 02675 p->outgoing = 0; 02676 p->digital = 0; 02677 p->faxhandled = 0; 02678 p->pulsedial = 0; 02679 p->onhooktime = time(NULL); 02680 #ifdef HAVE_PRI 02681 p->proceeding = 0; 02682 p->progress = 0; 02683 p->alerting = 0; 02684 p->setup_ack = 0; 02685 #endif 02686 if (p->dsp) { 02687 ast_dsp_free(p->dsp); 02688 p->dsp = NULL; 02689 } 02690 02691 law = ZT_LAW_DEFAULT; 02692 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02693 if (res < 0) 02694 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02695 /* Perform low level hangup if no owner left */ 02696 #ifdef HAVE_PRI 02697 if (p->pri) { 02698 #ifdef SUPPORT_USERUSER 02699 const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02700 #endif 02701 02702 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02703 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02704 if (!pri_grab(p, p->pri)) { 02705 if (p->alreadyhungup) { 02706 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02707 02708 #ifdef SUPPORT_USERUSER 02709 pri_call_set_useruser(p->call, useruser); 02710 #endif 02711 02712 pri_hangup(p->pri->pri, p->call, -1, -1); 02713 p->call = NULL; 02714 if (p->bearer) 02715 p->bearer->call = NULL; 02716 } else { 02717 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02718 int icause = ast->hangupcause ? ast->hangupcause : -1; 02719 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02720 02721 #ifdef SUPPORT_USERUSER 02722 pri_call_set_useruser(p->call, useruser); 02723 #endif 02724 02725 p->alreadyhungup = 1; 02726 if (p->bearer) 02727 p->bearer->alreadyhungup = 1; 02728 if (cause) { 02729 if (atoi(cause)) 02730 icause = atoi(cause); 02731 } 02732 02733 pri_hangup(p->pri->pri, p->call, icause, -1); 02734 02735 /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */ 02736 if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) { 02737 if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) { 02738 /* no-op */ 02739 } else { 02740 ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state); 02741 icause = 16; /* Note, in pri_hangup() libpri will already override the cause */ 02742 } 02743 p->call = NULL; 02744 } 02745 02746 if (p->pri->nodetype == BRI_NETWORK_PTMP) { 02747 if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) { 02748 if (outgoing) { 02749 p->call = NULL; 02750 } 02751 } 02752 } 02753 02754 02755 } 02756 if (res < 0) 02757 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02758 pri_rel(p->pri); 02759 } else { 02760 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02761 res = -1; 02762 } 02763 } else { 02764 if (p->bearer) 02765 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02766 p->call = NULL; 02767 res = 0; 02768 } 02769 } 02770 #endif 02771 #ifdef HAVE_GSMAT 02772 if (p->gsm.modul) { 02773 if (!p->alreadyhungup) 02774 gsm_hangup(p->gsm.modul); 02775 } 02776 #endif 02777 if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM)) 02778 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02779 if (res < 0) { 02780 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02781 } 02782 switch (p->sig) { 02783 case SIG_FXOGS: 02784 case SIG_FXOLS: 02785 case SIG_FXOKS: 02786 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02787 if (!res) { 02788 #if 0 02789 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02790 #endif 02791 /* If they're off hook, try playing congestion */ 02792 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02793 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02794 else 02795 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02796 } 02797 break; 02798 case SIG_FXSGS: 02799 case SIG_FXSLS: 02800 case SIG_FXSKS: 02801 /* Make sure we're not made available for at least two seconds assuming 02802 we were actually used for an inbound or outbound call. */ 02803 if (ast->_state != AST_STATE_RESERVED) { 02804 time(&p->guardtime); 02805 p->guardtime += 2; 02806 } 02807 break; 02808 default: 02809 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02810 } 02811 if (p->cidspill) 02812 free(p->cidspill); 02813 if (p->sig) 02814 zt_disable_ec(p); 02815 x = 0; 02816 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02817 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02818 p->didtdd = 0; 02819 p->cidspill = NULL; 02820 p->callwaitcas = 0; 02821 p->callwaiting = p->permcallwaiting; 02822 p->hidecallerid = p->permhidecallerid; 02823 p->dialing = 0; 02824 p->rdnis[0] = '\0'; 02825 update_conf(p); 02826 reset_conf(p); 02827 /* Restore data mode */ 02828 if (p->sig == SIG_PRI) { 02829 x = 0; 02830 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02831 } 02832 #ifdef HAVE_PRI 02833 if (p->bearer) { 02834 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02835 /* Free up the bearer channel as well, and 02836 don't use its file descriptor anymore */ 02837 update_conf(p->bearer); 02838 reset_conf(p->bearer); 02839 p->bearer->owner = NULL; 02840 p->bearer->realcall = NULL; 02841 p->bearer = NULL; 02842 p->subs[SUB_REAL].zfd = -1; 02843 p->pri = NULL; 02844 } 02845 #endif 02846 restart_monitor(); 02847 } 02848 02849 p->callwaitingrepeat = 0; 02850 p->cidcwexpire = 0; 02851 p->oprmode = 0; 02852 ast->tech_pvt = NULL; 02853 ast_mutex_unlock(&p->lock); 02854 ast_module_unref(ast_module_info->self); 02855 if (option_verbose > 2) 02856 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02857 02858 ast_mutex_lock(&iflock); 02859 tmp = iflist; 02860 prev = NULL; 02861 if (p->destroy) { 02862 while (tmp) { 02863 if (tmp == p) { 02864 destroy_channel(prev, tmp, 0); 02865 break; 02866 } else { 02867 prev = tmp; 02868 tmp = tmp->next; 02869 } 02870 } 02871 } 02872 ast_mutex_unlock(&iflock); 02873 return 0; 02874 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5185 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, LOG_WARNING, 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().
Referenced by zt_fixup().
05186 { 05187 struct zt_pvt *p = chan->tech_pvt; 05188 int res=-1; 05189 int index; 05190 int func = ZT_FLASH; 05191 ast_mutex_lock(&p->lock); 05192 index = zt_get_index(chan, p, 0); 05193 if (option_debug) 05194 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 05195 if (index == SUB_REAL) { 05196 switch (condition) { 05197 case AST_CONTROL_BUSY: 05198 #ifdef HAVE_PRI 05199 if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { 05200 chan->hangupcause = AST_CAUSE_USER_BUSY; 05201 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05202 res = 0; 05203 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05204 if (p->pri->pri) { 05205 if (!pri_grab(p, p->pri)) { 05206 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05207 pri_rel(p->pri); 05208 } 05209 else 05210 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05211 } 05212 p->progress = 1; 05213 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05214 } else 05215 #endif 05216 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05217 break; 05218 case AST_CONTROL_RINGING: 05219 #ifdef HAVE_PRI 05220 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05221 if (p->pri->pri) { 05222 if (!pri_grab(p, p->pri)) { 05223 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05224 pri_rel(p->pri); 05225 } 05226 else 05227 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05228 } 05229 p->alerting = 1; 05230 } 05231 #endif 05232 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05233 if (chan->_state != AST_STATE_UP) { 05234 if ((chan->_state != AST_STATE_RING) || 05235 ((p->sig != SIG_FXSKS) && 05236 (p->sig != SIG_FXSLS) && 05237 (p->sig != SIG_FXSGS))) 05238 ast_setstate(chan, AST_STATE_RINGING); 05239 } 05240 break; 05241 case AST_CONTROL_PROCEEDING: 05242 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05243 #ifdef HAVE_PRI 05244 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05245 if (p->pri->pri) { 05246 if (!pri_grab(p, p->pri)) { 05247 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05248 pri_rel(p->pri); 05249 } 05250 else 05251 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05252 } 05253 p->proceeding = 1; 05254 } 05255 #endif 05256 /* don't continue in ast_indicate */ 05257 res = 0; 05258 break; 05259 case AST_CONTROL_PROGRESS: 05260 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05261 #ifdef HAVE_PRI 05262 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05263 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05264 if (p->pri->pri) { 05265 if (!pri_grab(p, p->pri)) { 05266 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05267 pri_rel(p->pri); 05268 } 05269 else 05270 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05271 } 05272 p->progress = 1; 05273 } 05274 #endif 05275 /* don't continue in ast_indicate */ 05276 res = 0; 05277 break; 05278 case AST_CONTROL_CONGESTION: 05279 chan->hangupcause = AST_CAUSE_CONGESTION; 05280 #ifdef HAVE_PRI 05281 if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { 05282 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05283 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05284 res = 0; 05285 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05286 if (p->pri) { 05287 if (!pri_grab(p, p->pri)) { 05288 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05289 pri_rel(p->pri); 05290 } else 05291 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05292 } 05293 p->progress = 1; 05294 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05295 } else 05296 #endif 05297 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05298 break; 05299 case AST_CONTROL_HOLD: 05300 #ifdef HAVE_PRI 05301 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05302 if (!pri_grab(p, p->pri)) { 05303 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05304 pri_rel(p->pri); 05305 } else 05306 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05307 } else 05308 #endif 05309 ast_moh_start(chan, data, p->mohinterpret); 05310 break; 05311 case AST_CONTROL_UNHOLD: 05312 #ifdef HAVE_PRI 05313 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05314 if (!pri_grab(p, p->pri)) { 05315 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05316 pri_rel(p->pri); 05317 } else 05318 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05319 } else 05320 #endif 05321 ast_moh_stop(chan); 05322 break; 05323 case AST_CONTROL_RADIO_KEY: 05324 if (p->radio) 05325 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05326 res = 0; 05327 break; 05328 case AST_CONTROL_RADIO_UNKEY: 05329 if (p->radio) 05330 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05331 res = 0; 05332 break; 05333 case AST_CONTROL_FLASH: 05334 /* flash hookswitch */ 05335 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05336 /* Clear out the dial buffer */ 05337 p->dop.dialstr[0] = '\0'; 05338 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05339 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05340 chan->name, strerror(errno)); 05341 } else 05342 res = 0; 05343 } else 05344 res = 0; 05345 break; 05346 case AST_CONTROL_SRCUPDATE: 05347 res = 0; 05348 break; 05349 case -1: 05350 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05351 break; 05352 } 05353 } else 05354 res = 0; 05355 ast_mutex_unlock(&p->lock); 05356 return res; 05357 }
Definition at line 3232 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_DEBUG, LOG_WARNING, zt_pvt::master, MAX_SLAVES, and zt_pvt::slaves.
Referenced by zt_bridge().
03232 { 03233 int x; 03234 if (!slave || !master) { 03235 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03236 return; 03237 } 03238 for (x = 0; x < MAX_SLAVES; x++) { 03239 if (!master->slaves[x]) { 03240 master->slaves[x] = slave; 03241 break; 03242 } 03243 } 03244 if (x >= MAX_SLAVES) { 03245 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03246 master->slaves[MAX_SLAVES - 1] = slave; 03247 } 03248 if (slave->master) 03249 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03250 slave->master = master; 03251 03252 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03253 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | i, | |
int | state, | |||
int | startpbx, | |||
int | index, | |||
int | law, | |||
int | transfercapability | |||
) | [static, read] |
> b2 can be freed now, it's been copied into the channel structure
Definition at line 5359 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, LOG_WARNING, 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, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
05360 { 05361 struct ast_channel *tmp; 05362 int deflaw; 05363 int res; 05364 int x,y; 05365 int features; 05366 char *b2 = NULL; 05367 ZT_PARAMS ps; 05368 if (i->subs[index].owner) { 05369 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05370 return NULL; 05371 } 05372 y = 1; 05373 do { 05374 if (b2) 05375 free(b2); 05376 #ifdef HAVE_PRI 05377 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05378 b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05379 else 05380 #endif 05381 if (i->channel == CHAN_PSEUDO) 05382 b2 = ast_safe_string_alloc("pseudo-%ld", ast_random()); 05383 else 05384 b2 = ast_safe_string_alloc("%d-%d", i->channel, y); 05385 for (x = 0; x < 3; x++) { 05386 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05387 break; 05388 } 05389 y++; 05390 } while (x < 3); 05391 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2); 05392 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05393 free(b2); 05394 if (!tmp) 05395 return NULL; 05396 tmp->tech = &zap_tech; 05397 ps.channo = i->channel; 05398 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05399 if (res) { 05400 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05401 ps.curlaw = ZT_LAW_MULAW; 05402 } 05403 if (ps.curlaw == ZT_LAW_ALAW) 05404 deflaw = AST_FORMAT_ALAW; 05405 else 05406 deflaw = AST_FORMAT_ULAW; 05407 if (law) { 05408 if (law == ZT_LAW_ALAW) 05409 deflaw = AST_FORMAT_ALAW; 05410 else 05411 deflaw = AST_FORMAT_ULAW; 05412 } 05413 tmp->fds[0] = i->subs[index].zfd; 05414 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05415 /* Start out assuming ulaw since it's smaller :) */ 05416 tmp->rawreadformat = deflaw; 05417 tmp->readformat = deflaw; 05418 tmp->rawwriteformat = deflaw; 05419 tmp->writeformat = deflaw; 05420 i->subs[index].linear = 0; 05421 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05422 features = 0; 05423 if (index == SUB_REAL) { 05424 if (i->busydetect && CANBUSYDETECT(i)) 05425 features |= DSP_FEATURE_BUSY_DETECT; 05426 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05427 features |= DSP_FEATURE_CALL_PROGRESS; 05428 if ((!i->outgoing && (i->callprogress & 4)) || 05429 (i->outgoing && (i->callprogress & 2))) { 05430 features |= DSP_FEATURE_FAX_DETECT; 05431 } 05432 #ifdef ZT_TONEDETECT 05433 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05434 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05435 #endif 05436 i->hardwaredtmf = 0; 05437 features |= DSP_FEATURE_DTMF_DETECT; 05438 #ifdef ZT_TONEDETECT 05439 } else if (NEED_MFDETECT(i)) { 05440 i->hardwaredtmf = 1; 05441 features |= DSP_FEATURE_DTMF_DETECT; 05442 } 05443 #endif 05444 } 05445 if (features) { 05446 if (i->dsp) { 05447 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05448 } else { 05449 if (i->channel != CHAN_PSEUDO) 05450 i->dsp = ast_dsp_new(); 05451 else 05452 i->dsp = NULL; 05453 if (i->dsp) { 05454 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05455 #ifdef HAVE_PRI 05456 /* We cannot do progress detection until receives PROGRESS message */ 05457 if (i->outgoing && (i->sig == SIG_PRI)) { 05458 /* Remember requested DSP features, don't treat 05459 talking as ANSWER */ 05460 features = 0; 05461 } 05462 #endif 05463 ast_dsp_set_features(i->dsp, features); 05464 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05465 if (!ast_strlen_zero(progzone)) 05466 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05467 if (i->busydetect && CANBUSYDETECT(i)) { 05468 ast_dsp_set_busy_count(i->dsp, i->busycount); 05469 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05470 } 05471 } 05472 } 05473 } 05474 05475 if (state == AST_STATE_RING) 05476 tmp->rings = 1; 05477 tmp->tech_pvt = i; 05478 #ifdef HAVE_PRI 05479 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) { 05480 #else 05481 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05482 #endif 05483 /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */ 05484 tmp->callgroup = i->callgroup; 05485 tmp->pickupgroup = i->pickupgroup; 05486 } 05487 if (!ast_strlen_zero(i->language)) 05488 ast_string_field_set(tmp, language, i->language); 05489 if (!i->owner) 05490 i->owner = tmp; 05491 if (!ast_strlen_zero(i->accountcode)) 05492 ast_string_field_set(tmp, accountcode, i->accountcode); 05493 if (i->amaflags) 05494 tmp->amaflags = i->amaflags; 05495 i->subs[index].owner = tmp; 05496 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05497 ast_string_field_set(tmp, call_forward, i->call_forward); 05498 /* If we've been told "no ADSI" then enforce it */ 05499 if (!i->adsi) 05500 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05501 if (!ast_strlen_zero(i->exten)) 05502 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05503 if (!ast_strlen_zero(i->rdnis)) 05504 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05505 if (!ast_strlen_zero(i->dnid)) 05506 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05507 05508 /* Don't use ast_set_callerid() here because it will 05509 * generate a needless NewCallerID event */ 05510 #ifdef PRI_ANI 05511 if (!ast_strlen_zero(i->cid_ani)) 05512 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05513 else 05514 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05515 #else 05516 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05517 #endif 05518 tmp->cid.cid_pres = i->callingpres; 05519 tmp->cid.cid_ton = i->cid_ton; 05520 #ifdef HAVE_PRI 05521 tmp->transfercapability = transfercapability; 05522 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05523 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05524 i->digital = 1; 05525 /* Assume calls are not idle calls unless we're told differently */ 05526 i->isidlecall = 0; 05527 i->alreadyhungup = 0; 05528 #endif 05529 /* clear the fake event in case we posted one before we had ast_channel */ 05530 i->fake_event = 0; 05531 /* Assure there is no confmute on this channel */ 05532 zt_confmute(i, 0); 05533 /* Configure the new channel jb */ 05534 ast_jb_configure(tmp, &global_jbconf); 05535 if (startpbx) { 05536 if (ast_pbx_start(tmp)) { 05537 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05538 ast_hangup(tmp); 05539 i->owner = NULL; 05540 return NULL; 05541 } 05542 } 05543 05544 ast_module_ref(ast_module_info->self); 05545 05546 return tmp; 05547 }
static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 925 of file chan_zap.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
00926 { 00927 int fd; 00928 int isnum; 00929 int chan = 0; 00930 int bs; 00931 int x; 00932 isnum = 1; 00933 for (x = 0; x < strlen(fn); x++) { 00934 if (!isdigit(fn[x])) { 00935 isnum = 0; 00936 break; 00937 } 00938 } 00939 if (isnum) { 00940 chan = atoi(fn); 00941 if (chan < 1) { 00942 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 00943 return -1; 00944 } 00945 fn = "/dev/zap/channel"; 00946 } 00947 fd = open(fn, O_RDWR | O_NONBLOCK); 00948 if (fd < 0) { 00949 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 00950 return -1; 00951 } 00952 if (chan) { 00953 if (ioctl(fd, ZT_SPECIFY, &chan)) { 00954 x = errno; 00955 close(fd); 00956 errno = x; 00957 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 00958 return -1; 00959 } 00960 } 00961 bs = READ_SIZE; 00962 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) { 00963 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 00964 x = errno; 00965 close(fd); 00966 errno = x; 00967 return -1; 00968 } 00969 return fd; 00970 }
static struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4787 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, zt_pvt::fake_event, zt_pvt::firstradio, ast_frame::frametype, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, 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().
04788 { 04789 struct zt_pvt *p = ast->tech_pvt; 04790 int res; 04791 int index; 04792 void *readbuf; 04793 struct ast_frame *f; 04794 04795 04796 ast_mutex_lock(&p->lock); 04797 04798 index = zt_get_index(ast, p, 0); 04799 04800 /* Hang up if we don't really exist */ 04801 if (index < 0) { 04802 ast_log(LOG_WARNING, "We dont exist?\n"); 04803 ast_mutex_unlock(&p->lock); 04804 return NULL; 04805 } 04806 04807 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04808 04809 p->subs[index].f.frametype = AST_FRAME_NULL; 04810 p->subs[index].f.datalen = 0; 04811 p->subs[index].f.samples = 0; 04812 p->subs[index].f.mallocd = 0; 04813 p->subs[index].f.offset = 0; 04814 p->subs[index].f.subclass = 0; 04815 p->subs[index].f.delivery = ast_tv(0,0); 04816 p->subs[index].f.src = "zt_read"; 04817 p->subs[index].f.data = NULL; 04818 04819 /* make sure it sends initial key state as first frame */ 04820 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04821 { 04822 ZT_PARAMS ps; 04823 04824 ps.channo = p->channel; 04825 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04826 ast_mutex_unlock(&p->lock); 04827 return NULL; 04828 } 04829 p->firstradio = 1; 04830 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04831 if (ps.rxisoffhook) 04832 { 04833 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04834 } 04835 else 04836 { 04837 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04838 } 04839 ast_mutex_unlock(&p->lock); 04840 return &p->subs[index].f; 04841 } 04842 if (p->ringt == 1) { 04843 ast_mutex_unlock(&p->lock); 04844 return NULL; 04845 } 04846 else if (p->ringt > 0) 04847 p->ringt--; 04848 04849 if (p->subs[index].needringing) { 04850 /* Send ringing frame if requested */ 04851 p->subs[index].needringing = 0; 04852 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04853 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04854 ast_setstate(ast, AST_STATE_RINGING); 04855 ast_mutex_unlock(&p->lock); 04856 return &p->subs[index].f; 04857 } 04858 04859 if (p->subs[index].needbusy) { 04860 /* Send busy frame if requested */ 04861 p->subs[index].needbusy = 0; 04862 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04863 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04864 ast_mutex_unlock(&p->lock); 04865 return &p->subs[index].f; 04866 } 04867 04868 if (p->subs[index].needcongestion) { 04869 /* Send congestion frame if requested */ 04870 p->subs[index].needcongestion = 0; 04871 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04872 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04873 ast_mutex_unlock(&p->lock); 04874 return &p->subs[index].f; 04875 } 04876 04877 if (p->subs[index].needcallerid) { 04878 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04879 S_OR(p->lastcid_name, NULL), 04880 S_OR(p->lastcid_num, NULL) 04881 ); 04882 p->subs[index].needcallerid = 0; 04883 } 04884 04885 if (p->subs[index].needanswer) { 04886 /* Send answer frame if requested */ 04887 p->subs[index].needanswer = 0; 04888 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04889 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04890 ast_mutex_unlock(&p->lock); 04891 return &p->subs[index].f; 04892 } 04893 04894 if (p->subs[index].needflash) { 04895 /* Send answer frame if requested */ 04896 p->subs[index].needflash = 0; 04897 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04898 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04899 ast_mutex_unlock(&p->lock); 04900 return &p->subs[index].f; 04901 } 04902 04903 if (p->subs[index].needhold) { 04904 /* Send answer frame if requested */ 04905 p->subs[index].needhold = 0; 04906 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04907 p->subs[index].f.subclass = AST_CONTROL_HOLD; 04908 ast_mutex_unlock(&p->lock); 04909 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 04910 return &p->subs[index].f; 04911 } 04912 04913 if (p->subs[index].needunhold) { 04914 /* Send answer frame if requested */ 04915 p->subs[index].needunhold = 0; 04916 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04917 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 04918 ast_mutex_unlock(&p->lock); 04919 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 04920 return &p->subs[index].f; 04921 } 04922 04923 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04924 if (!p->subs[index].linear) { 04925 p->subs[index].linear = 1; 04926 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04927 if (res) 04928 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04929 } 04930 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04931 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04932 if (p->subs[index].linear) { 04933 p->subs[index].linear = 0; 04934 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04935 if (res) 04936 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04937 } 04938 } else { 04939 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04940 ast_mutex_unlock(&p->lock); 04941 return NULL; 04942 } 04943 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04944 CHECK_BLOCKING(ast); 04945 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04946 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04947 /* Check for hangup */ 04948 if (res < 0) { 04949 f = NULL; 04950 if (res == -1) { 04951 if (errno == EAGAIN) { 04952 /* Return "NULL" frame if there is nobody there */ 04953 ast_mutex_unlock(&p->lock); 04954 return &p->subs[index].f; 04955 } else if (errno == ELAST) { 04956 f = __zt_exception(ast); 04957 } else 04958 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04959 } 04960 ast_mutex_unlock(&p->lock); 04961 return f; 04962 } 04963 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04964 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04965 f = __zt_exception(ast); 04966 ast_mutex_unlock(&p->lock); 04967 return f; 04968 } 04969 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04970 int c; 04971 04972 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04973 if (c < 0) { 04974 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04975 ast_mutex_unlock(&p->lock); 04976 return NULL; 04977 } 04978 if (c) { /* if a char to return */ 04979 p->subs[index].f.subclass = 0; 04980 p->subs[index].f.frametype = AST_FRAME_TEXT; 04981 p->subs[index].f.mallocd = 0; 04982 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04983 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04984 p->subs[index].f.datalen = 1; 04985 *((char *) p->subs[index].f.data) = c; 04986 ast_mutex_unlock(&p->lock); 04987 return &p->subs[index].f; 04988 } 04989 } 04990 /* Ensure the CW timer decrements only on a single subchannel */ 04991 if (p->callwaitingrepeat && zt_get_index(ast, p, 1) == SUB_REAL) { 04992 p->callwaitingrepeat--; 04993 } 04994 if (p->cidcwexpire) 04995 p->cidcwexpire--; 04996 /* Repeat callwaiting */ 04997 if (p->callwaitingrepeat == 1) { 04998 p->callwaitrings++; 04999 zt_callwait(ast); 05000 } 05001 /* Expire CID/CW */ 05002 if (p->cidcwexpire == 1) { 05003 if (option_verbose > 2) 05004 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 05005 restore_conference(p); 05006 } 05007 if (p->subs[index].linear) { 05008 p->subs[index].f.datalen = READ_SIZE * 2; 05009 } else 05010 p->subs[index].f.datalen = READ_SIZE; 05011 05012 /* Handle CallerID Transmission */ 05013 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 05014 send_callerid(p); 05015 } 05016 05017 p->subs[index].f.frametype = AST_FRAME_VOICE; 05018 p->subs[index].f.subclass = ast->rawreadformat; 05019 p->subs[index].f.samples = READ_SIZE; 05020 p->subs[index].f.mallocd = 0; 05021 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 05022 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 05023 #if 0 05024 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 05025 #endif 05026 if (p->dialing || /* Transmitting something */ 05027 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 05028 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 05029 ) { 05030 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 05031 don't send anything */ 05032 p->subs[index].f.frametype = AST_FRAME_NULL; 05033 p->subs[index].f.subclass = 0; 05034 p->subs[index].f.samples = 0; 05035 p->subs[index].f.mallocd = 0; 05036 p->subs[index].f.offset = 0; 05037 p->subs[index].f.data = NULL; 05038 p->subs[index].f.datalen= 0; 05039 } 05040 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 05041 /* Perform busy detection. etc on the zap line */ 05042 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 05043 if (f) { 05044 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 05045 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 05046 /* Treat this as a "hangup" instead of a "busy" on the assumption that 05047 a busy */ 05048 f = NULL; 05049 } 05050 } else if (f->frametype == AST_FRAME_DTMF) { 05051 #ifdef HAVE_PRI 05052 if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) { 05053 /* Don't accept in-band DTMF when in overlap dial mode 05054 or when in non-overlap overlapdialing mode ... */ 05055 f->frametype = AST_FRAME_NULL; 05056 f->subclass = 0; 05057 } 05058 #endif 05059 /* DSP clears us of being pulse */ 05060 p->pulsedial = 0; 05061 } 05062 } 05063 } else 05064 f = &p->subs[index].f; 05065 05066 if (f && (f->frametype == AST_FRAME_DTMF)) 05067 zt_handle_dtmfup(ast, index, &f); 05068 05069 /* If we have a fake_event, trigger exception to handle it */ 05070 if (p->fake_event) 05071 ast_set_flag(ast, AST_FLAG_EXCEPTION); 05072 05073 ast_mutex_unlock(&p->lock); 05074 return f; 05075 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 8041 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_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), busy, ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, zt_subchannel::zfd, and zt_new().
08042 { 08043 ast_group_t groupmatch = 0; 08044 int channelmatch = -1; 08045 int roundrobin = 0; 08046 int callwait = 0; 08047 int busy = 0; 08048 struct zt_pvt *p; 08049 struct ast_channel *tmp = NULL; 08050 char *dest=NULL; 08051 int x; 08052 char *s; 08053 char opt=0; 08054 int res=0, y=0; 08055 int backwards = 0; 08056 #ifdef HAVE_PRI 08057 int crv; 08058 int bearer = -1; 08059 int trunkgroup; 08060 struct zt_pri *pri=NULL; 08061 #endif 08062 struct zt_pvt *exit, *start, *end; 08063 ast_mutex_t *lock; 08064 int channelmatched = 0; 08065 int groupmatched = 0; 08066 08067 /* Assume we're locking the iflock */ 08068 lock = &iflock; 08069 start = iflist; 08070 end = ifend; 08071 if (data) { 08072 dest = ast_strdupa((char *)data); 08073 } else { 08074 ast_log(LOG_WARNING, "Channel requested with no data\n"); 08075 return NULL; 08076 } 08077 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 08078 /* Retrieve the group number */ 08079 char *stringp=NULL; 08080 stringp=dest + 1; 08081 s = strsep(&stringp, "/"); 08082 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 08083 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 08084 return NULL; 08085 } 08086 groupmatch = ((ast_group_t) 1 << x); 08087 if (toupper(dest[0]) == 'G') { 08088 if (dest[0] == 'G') { 08089 backwards = 1; 08090 p = ifend; 08091 } else 08092 p = iflist; 08093 } else { 08094 if (dest[0] == 'R') { 08095 backwards = 1; 08096 p = round_robin[x]?round_robin[x]->prev:ifend; 08097 if (!p) 08098 p = ifend; 08099 } else { 08100 p = round_robin[x]?round_robin[x]->next:iflist; 08101 if (!p) 08102 p = iflist; 08103 } 08104 roundrobin = 1; 08105 } 08106 } else { 08107 char *stringp=NULL; 08108 stringp=dest; 08109 s = strsep(&stringp, "/"); 08110 p = iflist; 08111 if (!strcasecmp(s, "pseudo")) { 08112 /* Special case for pseudo */ 08113 x = CHAN_PSEUDO; 08114 channelmatch = x; 08115 } 08116 #ifdef HAVE_PRI 08117 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 08118 if ((trunkgroup < 1) || (crv < 1)) { 08119 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 08120 return NULL; 08121 } 08122 res--; 08123 for (x = 0; x < NUM_SPANS; x++) { 08124 if (pris[x].trunkgroup == trunkgroup) { 08125 pri = pris + x; 08126 lock = &pri->lock; 08127 start = pri->crvs; 08128 end = pri->crvend; 08129 break; 08130 } 08131 } 08132 if (!pri) { 08133 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 08134 return NULL; 08135 } 08136 channelmatch = crv; 08137 p = pris[x].crvs; 08138 } 08139 #endif 08140 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 08141 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 08142 return NULL; 08143 } else { 08144 channelmatch = x; 08145 } 08146 } 08147 /* Search for an unowned channel */ 08148 ast_mutex_lock(lock); 08149 exit = p; 08150 while (p && !tmp) { 08151 if (roundrobin) 08152 round_robin[x] = p; 08153 #if 0 08154 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 08155 #endif 08156 08157 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 08158 if (option_debug) 08159 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 08160 if (p->inalarm) 08161 goto next; 08162 08163 callwait = (p->owner != NULL); 08164 #ifdef HAVE_PRI 08165 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 08166 if (p->sig != SIG_FXSKS) { 08167 /* Gotta find an actual channel to use for this 08168 CRV if this isn't a callwait */ 08169 bearer = pri_find_empty_chan(pri, 0); 08170 if (bearer < 0) { 08171 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 08172 p = NULL; 08173 break; 08174 } 08175 pri_assign_bearer(p, pri, pri->pvts[bearer]); 08176 } else { 08177 if (alloc_sub(p, 0)) { 08178 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 08179 p = NULL; 08180 break; 08181 } else 08182 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 08183 p->pri = pri; 08184 } 08185 } 08186 #endif 08187 if (p->channel == CHAN_PSEUDO) { 08188 p = chandup(p); 08189 if (!p) { 08190 break; 08191 } 08192 } 08193 if (p->owner) { 08194 if (alloc_sub(p, SUB_CALLWAIT)) { 08195 p = NULL; 08196 break; 08197 } 08198 } 08199 p->outgoing = 1; 08200 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 08201 #ifdef HAVE_PRI 08202 if (p->bearer) { 08203 /* Log owner to bearer channel, too */ 08204 p->bearer->owner = tmp; 08205 } 08206 #endif 08207 /* Make special notes */ 08208 if (res > 1) { 08209 if (opt == 'c') { 08210 /* Confirm answer */ 08211 p->confirmanswer = 1; 08212 } else if (opt == 'r') { 08213 /* Distinctive ring */ 08214 if (res < 3) 08215 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 08216 else 08217 p->distinctivering = y; 08218 } else if (opt == 'd') { 08219 /* If this is an ISDN call, make it digital */ 08220 p->digital = 1; 08221 if (tmp) 08222 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 08223 } else if (opt == 'm') { 08224 /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */ 08225 p->faxhandled = 1; 08226 if (tmp) 08227 tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO; 08228 } else { 08229 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 08230 } 08231 } 08232 /* Note if the call is a call waiting call */ 08233 if (tmp && callwait) 08234 tmp->cdrflags |= AST_CDR_CALLWAIT; 08235 break; 08236 } 08237 next: 08238 if (backwards) { 08239 p = p->prev; 08240 if (!p) 08241 p = end; 08242 } else { 08243 p = p->next; 08244 if (!p) 08245 p = start; 08246 } 08247 /* stop when you roll to the one that we started from */ 08248 if (p == exit) 08249 break; 08250 } 08251 ast_mutex_unlock(lock); 08252 restart_monitor(); 08253 if (callwait) 08254 *cause = AST_CAUSE_BUSY; 08255 else if (!tmp) { 08256 if (channelmatched) { 08257 if (busy) 08258 *cause = AST_CAUSE_BUSY; 08259 } else if (groupmatched) { 08260 *cause = AST_CAUSE_CONGESTION; 08261 } else { 08262 *cause = AST_CAUSE_CONGESTION; 08263 } 08264 } 08265 08266 return tmp; 08267 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3616 of file chan_zap.c.
References ast_log(), errno, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), and zt_handle_event().
03617 { 03618 int x; 03619 int res; 03620 /* Make sure our transmit state is on hook */ 03621 x = 0; 03622 x = ZT_ONHOOK; 03623 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03624 do { 03625 x = ZT_RING; 03626 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03627 if (res) { 03628 switch (errno) { 03629 case EBUSY: 03630 case EINTR: 03631 /* Wait just in case */ 03632 usleep(10000); 03633 continue; 03634 case EINPROGRESS: 03635 res = 0; 03636 break; 03637 default: 03638 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03639 res = 0; 03640 } 03641 } 03642 } while (res); 03643 return res; 03644 }
static int zt_sendmessage | ( | struct ast_channel * | c, | |
const char * | dest, | |||
const char * | text, | |||
int | ispdu | |||
) | [static] |
Definition at line 12852 of file chan_zap.c.
References ast_log(), LOG_WARNING, zt_pvt::sig, SIG_GSM, SIG_PRI, ast_channel::tech_pvt, and zt_tdd_sendtext().
12852 { 12853 struct zt_pvt *p = c->tech_pvt; 12854 if (!p) return -1; 12855 if (p->sig == SIG_PRI) { 12856 #ifdef HAVE_PRI 12857 if (ispdu) { 12858 ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n"); 12859 return -1; 12860 } 12861 return zt_pri_sendtext(c, text); 12862 #endif 12863 } else if (p->sig == SIG_GSM) { 12864 #ifdef HAVE_GSMAT 12865 return zt_gsm_sendtext(c, dest, text, ispdu); 12866 #endif 12867 } else { 12868 if (ispdu) { 12869 ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP channel\n"); 12870 return -1; 12871 } 12872 return zt_tdd_sendtext(c, text); 12873 } 12874 return -1; 12875 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 12838 of file chan_zap.c.
References zt_pvt::sig, SIG_GSM, SIG_PRI, ast_channel::tech_pvt, and zt_tdd_sendtext().
12838 { 12839 struct zt_pvt *p = c->tech_pvt; 12840 if (!p) return -1; 12841 if (p->sig == SIG_PRI) { 12842 #ifdef HAVE_PRI 12843 return zt_pri_sendtext(c, text); 12844 #endif 12845 } else if (p->sig == SIG_GSM) { 12846 } else { 12847 return zt_tdd_sendtext(c, text); 12848 } 12849 return -1; 12850 }
static int zt_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 1674 of file chan_zap.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by __zt_exception(), handle_init_event(), mkintf(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().
01675 { 01676 int x, res; 01677 01678 x = hs; 01679 res = ioctl(fd, ZT_HOOK, &x); 01680 01681 if (res < 0) { 01682 if (errno == EINPROGRESS) 01683 return 0; 01684 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01685 } 01686 01687 return res; 01688 }
static int zt_setlaw | ( | int | zfd, | |
int | law | |||
) | [static] |
Definition at line 2510 of file chan_zap.c.
02511 { 02512 int res; 02513 res = ioctl(zfd, ZT_SETLAW, &law); 02514 if (res) 02515 return res; 02516 return 0; 02517 }
static int zt_setlinear | ( | int | zfd, | |
int | linear | |||
) | [static] |
Definition at line 978 of file chan_zap.c.
Referenced by send_callerid(), ss_thread(), zt_hangup(), zt_new(), zt_read(), and zt_write().
00979 { 00980 int res; 00981 res = ioctl(zfd, ZT_SETLINEAR, &linear); 00982 if (res) 00983 return res; 00984 return 0; 00985 }
static int zt_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2972 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().
02973 { 02974 char *cp; 02975 signed char *scp; 02976 int x; 02977 int index; 02978 struct zt_pvt *p = chan->tech_pvt, *pp; 02979 struct oprmode *oprmode; 02980 02981 02982 /* all supported options require data */ 02983 if (!data || (datalen < 1)) { 02984 errno = EINVAL; 02985 return -1; 02986 } 02987 02988 switch (option) { 02989 case AST_OPTION_TXGAIN: 02990 scp = (signed char *) data; 02991 index = zt_get_index(chan, p, 0); 02992 if (index < 0) { 02993 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02994 return -1; 02995 } 02996 if (option_debug) 02997 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02998 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02999 case AST_OPTION_RXGAIN: 03000 scp = (signed char *) data; 03001 index = zt_get_index(chan, p, 0); 03002 if (index < 0) { 03003 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 03004 return -1; 03005 } 03006 if (option_debug) 03007 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 03008 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 03009 case AST_OPTION_TONE_VERIFY: 03010 if (!p->dsp) 03011 break; 03012 cp = (char *) data; 03013 switch (*cp) { 03014 case 1: 03015 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 03016 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 03017 break; 03018 case 2: 03019 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 03020 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 03021 break; 03022 default: 03023 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 03024 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 03025 break; 03026 } 03027 break; 03028 case AST_OPTION_TDD: 03029 /* turn on or off TDD */ 03030 cp = (char *) data; 03031 p->mate = 0; 03032 if (!*cp) { /* turn it off */ 03033 if (option_debug) 03034 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 03035 if (p->tdd) 03036 tdd_free(p->tdd); 03037 p->tdd = 0; 03038 break; 03039 } 03040 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 03041 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 03042 zt_disable_ec(p); 03043 /* otherwise, turn it on */ 03044 if (!p->didtdd) { /* if havent done it yet */ 03045 unsigned char mybuf[41000], *buf; 03046 int size, res, fd, len; 03047 struct pollfd fds[1]; 03048 03049 buf = mybuf; 03050 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 03051 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 03052 len = 40000; 03053 index = zt_get_index(chan, p, 0); 03054 if (index < 0) { 03055 ast_log(LOG_WARNING, "No index in TDD?\n"); 03056 return -1; 03057 } 03058 fd = p->subs[index].zfd; 03059 while (len) { 03060 if (ast_check_hangup(chan)) 03061 return -1; 03062 size = len; 03063 if (size > READ_SIZE) 03064 size = READ_SIZE; 03065 fds[0].fd = fd; 03066 fds[0].events = POLLPRI | POLLOUT; 03067 fds[0].revents = 0; 03068 res = poll(fds, 1, -1); 03069 if (!res) { 03070 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 03071 continue; 03072 } 03073 /* if got exception */ 03074 if (fds[0].revents & POLLPRI) 03075 return -1; 03076 if (!(fds[0].revents & POLLOUT)) { 03077 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 03078 continue; 03079 } 03080 res = write(fd, buf, size); 03081 if (res != size) { 03082 if (res == -1) return -1; 03083 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 03084 break; 03085 } 03086 len -= size; 03087 buf += size; 03088 } 03089 p->didtdd = 1; /* set to have done it now */ 03090 } 03091 if (*cp == 2) { /* Mate mode */ 03092 if (p->tdd) 03093 tdd_free(p->tdd); 03094 p->tdd = 0; 03095 p->mate = 1; 03096 break; 03097 } 03098 if (!p->tdd) { /* if we dont have one yet */ 03099 p->tdd = tdd_new(); /* allocate one */ 03100 } 03101 break; 03102 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 03103 if (!p->dsp) 03104 break; 03105 cp = (char *) data; 03106 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 03107 *cp ? "ON" : "OFF", (int) *cp, chan->name); 03108 p->dtmfrelax = 0; 03109 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 03110 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 03111 break; 03112 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 03113 cp = (char *) data; 03114 if (!*cp) { 03115 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 03116 x = 0; 03117 zt_disable_ec(p); 03118 } else { 03119 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 03120 x = 1; 03121 } 03122 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 03123 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 03124 break; 03125 case AST_OPTION_OPRMODE: /* Operator services mode */ 03126 oprmode = (struct oprmode *) data; 03127 pp = oprmode->peer->tech_pvt; 03128 p->oprmode = pp->oprmode = 0; 03129 /* setup peers */ 03130 p->oprpeer = pp; 03131 pp->oprpeer = p; 03132 /* setup modes, if any */ 03133 if (oprmode->mode) 03134 { 03135 pp->oprmode = oprmode->mode; 03136 p->oprmode = -oprmode->mode; 03137 } 03138 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 03139 oprmode->mode, chan->name,oprmode->peer->name);; 03140 break; 03141 case AST_OPTION_ECHOCAN: 03142 cp = (char *) data; 03143 if (*cp) { 03144 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 03145 zt_enable_ec(p); 03146 } else { 03147 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 03148 zt_disable_ec(p); 03149 } 03150 break; 03151 } 03152 errno = 0; 03153 03154 return 0; 03155 }
static int zt_tdd_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 12877 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_DEBUG, LOG_ERROR, LOG_WARNING, 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().
Referenced by zt_sendmessage(), and zt_sendtext().
12878 { 12879 #define END_SILENCE_LEN 400 12880 #define HEADER_MS 50 12881 #define TRAILER_MS 5 12882 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 12883 #define ASCII_BYTES_PER_CHAR 80 12884 12885 unsigned char *buf,*mybuf; 12886 struct zt_pvt *p = c->tech_pvt; 12887 struct pollfd fds[1]; 12888 int size,res,fd,len,x; 12889 int bytes=0; 12890 /* Initial carrier (imaginary) */ 12891 float cr = 1.0; 12892 float ci = 0.0; 12893 float scont = 0.0; 12894 int index; 12895 12896 12897 index = zt_get_index(c, p, 0); 12898 if (index < 0) { 12899 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 12900 return -1; 12901 } 12902 if (!text[0]) return(0); /* if nothing to send, dont */ 12903 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 12904 if (p->mate) 12905 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 12906 else 12907 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 12908 if (!buf) 12909 return -1; 12910 mybuf = buf; 12911 if (p->mate) { 12912 int codec = AST_LAW(p); 12913 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 12914 PUT_CLID_MARKMS; 12915 } 12916 /* Put actual message */ 12917 for (x = 0; text[x]; x++) { 12918 PUT_CLID(text[x]); 12919 } 12920 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 12921 PUT_CLID_MARKMS; 12922 } 12923 len = bytes; 12924 buf = mybuf; 12925 } else { 12926 len = tdd_generate(p->tdd, buf, text); 12927 if (len < 1) { 12928 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 12929 free(mybuf); 12930 return -1; 12931 } 12932 } 12933 memset(buf + len, 0x7f, END_SILENCE_LEN); 12934 len += END_SILENCE_LEN; 12935 fd = p->subs[index].zfd; 12936 while (len) { 12937 if (ast_check_hangup(c)) { 12938 free(mybuf); 12939 return -1; 12940 } 12941 size = len; 12942 if (size > READ_SIZE) 12943 size = READ_SIZE; 12944 fds[0].fd = fd; 12945 fds[0].events = POLLOUT | POLLPRI; 12946 fds[0].revents = 0; 12947 res = poll(fds, 1, -1); 12948 if (!res) { 12949 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 12950 continue; 12951 } 12952 /* if got exception */ 12953 if (fds[0].revents & POLLPRI) { 12954 ast_free(mybuf); 12955 return -1; 12956 } 12957 if (!(fds[0].revents & POLLOUT)) { 12958 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 12959 continue; 12960 } 12961 res = write(fd, buf, size); 12962 if (res != size) { 12963 if (res == -1) { 12964 free(mybuf); 12965 return -1; 12966 } 12967 if (option_debug) 12968 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 12969 break; 12970 } 12971 len -= size; 12972 buf += size; 12973 } 12974 free(mybuf); 12975 return(0); 12976 }
static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1506 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echotraining, zt_pvt::faxhandled, LOG_DEBUG, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_answer(), and zt_handle_event().
01507 { 01508 int x; 01509 int res; 01510 if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) { 01511 x = p->echotraining; 01512 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01513 if (res) 01514 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01515 else { 01516 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01517 } 01518 } else 01519 ast_log(LOG_DEBUG, "No echo training requested\n"); 01520 }
Definition at line 3176 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), zt_pvt::channel, conf_del(), DEADLOCK_AVOIDANCE, zt_pvt::inconference, zt_pvt::lock, LOG_DEBUG, zt_pvt::master, MAX_SLAVES, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and update_conf().
Referenced by zt_bridge(), and zt_fixup().
03177 { 03178 /* Unlink a specific slave or all slaves/masters from a given master */ 03179 int x; 03180 int hasslaves; 03181 if (!master) 03182 return; 03183 if (needlock) { 03184 ast_mutex_lock(&master->lock); 03185 if (slave) { 03186 while (ast_mutex_trylock(&slave->lock)) { 03187 DEADLOCK_AVOIDANCE(&master->lock); 03188 } 03189 } 03190 } 03191 hasslaves = 0; 03192 for (x = 0; x < MAX_SLAVES; x++) { 03193 if (master->slaves[x]) { 03194 if (!slave || (master->slaves[x] == slave)) { 03195 /* Take slave out of the conference */ 03196 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03197 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03198 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03199 master->slaves[x]->master = NULL; 03200 master->slaves[x] = NULL; 03201 } else 03202 hasslaves = 1; 03203 } 03204 if (!hasslaves) 03205 master->inconference = 0; 03206 } 03207 if (!slave) { 03208 if (master->master) { 03209 /* Take master out of the conference */ 03210 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03211 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03212 hasslaves = 0; 03213 for (x = 0; x < MAX_SLAVES; x++) { 03214 if (master->master->slaves[x] == master) 03215 master->master->slaves[x] = NULL; 03216 else if (master->master->slaves[x]) 03217 hasslaves = 1; 03218 } 03219 if (!hasslaves) 03220 master->master->inconference = 0; 03221 } 03222 master->master = NULL; 03223 } 03224 update_conf(master); 03225 if (needlock) { 03226 if (slave) 03227 ast_mutex_unlock(&slave->lock); 03228 ast_mutex_unlock(&master->lock); 03229 } 03230 }
static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 272 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00273 { 00274 int i, j = 0; 00275 i = ZT_IOMUX_SIGEVENT; 00276 if (ioctl(fd, ZT_IOMUX, &i) == -1) 00277 return -1; 00278 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00279 return -1; 00280 return j; 00281 }
static int zt_wink | ( | struct zt_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 5569 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05570 { 05571 int j; 05572 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05573 for (;;) 05574 { 05575 /* set bits of interest */ 05576 j = ZT_IOMUX_SIGEVENT; 05577 /* wait for some happening */ 05578 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05579 /* exit loop if we have it */ 05580 if (j & ZT_IOMUX_SIGEVENT) break; 05581 } 05582 /* get the event info */ 05583 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05584 return 0; 05585 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 5100 of file chan_zap.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_TEXT, 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, LOG_NOTICE, LOG_WARNING, 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().
05101 { 05102 struct zt_pvt *p = ast->tech_pvt; 05103 int res; 05104 int index; 05105 index = zt_get_index(ast, p, 0); 05106 if (index < 0) { 05107 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 05108 return -1; 05109 } 05110 05111 #if 0 05112 #ifdef HAVE_PRI 05113 ast_mutex_lock(&p->lock); 05114 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05115 if (p->pri->pri) { 05116 if (!pri_grab(p, p->pri)) { 05117 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05118 pri_rel(p->pri); 05119 } else 05120 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05121 } 05122 p->proceeding=1; 05123 } 05124 ast_mutex_unlock(&p->lock); 05125 #endif 05126 #endif 05127 /* Write a frame of (presumably voice) data */ 05128 if (frame->frametype != AST_FRAME_VOICE) { 05129 if (frame->frametype == AST_FRAME_TEXT) { 05130 ast_log(LOG_NOTICE, "text\n"); 05131 } else if (frame->frametype != AST_FRAME_IMAGE) 05132 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 05133 return 0; 05134 } 05135 if ((frame->subclass != AST_FORMAT_SLINEAR) && 05136 (frame->subclass != AST_FORMAT_ULAW) && 05137 (frame->subclass != AST_FORMAT_ALAW)) { 05138 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 05139 return -1; 05140 } 05141 if (p->dialing) { 05142 if (option_debug) 05143 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 05144 return 0; 05145 } 05146 if (!p->owner) { 05147 if (option_debug) 05148 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 05149 return 0; 05150 } 05151 if (p->cidspill) { 05152 if (option_debug) 05153 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 05154 return 0; 05155 } 05156 /* Return if it's not valid data */ 05157 if (!frame->data || !frame->datalen) 05158 return 0; 05159 05160 if (frame->subclass == AST_FORMAT_SLINEAR) { 05161 if (!p->subs[index].linear) { 05162 p->subs[index].linear = 1; 05163 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05164 if (res) 05165 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 05166 } 05167 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 05168 } else { 05169 /* x-law already */ 05170 if (p->subs[index].linear) { 05171 p->subs[index].linear = 0; 05172 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05173 if (res) 05174 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 05175 } 05176 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 05177 } 05178 if (res < 0) { 05179 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05180 return -1; 05181 } 05182 return 0; 05183 }
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 797 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 808 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 173 of file chan_zap.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 117 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 213 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 214 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 11510 of file chan_zap.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 218 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 124 of file chan_zap.c.
char gsm_modem_exten[AST_MAX_EXTENSION] [static] |
Definition at line 242 of file chan_zap.c.
char gsm_modem_pin[20] [static] |
Definition at line 241 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 244 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 236 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 252 of file chan_zap.c.
char* name |
Definition at line 1179 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 794 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 220 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 216 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 297 of file chan_zap.c.
struct zt_pvt* round_robin[32] |
Definition at line 767 of file chan_zap.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 11502 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 11498 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 167 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 795 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
Definition at line 11521 of file chan_zap.c.
char zap_restart_usage[] [static] |
Definition at line 11514 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 11406 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 11506 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 737 of file chan_zap.c.
char* zapEC_app = "zapEC" [static] |
Definition at line 11159 of file chan_zap.c.
char* zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel" [static] |
Definition at line 11160 of file chan_zap.c.
char* zapEC_tdesc = "Enable/disable Echo cancelation" [static] |
Definition at line 11158 of file chan_zap.c.