#include "asterisk.h"
#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <math.h>
#include <ctype.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj.h"
Include dependency graph for chan_zap.c:
Go to the source code of this file.
Data Structures | |
struct | distRingData |
struct | ringContextData |
struct | zt_chan_conf |
Channel configuration from zapata.conf . This struct is used for parsing the [channels] section of zapata.conf. Generally there is a field here for every possible configuration item. More... | |
struct | zt_distRings |
struct | zt_pvt |
struct | zt_subchannel |
Defines | |
#define | ASCII_BYTES_PER_CHAR 80 |
#define | AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
#define | CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define | CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
#define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CHAN_PSEUDO -2 |
#define | CHANNEL_PSEUDO -12 |
#define | CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define | CONF_USER_REAL (1 << 0) |
#define | CONF_USER_THIRDCALL (1 << 1) |
#define | DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 1) |
#define | DCHAN_PROVISIONED (1 << 0) |
#define | DCHAN_UP (1 << 2) |
#define | DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID. | |
#define | DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
#define | END_SILENCE_LEN 400 |
#define | FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | GET_CHANNEL(p) ((p)->channel) |
#define | HANGUP 1 |
#define | HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
#define | HEADER_MS 50 |
#define | ISTRUNK(p) |
#define | MASK_AVAIL (1 << 0) |
#define | MASK_INUSE (1 << 1) |
#define | MAX_CHANLIST_LEN 80 |
#define | MAX_CHANNELS 672 |
#define | MAX_SLAVES 4 |
#define | MIN_MS_SINCE_FLASH ( (2000) ) |
#define | NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro. | |
#define | NUM_CADENCE_MAX 25 |
#define | NUM_DCHANS 4 |
#define | NUM_SPANS 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 |
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 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(), 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.
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) |
Definition at line 764 of file chan_zap.c.
#define HANGUP 1 |
Definition at line 11544 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 11908 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 |
#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 |
Definition at line 793 of file chan_zap.c.
#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 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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 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(), 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(), 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(), 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(), 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(), 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 12994 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 11725 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, zap_cli, zap_tech, zapEC_app, zt_subchannel::zfd, and zt_close().
11726 { 11727 int x; 11728 struct zt_pvt *p, *pl; 11729 11730 #ifdef HAVE_PRI 11731 int i; 11732 for (i = 0; i < NUM_SPANS; i++) { 11733 if (pris[i].master != AST_PTHREADT_NULL) 11734 pthread_cancel(pris[i].master); 11735 } 11736 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 11737 ast_unregister_application(zap_send_keypad_facility_app); 11738 ast_unregister_application(zapCD_app); 11739 ast_unregister_application(zapInband_app); 11740 #endif 11741 #ifdef HAVE_GSMAT 11742 ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); 11743 ast_cli_unregister(&gsm_send_sms); 11744 ast_cli_unregister(&gsm_send_pdu); 11745 ast_cli_unregister(&gsm_show_status); 11746 #endif 11747 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 11748 ast_unregister_application(zapEC_app); 11749 ast_manager_unregister( "ZapDialOffhook" ); 11750 ast_manager_unregister( "ZapHangup" ); 11751 ast_manager_unregister( "ZapTransfer" ); 11752 ast_manager_unregister( "ZapDNDoff" ); 11753 ast_manager_unregister( "ZapDNDon" ); 11754 ast_manager_unregister("ZapShowChannels"); 11755 ast_manager_unregister("ZapRestart"); 11756 ast_channel_unregister(&zap_tech); 11757 ast_mutex_lock(&iflock); 11758 /* Hangup all interfaces if they have an owner */ 11759 p = iflist; 11760 while (p) { 11761 if (p->owner) 11762 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 11763 p = p->next; 11764 } 11765 ast_mutex_unlock(&iflock); 11766 ast_mutex_lock(&monlock); 11767 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 11768 pthread_cancel(monitor_thread); 11769 pthread_kill(monitor_thread, SIGURG); 11770 pthread_join(monitor_thread, NULL); 11771 } 11772 monitor_thread = AST_PTHREADT_STOP; 11773 ast_mutex_unlock(&monlock); 11774 11775 ast_mutex_lock(&iflock); 11776 /* Destroy all the interfaces and free their memory */ 11777 p = iflist; 11778 while (p) { 11779 /* Free any callerid */ 11780 if (p->cidspill) 11781 free(p->cidspill); 11782 /* Close the zapata thingy */ 11783 if (p->subs[SUB_REAL].zfd > -1) 11784 zt_close(p->subs[SUB_REAL].zfd); 11785 pl = p; 11786 p = p->next; 11787 x = pl->channel; 11788 /* Free associated memory */ 11789 if (pl) 11790 destroy_zt_pvt(&pl); 11791 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 11792 } 11793 iflist = NULL; 11794 ifcount = 0; 11795 ast_mutex_unlock(&iflock); 11796 #ifdef HAVE_PRI 11797 for (i = 0; i < NUM_SPANS; i++) { 11798 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 11799 pthread_join(pris[i].master, NULL); 11800 zt_close(pris[i].fds[i]); 11801 } 11802 #endif 11803 return 0; 11804 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4668 of file chan_zap.c.
References ast_bridged_channel(), AST_CONTROL_UNHOLD, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, event2str(), zt_subchannel::f, f, zt_pvt::fake_event, ast_channel::fds, ast_frame::frametype, LOG_DEBUG, ast_frame::mallocd, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_debug, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().
Referenced by zt_exception(), and zt_read().
04669 { 04670 struct zt_pvt *p = ast->tech_pvt; 04671 int res; 04672 int usedindex=-1; 04673 int index; 04674 struct ast_frame *f; 04675 04676 04677 index = zt_get_index(ast, p, 1); 04678 04679 p->subs[index].f.frametype = AST_FRAME_NULL; 04680 p->subs[index].f.datalen = 0; 04681 p->subs[index].f.samples = 0; 04682 p->subs[index].f.mallocd = 0; 04683 p->subs[index].f.offset = 0; 04684 p->subs[index].f.subclass = 0; 04685 p->subs[index].f.delivery = ast_tv(0,0); 04686 p->subs[index].f.src = "zt_exception"; 04687 p->subs[index].f.data = NULL; 04688 04689 04690 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04691 /* If nobody owns us, absorb the event appropriately, otherwise 04692 we loop indefinitely. This occurs when, during call waiting, the 04693 other end hangs up our channel so that it no longer exists, but we 04694 have neither FLASH'd nor ONHOOK'd to signify our desire to 04695 change to the other channel. */ 04696 if (p->fake_event) { 04697 res = p->fake_event; 04698 p->fake_event = 0; 04699 } else 04700 res = zt_get_event(p->subs[SUB_REAL].zfd); 04701 /* Switch to real if there is one and this isn't something really silly... */ 04702 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04703 (res != ZT_EVENT_HOOKCOMPLETE)) { 04704 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04705 p->owner = p->subs[SUB_REAL].owner; 04706 if (p->owner && ast_bridged_channel(p->owner)) 04707 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04708 p->subs[SUB_REAL].needunhold = 1; 04709 } 04710 switch (res) { 04711 case ZT_EVENT_ONHOOK: 04712 zt_disable_ec(p); 04713 if (p->owner) { 04714 if (option_verbose > 2) 04715 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04716 zt_ring_phone(p); 04717 p->callwaitingrepeat = 0; 04718 p->cidcwexpire = 0; 04719 } else 04720 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04721 update_conf(p); 04722 break; 04723 case ZT_EVENT_RINGOFFHOOK: 04724 zt_enable_ec(p); 04725 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04726 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04727 p->subs[SUB_REAL].needanswer = 1; 04728 p->dialing = 0; 04729 } 04730 break; 04731 case ZT_EVENT_HOOKCOMPLETE: 04732 case ZT_EVENT_RINGERON: 04733 case ZT_EVENT_RINGEROFF: 04734 /* Do nothing */ 04735 break; 04736 case ZT_EVENT_WINKFLASH: 04737 gettimeofday(&p->flashtime, NULL); 04738 if (p->owner) { 04739 if (option_verbose > 2) 04740 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04741 if (p->owner->_state != AST_STATE_UP) { 04742 /* Answer if necessary */ 04743 usedindex = zt_get_index(p->owner, p, 0); 04744 if (usedindex > -1) { 04745 p->subs[usedindex].needanswer = 1; 04746 } 04747 ast_setstate(p->owner, AST_STATE_UP); 04748 } 04749 p->callwaitingrepeat = 0; 04750 p->cidcwexpire = 0; 04751 if (ast_bridged_channel(p->owner)) 04752 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04753 p->subs[SUB_REAL].needunhold = 1; 04754 } else 04755 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04756 update_conf(p); 04757 break; 04758 default: 04759 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04760 } 04761 f = &p->subs[index].f; 04762 return f; 04763 } 04764 if (!(p->radio || (p->oprmode < 0)) && option_debug) 04765 ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04766 /* If it's not us, return NULL immediately */ 04767 if (ast != p->owner) { 04768 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04769 f = &p->subs[index].f; 04770 return f; 04771 } 04772 f = zt_handle_event(ast); 04773 return f; 04774 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11612 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), s, TRANSFER, and zap_fake_event().
Referenced by load_module().
11613 { 11614 struct zt_pvt *p = NULL; 11615 const char *channel = astman_get_header(m, "ZapChannel"); 11616 11617 if (ast_strlen_zero(channel)) { 11618 astman_send_error(s, m, "No channel specified"); 11619 return 0; 11620 } 11621 p = find_channel(atoi(channel)); 11622 if (!p) { 11623 astman_send_error(s, m, "No such channel"); 11624 return 0; 11625 } 11626 zap_fake_event(p,TRANSFER); 11627 astman_send_ack(s, m, "ZapTransfer"); 11628 return 0; 11629 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11631 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, s, and zap_fake_event().
Referenced by load_module().
11632 { 11633 struct zt_pvt *p = NULL; 11634 const char *channel = astman_get_header(m, "ZapChannel"); 11635 11636 if (ast_strlen_zero(channel)) { 11637 astman_send_error(s, m, "No channel specified"); 11638 return 0; 11639 } 11640 p = find_channel(atoi(channel)); 11641 if (!p) { 11642 astman_send_error(s, m, "No such channel"); 11643 return 0; 11644 } 11645 zap_fake_event(p,HANGUP); 11646 astman_send_ack(s, m, "ZapHangup"); 11647 return 0; 11648 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11650 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), f, find_channel(), zt_pvt::owner, s, and zap_queue_frame().
Referenced by load_module().
11651 { 11652 struct zt_pvt *p = NULL; 11653 const char *channel = astman_get_header(m, "ZapChannel"); 11654 const char *number = astman_get_header(m, "Number"); 11655 int i; 11656 11657 if (ast_strlen_zero(channel)) { 11658 astman_send_error(s, m, "No channel specified"); 11659 return 0; 11660 } 11661 if (ast_strlen_zero(number)) { 11662 astman_send_error(s, m, "No number specified"); 11663 return 0; 11664 } 11665 p = find_channel(atoi(channel)); 11666 if (!p) { 11667 astman_send_error(s, m, "No such channel"); 11668 return 0; 11669 } 11670 if (!p->owner) { 11671 astman_send_error(s, m, "Channel does not have it's owner"); 11672 return 0; 11673 } 11674 for (i = 0; i < strlen(number); i++) { 11675 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 11676 zap_queue_frame(p, &f, NULL); 11677 } 11678 astman_send_ack(s, m, "ZapDialOffhook"); 11679 return 0; 11680 }
static int action_zapdndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11593 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.
Referenced by load_module().
11594 { 11595 struct zt_pvt *p = NULL; 11596 const char *channel = astman_get_header(m, "ZapChannel"); 11597 11598 if (ast_strlen_zero(channel)) { 11599 astman_send_error(s, m, "No channel specified"); 11600 return 0; 11601 } 11602 p = find_channel(atoi(channel)); 11603 if (!p) { 11604 astman_send_error(s, m, "No such channel"); 11605 return 0; 11606 } 11607 p->dnd = 0; 11608 astman_send_ack(s, m, "DND Disabled"); 11609 return 0; 11610 }
static int action_zapdndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11574 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.
Referenced by load_module().
11575 { 11576 struct zt_pvt *p = NULL; 11577 const char *channel = astman_get_header(m, "ZapChannel"); 11578 11579 if (ast_strlen_zero(channel)) { 11580 astman_send_error(s, m, "No channel specified"); 11581 return 0; 11582 } 11583 p = find_channel(atoi(channel)); 11584 if (!p) { 11585 astman_send_error(s, m, "No such channel"); 11586 return 0; 11587 } 11588 p->dnd = 1; 11589 astman_send_ack(s, m, "DND Enabled"); 11590 return 0; 11591 }
static int action_zaprestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11201 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), s, and zap_restart().
Referenced by load_module().
11202 { 11203 if (zap_restart() != 0) { 11204 astman_send_error(s, m, "Failed rereading zaptel configuration"); 11205 return 1; 11206 } 11207 astman_send_ack(s, m, "ZapRestart: Success"); 11208 return 0; 11209 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11682 of file chan_zap.c.
References alarm, alarm2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, s, zt_pvt::sig, and sig2str.
Referenced by load_module().
11683 { 11684 struct zt_pvt *tmp = NULL; 11685 const char *id = astman_get_header(m, "ActionID"); 11686 char idText[256] = ""; 11687 11688 astman_send_ack(s, m, "Zapata channel status will follow"); 11689 if (!ast_strlen_zero(id)) 11690 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 11691 11692 ast_mutex_lock(&iflock); 11693 11694 tmp = iflist; 11695 while (tmp) { 11696 if (tmp->channel > 0) { 11697 int alarm = get_alarms(tmp); 11698 astman_append(s, 11699 "Event: ZapShowChannels\r\n" 11700 "Channel: %d\r\n" 11701 "Signalling: %s\r\n" 11702 "Context: %s\r\n" 11703 "DND: %s\r\n" 11704 "Alarm: %s\r\n" 11705 "%s" 11706 "\r\n", 11707 tmp->channel, sig2str(tmp->sig), tmp->context, 11708 tmp->dnd ? "Enabled" : "Disabled", 11709 alarm2str(alarm), idText); 11710 } 11711 11712 tmp = tmp->next; 11713 } 11714 11715 ast_mutex_unlock(&iflock); 11716 11717 astman_append(s, 11718 "Event: ZapShowChannelsComplete\r\n" 11719 "%s" 11720 "\r\n", 11721 idText); 11722 return 0; 11723 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1190 of file chan_zap.c.
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 11120 of file chan_zap.c.
References ast_log(), ast_verbose(), 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().
11121 { 11122 int res=-1; 11123 struct zt_pvt *p = NULL; 11124 11125 if (!data) { 11126 ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n"); 11127 } 11128 if (chan && !strcasecmp("ZAP",chan->tech->type)) { 11129 p = chan->tech_pvt; 11130 if (!p) return res; 11131 if (!strcasecmp("on",(char *)data)) { 11132 zt_enable_ec(p); 11133 res = 0; 11134 if (option_verbose > 3) { 11135 ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name); 11136 } 11137 } else if (!strcasecmp("off",(char *)data)) { 11138 zt_disable_ec(p); 11139 res = 0; 11140 if (option_verbose > 3) { 11141 ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name); 11142 } 11143 } else { 11144 ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data); 11145 } 11146 } else { 11147 ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n"); 11148 res = 0; 11149 } 11150 11151 return res; 11152 }
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 3649 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_indicate(), ast_log(), ast_mutex_unlock(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.
03650 { 03651 /* In order to transfer, we need at least one of the channels to 03652 actually be in a call bridge. We can't conference two applications 03653 together (but then, why would we want to?) */ 03654 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03655 /* The three-way person we're about to transfer to could still be in MOH, so 03656 stop if now if appropriate */ 03657 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03658 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03659 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03660 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03661 } 03662 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03663 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03664 } 03665 if (p->subs[SUB_REAL].owner->cdr) { 03666 /* Move CDR from second channel to current one */ 03667 p->subs[SUB_THREEWAY].owner->cdr = 03668 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03669 p->subs[SUB_REAL].owner->cdr = NULL; 03670 } 03671 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03672 /* Move CDR from second channel's bridge to current one */ 03673 p->subs[SUB_THREEWAY].owner->cdr = 03674 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03675 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03676 } 03677 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03678 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03679 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03680 return -1; 03681 } 03682 /* Orphan the channel after releasing the lock */ 03683 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03684 unalloc_sub(p, SUB_THREEWAY); 03685 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03686 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03687 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03688 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03689 } 03690 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03691 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03692 } 03693 if (p->subs[SUB_THREEWAY].owner->cdr) { 03694 /* Move CDR from second channel to current one */ 03695 p->subs[SUB_REAL].owner->cdr = 03696 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03697 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03698 } 03699 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03700 /* Move CDR from second channel's bridge to current one */ 03701 p->subs[SUB_REAL].owner->cdr = 03702 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03703 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03704 } 03705 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03706 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03707 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03708 return -1; 03709 } 03710 /* Three-way is now the REAL */ 03711 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03712 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03713 unalloc_sub(p, SUB_THREEWAY); 03714 /* Tell the caller not to hangup */ 03715 return 1; 03716 } else { 03717 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03718 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03719 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03720 return -1; 03721 } 03722 return 0; 03723 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
ast_group_t | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7865 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, zt_pvt::oprmode, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_request().
07866 { 07867 int res; 07868 ZT_PARAMS par; 07869 07870 /* First, check group matching */ 07871 if (groupmatch) { 07872 if ((p->group & groupmatch) != groupmatch) 07873 return 0; 07874 *groupmatched = 1; 07875 } 07876 /* Check to see if we have a channel match */ 07877 if (channelmatch != -1) { 07878 if (p->channel != channelmatch) 07879 return 0; 07880 *channelmatched = 1; 07881 } 07882 /* We're at least busy at this point */ 07883 if (busy) { 07884 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07885 *busy = 1; 07886 } 07887 /* If do not disturb, definitely not */ 07888 if (p->dnd) 07889 return 0; 07890 /* If guard time, definitely not */ 07891 if (p->guardtime && (time(NULL) < p->guardtime)) 07892 return 0; 07893 07894 /* If no owner definitely available */ 07895 if (!p->owner) { 07896 #ifdef HAVE_PRI 07897 /* Trust PRI */ 07898 if (p->pri) { 07899 if (p->resetting || p->call) 07900 return 0; 07901 else 07902 return 1; 07903 } 07904 #endif 07905 #ifdef HAVE_GSMAT 07906 if (p->gsm.modul) { 07907 return gsm_available(p->gsm.modul); 07908 } 07909 07910 #endif 07911 if (!(p->radio || (p->oprmode < 0))) 07912 { 07913 if (!p->sig || (p->sig == SIG_FXSLS)) 07914 return 1; 07915 /* Check hook state */ 07916 if (p->subs[SUB_REAL].zfd > -1) 07917 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07918 else { 07919 /* Assume not off hook on CVRS */ 07920 res = 0; 07921 par.rxisoffhook = 0; 07922 } 07923 if (res) { 07924 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07925 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07926 /* When "onhook" that means no battery on the line, and thus 07927 it is out of service..., if it's on a TDM card... If it's a channel 07928 bank, there is no telling... */ 07929 if (par.rxbits > -1) 07930 return 1; 07931 if (par.rxisoffhook) 07932 return 1; 07933 else 07934 #ifdef ZAP_CHECK_HOOKSTATE 07935 return 0; 07936 #else 07937 return 1; 07938 #endif 07939 } else if (par.rxisoffhook) { 07940 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07941 /* Not available when the other end is off hook */ 07942 return 0; 07943 } 07944 } 07945 return 1; 07946 } 07947 07948 /* If it's not an FXO, forget about call wait */ 07949 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07950 return 0; 07951 07952 if (!p->callwaiting) { 07953 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07954 return 0; 07955 } 07956 07957 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07958 /* If there is already a call waiting call, then we can't take a second one */ 07959 return 0; 07960 } 07961 07962 if ((p->owner->_state != AST_STATE_UP) && 07963 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07964 /* If the current call is not up, then don't allow the call */ 07965 return 0; 07966 } 07967 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07968 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07969 return 0; 07970 } 07971 /* We're cool */ 07972 return 1; 07973 }
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 11816 of file chan_zap.c.
References ast_log(), ast_strdupa, ast_verbose(), zt_chan_conf::chan, CHAN_PSEUDO, HAVE_PRI, LOG_ERROR, mkintf(), option_verbose, zt_pvt::sig, sig2str, strsep(), and VERBOSE_PREFIX_3.
Referenced by process_zap().
11817 { 11818 char *c, *chan; 11819 int x, start, finish; 11820 struct zt_pvt *tmp; 11821 #ifdef HAVE_PRI 11822 struct zt_pri *pri; 11823 int trunkgroup, y; 11824 #endif 11825 11826 if ((reload == 0) && (conf->chan.sig < 0)) { 11827 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 11828 return -1; 11829 } 11830 11831 c = ast_strdupa(value); 11832 11833 #ifdef HAVE_PRI 11834 pri = NULL; 11835 if (iscrv) { 11836 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 11837 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 11838 return -1; 11839 } 11840 if (trunkgroup < 1) { 11841 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 11842 return -1; 11843 } 11844 c += y; 11845 for (y = 0; y < NUM_SPANS; y++) { 11846 if (pris[y].trunkgroup == trunkgroup) { 11847 pri = pris + y; 11848 break; 11849 } 11850 } 11851 if (!pri) { 11852 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 11853 return -1; 11854 } 11855 } 11856 #endif 11857 11858 while ((chan = strsep(&c, ","))) { 11859 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 11860 /* Range */ 11861 } else if (sscanf(chan, "%d", &start)) { 11862 /* Just one */ 11863 finish = start; 11864 } else if (!strcasecmp(chan, "pseudo")) { 11865 finish = start = CHAN_PSEUDO; 11866 if (found_pseudo) 11867 *found_pseudo = 1; 11868 } else { 11869 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 11870 return -1; 11871 } 11872 if (finish < start) { 11873 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 11874 x = finish; 11875 finish = start; 11876 start = x; 11877 } 11878 11879 for (x = start; x <= finish; x++) { 11880 #ifdef HAVE_PRI 11881 tmp = mkintf(x, conf, pri, reload); 11882 #else 11883 tmp = mkintf(x, conf, NULL, reload); 11884 #endif 11885 11886 if (tmp) { 11887 if (option_verbose > 2) { 11888 #ifdef HAVE_PRI 11889 if (pri) 11890 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 11891 else 11892 #endif 11893 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 11894 } 11895 } else { 11896 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 11897 (reload == 1) ? "reconfigure" : "register", value); 11898 return -1; 11899 } 11900 } 11901 } 11902 11903 return 0; 11904 }
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 7975 of file chan_zap.c.
References ast_log(), ast_malloc, ast_mutex_init(), destroy_zt_pvt(), errno, iflist, LOG_ERROR, oh323_pvt::next, SUB_REAL, and zt_open().
Referenced by zt_request().
07976 { 07977 struct zt_pvt *p; 07978 ZT_BUFFERINFO bi; 07979 int res; 07980 07981 if ((p = ast_malloc(sizeof(*p)))) { 07982 memcpy(p, src, sizeof(struct zt_pvt)); 07983 ast_mutex_init(&p->lock); 07984 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07985 /* Allocate a zapata structure */ 07986 if (p->subs[SUB_REAL].zfd < 0) { 07987 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07988 destroy_zt_pvt(&p); 07989 return NULL; 07990 } 07991 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07992 if (!res) { 07993 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07994 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07995 bi.numbufs = numbufs; 07996 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07997 if (res < 0) { 07998 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 07999 } 08000 } else 08001 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 08002 } 08003 p->destroy = 1; 08004 p->next = iflist; 08005 p->prev = NULL; 08006 iflist = p; 08007 if (iflist->next) 08008 iflist->next->prev = p; 08009 return p; 08010 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3725 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_subchannel::zfd.
Referenced by zt_handle_event().
03726 { 03727 ZT_CONFINFO ci; 03728 /* Fine if we already have a master, etc */ 03729 if (p->master || (p->confno > -1)) 03730 return 0; 03731 memset(&ci, 0, sizeof(ci)); 03732 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03733 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03734 return 0; 03735 } 03736 /* If we have no master and don't have a confno, then 03737 if we're in a conference, it's probably a MeetMe room or 03738 some such, so don't let us 3-way out! */ 03739 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03740 if (option_verbose > 2) 03741 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03742 return 1; 03743 } 03744 return 0; 03745 }
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 3254 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().
03255 { 03256 #ifdef ZT_TONEDETECT 03257 int val; 03258 #endif 03259 03260 p->ignoredtmf = 1; 03261 03262 #ifdef ZT_TONEDETECT 03263 val = 0; 03264 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03265 #endif 03266 if (!p->hardwaredtmf && p->dsp) { 03267 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03268 ast_dsp_set_features(p->dsp, p->dsp_features); 03269 } 03270 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 7008 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::cidspill, pollfd::events, pollfd::fd, free, iflist, last, LOG_DEBUG, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
07009 { 07010 int count, res, res2, spoint, pollres=0; 07011 struct zt_pvt *i; 07012 struct zt_pvt *last = NULL; 07013 time_t thispass = 0, lastpass = 0; 07014 int found; 07015 char buf[1024]; 07016 struct pollfd *pfds=NULL; 07017 int lastalloc = -1; 07018 /* This thread monitors all the frame relay interfaces which are not yet in use 07019 (and thus do not have a separate thread) indefinitely */ 07020 /* From here on out, we die whenever asked */ 07021 #if 0 07022 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 07023 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 07024 return NULL; 07025 } 07026 ast_log(LOG_DEBUG, "Monitor starting...\n"); 07027 #endif 07028 for (;;) { 07029 /* Lock the interface list */ 07030 ast_mutex_lock(&iflock); 07031 if (!pfds || (lastalloc != ifcount)) { 07032 if (pfds) { 07033 free(pfds); 07034 pfds = NULL; 07035 } 07036 if (ifcount) { 07037 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 07038 ast_mutex_unlock(&iflock); 07039 return NULL; 07040 } 07041 } 07042 lastalloc = ifcount; 07043 } 07044 /* Build the stuff we're going to poll on, that is the socket of every 07045 zt_pvt that does not have an associated owner channel */ 07046 count = 0; 07047 i = iflist; 07048 while (i) { 07049 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 07050 if (!i->owner && !i->subs[SUB_REAL].owner) { 07051 /* This needs to be watched, as it lacks an owner */ 07052 pfds[count].fd = i->subs[SUB_REAL].zfd; 07053 pfds[count].events = POLLPRI; 07054 pfds[count].revents = 0; 07055 /* Message waiting or r2 channels also get watched for reading */ 07056 if (i->cidspill) 07057 pfds[count].events |= POLLIN; 07058 count++; 07059 } 07060 } 07061 i = i->next; 07062 } 07063 /* Okay, now that we know what to do, release the interface lock */ 07064 ast_mutex_unlock(&iflock); 07065 07066 pthread_testcancel(); 07067 /* Wait at least a second for something to happen */ 07068 res = poll(pfds, count, 1000); 07069 pthread_testcancel(); 07070 /* Okay, poll has finished. Let's see what happened. */ 07071 if (res < 0) { 07072 if ((errno != EAGAIN) && (errno != EINTR)) 07073 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 07074 continue; 07075 } 07076 /* Alright, lock the interface list again, and let's look and see what has 07077 happened */ 07078 ast_mutex_lock(&iflock); 07079 found = 0; 07080 spoint = 0; 07081 lastpass = thispass; 07082 thispass = time(NULL); 07083 i = iflist; 07084 while (i) { 07085 if (thispass != lastpass) { 07086 if (!found && ((i == last) || ((i == iflist) && !last))) { 07087 last = i; 07088 if (last) { 07089 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 07090 (last->sig & __ZT_SIG_FXO)) { 07091 res = ast_app_has_voicemail(last->mailbox, NULL); 07092 if (last->msgstate != res) { 07093 int x; 07094 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 07095 x = ZT_FLUSH_BOTH; 07096 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 07097 if (res2) 07098 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 07099 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 07100 /* Turn on on hook transfer for 4 seconds */ 07101 x = 4000; 07102 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 07103 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 07104 last->cidpos = 0; 07105 last->msgstate = res; 07106 last->onhooktime = thispass; 07107 } 07108 found ++; 07109 } 07110 } 07111 last = last->next; 07112 } 07113 } 07114 } 07115 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 07116 if (i->radio && !i->owner) 07117 { 07118 res = zt_get_event(i->subs[SUB_REAL].zfd); 07119 if (res) 07120 { 07121 if (option_debug) 07122 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 07123 /* Don't hold iflock while handling init events */ 07124 ast_mutex_unlock(&iflock); 07125 handle_init_event(i, res); 07126 ast_mutex_lock(&iflock); 07127 } 07128 i = i->next; 07129 continue; 07130 } 07131 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 07132 if (pollres & POLLIN) { 07133 if (i->owner || i->subs[SUB_REAL].owner) { 07134 #ifdef HAVE_PRI 07135 if (!i->pri) 07136 #endif 07137 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 07138 i = i->next; 07139 continue; 07140 } 07141 if (!i->cidspill) { 07142 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 07143 i = i->next; 07144 continue; 07145 } 07146 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 07147 if (res > 0) { 07148 /* We read some number of bytes. Write an equal amount of data */ 07149 if (res > i->cidlen - i->cidpos) 07150 res = i->cidlen - i->cidpos; 07151 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 07152 if (res2 > 0) { 07153 i->cidpos += res2; 07154 if (i->cidpos >= i->cidlen) { 07155 free(i->cidspill); 07156 i->cidspill = 0; 07157 i->cidpos = 0; 07158 i->cidlen = 0; 07159 } 07160 } else { 07161 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 07162 i->msgstate = -1; 07163 } 07164 } else { 07165 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 07166 } 07167 } 07168 if (pollres & POLLPRI) { 07169 if (i->owner || i->subs[SUB_REAL].owner) { 07170 #ifdef HAVE_PRI 07171 if (!i->pri) 07172 #endif 07173 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 07174 i = i->next; 07175 continue; 07176 } 07177 res = zt_get_event(i->subs[SUB_REAL].zfd); 07178 if (option_debug) 07179 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 07180 /* Don't hold iflock while handling init events */ 07181 ast_mutex_unlock(&iflock); 07182 handle_init_event(i, res); 07183 ast_mutex_lock(&iflock); 07184 } 07185 } 07186 i=i->next; 07187 } 07188 ast_mutex_unlock(&iflock); 07189 } 07190 /* Never reached */ 07191 return NULL; 07192 07193 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3272 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().
03273 { 03274 #ifdef ZT_TONEDETECT 03275 int val; 03276 #endif 03277 03278 if (p->channel == CHAN_PSEUDO) 03279 return; 03280 03281 p->ignoredtmf = 0; 03282 03283 #ifdef ZT_TONEDETECT 03284 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03285 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03286 #endif 03287 if (!p->hardwaredtmf && p->dsp) { 03288 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03289 ast_dsp_set_features(p->dsp, p->dsp_features); 03290 } 03291 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1200 of file chan_zap.c.
Referenced by __zt_exception(), 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] |
Definition at line 11562 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().
11563 { 11564 struct zt_pvt *p = iflist; 11565 while (p) { 11566 if (p->channel == channel) { 11567 break; 11568 } 11569 p = p->next; 11570 } 11571 return p; 11572 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3747 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::span, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03748 { 03749 int res; 03750 ZT_SPANINFO zi; 03751 memset(&zi, 0, sizeof(zi)); 03752 zi.spanno = p->span; 03753 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03754 if (res < 0) { 03755 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03756 return 0; 03757 } 03758 return zi.alarms; 03759 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6760 of file chan_zap.c.
References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, errno, EVENT_FLAG_SYSTEM, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, zt_pvt::unknown_alarm, VERBOSE_PREFIX_2, zap_destroy_channel_bynum(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
06761 { 06762 int res; 06763 pthread_t threadid; 06764 pthread_attr_t attr; 06765 struct ast_channel *chan; 06766 pthread_attr_init(&attr); 06767 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06768 /* Handle an event on a given channel for the monitor thread. */ 06769 switch (event) { 06770 case ZT_EVENT_NONE: 06771 case ZT_EVENT_BITSCHANGED: 06772 break; 06773 case ZT_EVENT_WINKFLASH: 06774 case ZT_EVENT_RINGOFFHOOK: 06775 if (i->inalarm) break; 06776 if (i->radio) break; 06777 /* Got a ring/answer. What kind of channel are we? */ 06778 switch (i->sig) { 06779 case SIG_FXOLS: 06780 case SIG_FXOGS: 06781 case SIG_FXOKS: 06782 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06783 if (res && (errno == EBUSY)) 06784 break; 06785 if (i->cidspill) { 06786 /* Cancel VMWI spill */ 06787 free(i->cidspill); 06788 i->cidspill = NULL; 06789 } 06790 if (i->immediate) { 06791 zt_enable_ec(i); 06792 /* The channel is immediately up. Start right away */ 06793 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06794 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06795 if (!chan) { 06796 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06797 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06798 if (res < 0) 06799 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06800 } 06801 } else { 06802 /* Check for callerid, digits, etc */ 06803 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06804 if (chan) { 06805 if (has_voicemail(i)) 06806 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06807 else 06808 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06809 if (res < 0) 06810 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 06811 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06812 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06813 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06814 if (res < 0) 06815 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06816 ast_hangup(chan); 06817 } 06818 } else 06819 ast_log(LOG_WARNING, "Unable to create channel\n"); 06820 } 06821 break; 06822 case SIG_FXSLS: 06823 case SIG_FXSGS: 06824 case SIG_FXSKS: 06825 i->ringt = i->ringt_base; 06826 /* Fall through */ 06827 case SIG_EMWINK: 06828 case SIG_FEATD: 06829 case SIG_FEATDMF: 06830 case SIG_FEATDMF_TA: 06831 case SIG_E911: 06832 case SIG_FGC_CAMA: 06833 case SIG_FGC_CAMAMF: 06834 case SIG_FEATB: 06835 case SIG_EM: 06836 case SIG_EM_E1: 06837 case SIG_SFWINK: 06838 case SIG_SF_FEATD: 06839 case SIG_SF_FEATDMF: 06840 case SIG_SF_FEATB: 06841 case SIG_SF: 06842 /* Check for callerid, digits, etc */ 06843 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06844 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06845 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06846 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06847 if (res < 0) 06848 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06849 ast_hangup(chan); 06850 } else if (!chan) { 06851 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06852 } 06853 break; 06854 default: 06855 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06856 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06857 if (res < 0) 06858 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06859 return -1; 06860 } 06861 break; 06862 case ZT_EVENT_NOALARM: 06863 i->inalarm = 0; 06864 if (!i->unknown_alarm) { 06865 #ifdef HAVE_PRI 06866 if (i->pri) { 06867 if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { 06868 /* dont annoy BRI TE mode users with layer2layer alarms */ 06869 } else { 06870 #endif 06871 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06872 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06873 "Channel: %d\r\n", i->channel); 06874 #ifdef HAVE_PRI 06875 } 06876 } 06877 #endif 06878 06879 } else { 06880 i->unknown_alarm = 0; 06881 } 06882 break; 06883 case ZT_EVENT_ALARM: 06884 i->inalarm = 1; 06885 res = get_alarms(i); 06886 do { 06887 #ifdef HAVE_PRI 06888 if (i->pri) { 06889 if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { 06890 /* dont annoy BRI TE mode users with layer2layer alarms */ 06891 } else { 06892 #endif 06893 const char *alarm_str = alarm2str(res); 06894 06895 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 06896 * doesn't know what to do with it. Don't confuse users with log messages. */ 06897 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 06898 i->unknown_alarm = 1; 06899 break; 06900 } else { 06901 i->unknown_alarm = 0; 06902 } 06903 06904 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str); 06905 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06906 "Alarm: %s\r\n" 06907 "Channel: %d\r\n", 06908 alarm_str, i->channel); 06909 #ifdef HAVE_PRI 06910 } 06911 } 06912 #endif 06913 } while (0); 06914 /* fall thru intentionally */ 06915 case ZT_EVENT_ONHOOK: 06916 if (i->radio) 06917 break; 06918 /* Back on hook. Hang up. */ 06919 switch (i->sig) { 06920 case SIG_FXOLS: 06921 case SIG_FXOGS: 06922 case SIG_FEATD: 06923 case SIG_FEATDMF: 06924 case SIG_FEATDMF_TA: 06925 case SIG_E911: 06926 case SIG_FGC_CAMA: 06927 case SIG_FGC_CAMAMF: 06928 case SIG_FEATB: 06929 case SIG_EM: 06930 case SIG_EM_E1: 06931 case SIG_EMWINK: 06932 case SIG_SF_FEATD: 06933 case SIG_SF_FEATDMF: 06934 case SIG_SF_FEATB: 06935 case SIG_SF: 06936 case SIG_SFWINK: 06937 case SIG_FXSLS: 06938 case SIG_FXSGS: 06939 case SIG_FXSKS: 06940 case SIG_GR303FXSKS: 06941 zt_disable_ec(i); 06942 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06943 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06944 break; 06945 case SIG_GR303FXOKS: 06946 case SIG_FXOKS: 06947 zt_disable_ec(i); 06948 /* Diddle the battery for the zhone */ 06949 #ifdef ZHONE_HACK 06950 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06951 usleep(1); 06952 #endif 06953 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06954 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06955 break; 06956 case SIG_PRI: 06957 if (event != ZT_EVENT_ALARM) { 06958 zt_disable_ec(i); 06959 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06960 } 06961 break; 06962 default: 06963 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06964 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06965 return -1; 06966 } 06967 break; 06968 case ZT_EVENT_POLARITY: 06969 switch (i->sig) { 06970 case SIG_FXSLS: 06971 case SIG_FXSKS: 06972 case SIG_FXSGS: 06973 /* We have already got a PR before the channel was 06974 created, but it wasn't handled. We need polarity 06975 to be REV for remote hangup detection to work. 06976 At least in Spain */ 06977 if (i->hanguponpolarityswitch) 06978 i->polarity = POLARITY_REV; 06979 06980 if (i->cid_start == CID_START_POLARITY) { 06981 i->polarity = POLARITY_REV; 06982 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06983 "CID detection on channel %d\n", 06984 i->channel); 06985 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06986 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06987 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06988 } 06989 } 06990 break; 06991 default: 06992 ast_log(LOG_WARNING, "handle_init_event detected " 06993 "polarity reversal on non-FXO (SIG_FXS) " 06994 "interface %d\n", i->channel); 06995 } 06996 break; 06997 case ZT_EVENT_REMOVED: /* destroy channel */ 06998 ast_log(LOG_NOTICE, 06999 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 07000 i->channel); 07001 zap_destroy_channel_bynum(i->channel); 07002 break; 07003 } 07004 pthread_attr_destroy(&attr); 07005 return 0; 07006 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11406 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
11407 { 11408 int i, j; 11409 for (i = 0; i < num_cadence; i++) { 11410 char output[1024]; 11411 char tmp[16], tmp2[64]; 11412 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 11413 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 11414 11415 for (j = 0; j < 16; j++) { 11416 if (cadences[i].ringcadence[j] == 0) 11417 break; 11418 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 11419 if (cidrings[i] * 2 - 1 == j) 11420 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 11421 else 11422 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 11423 if (j != 0) 11424 strncat(output, ",", sizeof(output) - strlen(output) - 1); 11425 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 11426 } 11427 ast_cli(fd,"%s\n",output); 11428 } 11429 return 0; 11430 }
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, 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 12754 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, LOG_ERROR, name, round_robin, setup_zap(), zap_cli, zap_tech, zapEC_app, zapEC_synopsis, and zapEC_tdesc.
12755 { 12756 int res; 12757 12758 #ifdef HAVE_PRI 12759 int y,i; 12760 memset(pris, 0, sizeof(pris)); 12761 for (y = 0; y < NUM_SPANS; y++) { 12762 ast_mutex_init(&pris[y].lock); 12763 pris[y].offset = -1; 12764 pris[y].master = AST_PTHREADT_NULL; 12765 for (i = 0; i < NUM_DCHANS; i++) 12766 pris[y].fds[i] = -1; 12767 } 12768 pri_set_error(zt_pri_error); 12769 pri_set_message(zt_pri_message); 12770 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 12771 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 12772 #endif 12773 #ifdef HAVE_GSMAT 12774 gsm_set_error(zt_gsm_error); 12775 gsm_set_message(zt_gsm_message); 12776 #endif 12777 res = setup_zap(0); 12778 /* Make sure we can register our Zap channel type */ 12779 if (res) 12780 return AST_MODULE_LOAD_DECLINE; 12781 if (ast_channel_register(&zap_tech)) { 12782 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 12783 __unload_module(); 12784 return -1; 12785 } 12786 #ifdef HAVE_PRI 12787 ast_string_field_init(&inuse, 16); 12788 ast_string_field_set(&inuse, name, "GR-303InUse"); 12789 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 12790 ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc); 12791 ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc); 12792 #endif 12793 ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc); 12794 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 12795 #ifdef HAVE_GSMAT 12796 ast_cli_register(&gsm_send_sms); 12797 ast_cli_register(&gsm_send_pdu); 12798 ast_cli_register(&gsm_show_status); 12799 ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); 12800 #endif 12801 12802 memset(round_robin, 0, sizeof(round_robin)); 12803 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 12804 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 12805 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 12806 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 12807 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 12808 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 12809 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 12810 12811 return res; 12812 }
static struct zt_pvt* mkintf | ( | int | channel, | |
const struct zt_chan_conf * | conf, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static] |
Definition at line 7346 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_init(), ast_strlen_zero(), zt_chan_conf::chan, CHAN_PSEUDO, DCHAN_AVAILABLE, destroy_zt_pvt(), errno, iflist, LOG_ERROR, MAX_CHANNELS, zt_pvt::next, zt_pvt::prev, zt_pvt::sig, sig2str, SIG_FXOKS, SIG_FXSKS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SUB_REAL, and zt_open().
Referenced by build_channels().
07347 { 07348 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07349 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07350 char fn[80]; 07351 #if 1 07352 struct zt_bufferinfo bi; 07353 #endif 07354 struct zt_spaninfo si; 07355 int res; 07356 int span=0; 07357 int here = 0; 07358 int x; 07359 struct zt_pvt **wlist; 07360 struct zt_pvt **wend; 07361 ZT_PARAMS p; 07362 07363 wlist = &iflist; 07364 wend = &ifend; 07365 07366 #ifdef HAVE_PRI 07367 if (pri) { 07368 wlist = &pri->crvs; 07369 wend = &pri->crvend; 07370 } 07371 #endif 07372 07373 tmp2 = *wlist; 07374 prev = NULL; 07375 07376 while (tmp2) { 07377 if (!tmp2->destroy) { 07378 if (tmp2->channel == channel) { 07379 tmp = tmp2; 07380 here = 1; 07381 break; 07382 } 07383 if (tmp2->channel > channel) { 07384 break; 07385 } 07386 } 07387 prev = tmp2; 07388 tmp2 = tmp2->next; 07389 } 07390 07391 if (!here && !reloading) { 07392 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07393 destroy_zt_pvt(&tmp); 07394 return NULL; 07395 } 07396 ast_mutex_init(&tmp->lock); 07397 ifcount++; 07398 for (x = 0; x < 3; x++) 07399 tmp->subs[x].zfd = -1; 07400 tmp->channel = channel; 07401 } 07402 07403 if (tmp) { 07404 int chan_sig = conf->chan.sig; 07405 if (!here) { 07406 if ((channel != CHAN_PSEUDO) && !pri) { 07407 snprintf(fn, sizeof(fn), "%d", channel); 07408 /* Open non-blocking */ 07409 if (!here) 07410 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07411 /* Allocate a zapata structure */ 07412 if (tmp->subs[SUB_REAL].zfd < 0) { 07413 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); 07414 destroy_zt_pvt(&tmp); 07415 return NULL; 07416 } 07417 memset(&p, 0, sizeof(p)); 07418 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07419 if (res < 0) { 07420 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07421 destroy_zt_pvt(&tmp); 07422 return NULL; 07423 } 07424 if (p.sigtype != (conf->chan.sig & 0x3ffff)) { 07425 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)); 07426 destroy_zt_pvt(&tmp); 07427 return NULL; 07428 } 07429 tmp->law = p.curlaw; 07430 tmp->span = p.spanno; 07431 span = p.spanno - 1; 07432 } else { 07433 if (channel == CHAN_PSEUDO) 07434 chan_sig = 0; 07435 else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) { 07436 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07437 return NULL; 07438 } 07439 } 07440 #ifdef HAVE_PRI 07441 if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) { 07442 int offset; 07443 int myswitchtype; 07444 int matchesdchan; 07445 int x,y; 07446 offset = 0; 07447 if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07448 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07449 destroy_zt_pvt(&tmp); 07450 return NULL; 07451 } 07452 if (span >= NUM_SPANS) { 07453 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07454 destroy_zt_pvt(&tmp); 07455 return NULL; 07456 } else { 07457 si.spanno = 0; 07458 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07459 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07460 destroy_zt_pvt(&tmp); 07461 return NULL; 07462 } 07463 /* Store the logical span first based upon the real span */ 07464 tmp->logicalspan = pris[span].prilogicalspan; 07465 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07466 if (span < 0) { 07467 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07468 destroy_zt_pvt(&tmp); 07469 return NULL; 07470 } 07471 if (chan_sig == SIG_PRI) 07472 myswitchtype = conf->pri.switchtype; 07473 else 07474 myswitchtype = PRI_SWITCH_GR303_TMC; 07475 /* Make sure this isn't a d-channel */ 07476 matchesdchan=0; 07477 for (x = 0; x < NUM_SPANS; x++) { 07478 for (y = 0; y < NUM_DCHANS; y++) { 07479 if (pris[x].dchannels[y] == tmp->channel) { 07480 matchesdchan = 1; 07481 break; 07482 } 07483 } 07484 } 07485 offset = p.chanpos; 07486 if (!matchesdchan) { 07487 if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) { 07488 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07489 destroy_zt_pvt(&tmp); 07490 return NULL; 07491 } 07492 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07493 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07494 destroy_zt_pvt(&tmp); 07495 return NULL; 07496 } 07497 if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) { 07498 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07499 destroy_zt_pvt(&tmp); 07500 return NULL; 07501 } 07502 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) { 07503 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial); 07504 destroy_zt_pvt(&tmp); 07505 return NULL; 07506 } 07507 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) { 07508 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext); 07509 destroy_zt_pvt(&tmp); 07510 return NULL; 07511 } 07512 if ((pris[span].localdialplan) && (pris[span].localdialplan != conf->pri.localdialplan)) { 07513 ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan)); 07514 destroy_zt_pvt(&tmp); 07515 return NULL; 07516 } 07517 if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) { 07518 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused); 07519 destroy_zt_pvt(&tmp); 07520 return NULL; 07521 } 07522 if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) { 07523 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle); 07524 destroy_zt_pvt(&tmp); 07525 return NULL; 07526 } 07527 if (pris[span].numchans >= MAX_CHANNELS) { 07528 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07529 pris[span].trunkgroup); 07530 destroy_zt_pvt(&tmp); 07531 return NULL; 07532 } 07533 pris[span].nodetype = conf->pri.nodetype; 07534 07535 if (conf->pri.nodetype == BRI_NETWORK_PTMP) { 07536 pris[span].dchanavail[0] = DCHAN_AVAILABLE; 07537 pri_find_dchan(&pris[span]); 07538 } 07539 pris[span].switchtype = myswitchtype; 07540 pris[span].nsf = conf->pri.nsf; 07541 pris[span].dialplan = conf->pri.dialplan; 07542 pris[span].localdialplan = conf->pri.localdialplan; 07543 pris[span].pvts[pris[span].numchans++] = tmp; 07544 pris[span].minunused = conf->pri.minunused; 07545 pris[span].minidle = conf->pri.minidle; 07546 pris[span].overlapdial = conf->pri.overlapdial; 07547 pris[span].usercid = conf->pri.usercid; 07548 pris[span].suspended_calls = NULL; 07549 pris[span].facilityenable = conf->pri.facilityenable; 07550 ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial)); 07551 ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext)); 07552 ast_copy_string(pris[span].nocid, conf->pri.nocid, sizeof(pris[span].nocid)); 07553 ast_copy_string(pris[span].withheldcid, conf->pri.withheldcid, sizeof(pris[span].withheldcid)); 07554 ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07555 ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07556 ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix)); 07557 ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix)); 07558 ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07559 pris[span].resetinterval = conf->pri.resetinterval; 07560 07561 tmp->pri = &pris[span]; 07562 tmp->prioffset = offset; 07563 tmp->call = NULL; 07564 } else { 07565 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07566 destroy_zt_pvt(&tmp); 07567 return NULL; 07568 } 07569 } 07570 } else { 07571 tmp->prioffset = 0; 07572 } 07573 #endif 07574 #ifdef HAVE_GSMAT 07575 if (conf->chan.sig == SIG_GSM) { 07576 struct zt_bufferinfo bi; 07577 ast_mutex_init(&tmp->gsm.lock); 07578 strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1); 07579 strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1); 07580 tmp->gsm.available = 0; 07581 snprintf(fn, sizeof(fn), "%d", channel + 1); 07582 /* Open non-blocking */ 07583 tmp->gsm.fd = zt_open(fn); 07584 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07585 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07586 bi.numbufs = 16; 07587 bi.bufsize = 1024; 07588 if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) { 07589 ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno)); 07590 return NULL; 07591 } 07592 tmp->gsm.pvt = tmp; 07593 tmp->gsm.span = tmp->span; 07594 tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel); 07595 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) { 07596 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno)); 07597 destroy_zt_pvt(&tmp); 07598 return NULL; 07599 } 07600 if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) { 07601 zt_close(tmp->gsm.fd); 07602 } 07603 } 07604 #endif 07605 } else { 07606 chan_sig = tmp->sig; 07607 memset(&p, 0, sizeof(p)); 07608 if (tmp->subs[SUB_REAL].zfd > -1) 07609 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07610 } 07611 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07612 switch (chan_sig) { 07613 case SIG_FXSKS: 07614 case SIG_FXSLS: 07615 case SIG_EM: 07616 case SIG_EM_E1: 07617 case SIG_EMWINK: 07618 case SIG_FEATD: 07619 case SIG_FEATDMF: 07620 case SIG_FEATDMF_TA: 07621 case SIG_FEATB: 07622 case SIG_E911: 07623 case SIG_SF: 07624 case SIG_SFWINK: 07625 case SIG_FGC_CAMA: 07626 case SIG_FGC_CAMAMF: 07627 case SIG_SF_FEATD: 07628 case SIG_SF_FEATDMF: 07629 case SIG_SF_FEATB: 07630 p.starttime = 250; 07631 break; 07632 } 07633 07634 if (tmp->radio) { 07635 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07636 p.channo = channel; 07637 p.rxwinktime = 1; 07638 p.rxflashtime = 1; 07639 p.starttime = 1; 07640 p.debouncetime = 5; 07641 } 07642 if (!tmp->radio) { 07643 p.channo = channel; 07644 /* Override timing settings based on config file */ 07645 if (conf->timing.prewinktime >= 0) 07646 p.prewinktime = conf->timing.prewinktime; 07647 if (conf->timing.preflashtime >= 0) 07648 p.preflashtime = conf->timing.preflashtime; 07649 if (conf->timing.winktime >= 0) 07650 p.winktime = conf->timing.winktime; 07651 if (conf->timing.flashtime >= 0) 07652 p.flashtime = conf->timing.flashtime; 07653 if (conf->timing.starttime >= 0) 07654 p.starttime = conf->timing.starttime; 07655 if (conf->timing.rxwinktime >= 0) 07656 p.rxwinktime = conf->timing.rxwinktime; 07657 if (conf->timing.rxflashtime >= 0) 07658 p.rxflashtime = conf->timing.rxflashtime; 07659 if (conf->timing.debouncetime >= 0) 07660 p.debouncetime = conf->timing.debouncetime; 07661 } 07662 07663 /* dont set parms on a pseudo-channel (or CRV) */ 07664 if (tmp->subs[SUB_REAL].zfd >= 0) 07665 { 07666 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07667 if (res < 0) { 07668 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07669 destroy_zt_pvt(&tmp); 07670 return NULL; 07671 } 07672 } 07673 #if 1 07674 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07675 memset(&bi, 0, sizeof(bi)); 07676 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07677 if (!res) { 07678 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07679 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07680 bi.numbufs = numbufs; 07681 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07682 if (res < 0) { 07683 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07684 } 07685 } else 07686 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07687 } 07688 #endif 07689 tmp->immediate = conf->chan.immediate; 07690 tmp->transfertobusy = conf->chan.transfertobusy; 07691 tmp->sig = chan_sig; 07692 tmp->outsigmod = conf->chan.outsigmod; 07693 tmp->ringt_base = ringt_base; 07694 tmp->firstradio = 0; 07695 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 07696 tmp->permcallwaiting = conf->chan.callwaiting; 07697 else 07698 tmp->permcallwaiting = 0; 07699 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07700 tmp->destroy = 0; 07701 tmp->drings = drings; 07702 tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection; 07703 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 07704 tmp->threewaycalling = conf->chan.threewaycalling; 07705 tmp->adsi = conf->chan.adsi; 07706 tmp->use_smdi = conf->chan.use_smdi; 07707 tmp->permhidecallerid = conf->chan.hidecallerid; 07708 tmp->callreturn = conf->chan.callreturn; 07709 tmp->echocancel = conf->chan.echocancel; 07710 tmp->echotraining = conf->chan.echotraining; 07711 tmp->pulse = conf->chan.pulse; 07712 if (tmp->echocancel) 07713 tmp->echocanbridged = conf->chan.echocanbridged; 07714 else { 07715 if (conf->chan.echocanbridged) 07716 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 07717 tmp->echocanbridged = 0; 07718 } 07719 tmp->busydetect = conf->chan.busydetect; 07720 tmp->busycount = conf->chan.busycount; 07721 tmp->busy_tonelength = conf->chan.busy_tonelength; 07722 tmp->busy_quietlength = conf->chan.busy_quietlength; 07723 tmp->callprogress = conf->chan.callprogress; 07724 tmp->cancallforward = conf->chan.cancallforward; 07725 tmp->dtmfrelax = conf->chan.dtmfrelax; 07726 tmp->callwaiting = tmp->permcallwaiting; 07727 tmp->hidecallerid = tmp->permhidecallerid; 07728 tmp->channel = channel; 07729 tmp->stripmsd = conf->chan.stripmsd; 07730 tmp->use_callerid = conf->chan.use_callerid; 07731 tmp->cid_signalling = conf->chan.cid_signalling; 07732 tmp->cid_start = conf->chan.cid_start; 07733 tmp->zaptrcallerid = conf->chan.zaptrcallerid; 07734 tmp->restrictcid = conf->chan.restrictcid; 07735 tmp->use_callingpres = conf->chan.use_callingpres; 07736 tmp->priindication_oob = conf->chan.priindication_oob; 07737 tmp->pritransfer = conf->chan.pritransfer; 07738 tmp->priexclusive = conf->chan.priexclusive; 07739 if (tmp->usedistinctiveringdetection) { 07740 if (!tmp->use_callerid) { 07741 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07742 tmp->use_callerid = 1; 07743 } 07744 } 07745 07746 if (tmp->cid_signalling == CID_SIG_SMDI) { 07747 if (!tmp->use_smdi) { 07748 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07749 tmp->use_smdi = 1; 07750 } 07751 } 07752 if (tmp->use_smdi) { 07753 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 07754 if (!(tmp->smdi_iface)) { 07755 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07756 tmp->use_smdi = 0; 07757 } 07758 } 07759 07760 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 07761 tmp->amaflags = conf->chan.amaflags; 07762 if (!here) { 07763 tmp->confno = -1; 07764 tmp->propconfno = -1; 07765 } 07766 tmp->canpark = conf->chan.canpark; 07767 tmp->transfer = conf->chan.transfer; 07768 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 07769 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 07770 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 07771 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 07772 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 07773 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 07774 tmp->cid_ton = 0; 07775 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 07776 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 07777 tmp->msgstate = -1; 07778 tmp->group = conf->chan.group; 07779 tmp->callgroup = conf->chan.callgroup; 07780 tmp->pickupgroup= conf->chan.pickupgroup; 07781 tmp->rxgain = conf->chan.rxgain; 07782 tmp->txgain = conf->chan.txgain; 07783 tmp->tonezone = conf->chan.tonezone; 07784 tmp->onhooktime = time(NULL); 07785 if (tmp->subs[SUB_REAL].zfd > -1) { 07786 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07787 if (tmp->dsp) 07788 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07789 update_conf(tmp); 07790 if (!here) { 07791 if (chan_sig != SIG_PRI) 07792 /* Hang it up to be sure it's good */ 07793 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07794 } 07795 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07796 #ifdef HAVE_PRI 07797 /* the dchannel is down so put the channel in alarm */ 07798 if (tmp->pri && !pri_is_up(tmp->pri)) 07799 tmp->inalarm = 1; 07800 else 07801 tmp->inalarm = 0; 07802 #endif 07803 memset(&si, 0, sizeof(si)); 07804 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07805 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07806 destroy_zt_pvt(&tmp); 07807 return NULL; 07808 } 07809 if (si.alarms) tmp->inalarm = 1; 07810 } 07811 07812 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 07813 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 07814 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 07815 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 07816 07817 } 07818 if (tmp && !here) { 07819 /* nothing on the iflist */ 07820 if (!*wlist) { 07821 *wlist = tmp; 07822 tmp->prev = NULL; 07823 tmp->next = NULL; 07824 *wend = tmp; 07825 } else { 07826 /* at least one member on the iflist */ 07827 struct zt_pvt *working = *wlist; 07828 07829 /* check if we maybe have to put it on the begining */ 07830 if (working->channel > tmp->channel) { 07831 tmp->next = *wlist; 07832 tmp->prev = NULL; 07833 (*wlist)->prev = tmp; 07834 *wlist = tmp; 07835 } else { 07836 /* go through all the members and put the member in the right place */ 07837 while (working) { 07838 /* in the middle */ 07839 if (working->next) { 07840 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07841 tmp->next = working->next; 07842 tmp->prev = working; 07843 working->next->prev = tmp; 07844 working->next = tmp; 07845 break; 07846 } 07847 } else { 07848 /* the last */ 07849 if (working->channel < tmp->channel) { 07850 working->next = tmp; 07851 tmp->next = NULL; 07852 tmp->prev = working; 07853 *wend = tmp; 07854 break; 07855 } 07856 } 07857 working = working->next; 07858 } 07859 } 07860 } 07861 } 07862 return tmp; 07863 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5549 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05550 { 05551 char c; 05552 05553 *str = 0; /* start with empty output buffer */ 05554 for (;;) 05555 { 05556 /* Wait for the first digit (up to specified ms). */ 05557 c = ast_waitfordigit(chan, ms); 05558 /* if timeout, hangup or error, return as such */ 05559 if (c < 1) 05560 return c; 05561 *str++ = c; 05562 *str = 0; 05563 if (strchr(term, c)) 05564 return 1; 05565 } 05566 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 5076 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().
05077 { 05078 int sent=0; 05079 int size; 05080 int res; 05081 int fd; 05082 fd = p->subs[index].zfd; 05083 while (len) { 05084 size = len; 05085 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 05086 size = (linear ? READ_SIZE * 2 : READ_SIZE); 05087 res = write(fd, buf, size); 05088 if (res != size) { 05089 if (option_debug) 05090 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 05091 return sent; 05092 } 05093 len -= size; 05094 buf += size; 05095 } 05096 return sent; 05097 }
static int process_zap | ( | struct zt_chan_conf * | confp, | |
struct ast_variable * | v, | |||
int | reload, | |||
int | skipchannels | |||
) | [static] |
Definition at line 11909 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_jb_read_conf(), ast_log(), ast_strlen_zero(), ast_true(), ast_verbose(), build_channels(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, global_jbconf, zt_pvt::group, zt_pvt::hanguponpolarityswitch, HAVE_PRI, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, zt_pvt::immediate, zt_pvt::language, ast_variable::lineno, LOG_ERROR, zt_pvt::mailbox, MAX_CHANLIST_LEN, zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::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().
11910 { 11911 struct zt_pvt *tmp; 11912 char *ringc; /* temporary string for parsing the dring number. */ 11913 int y; 11914 int found_pseudo = 0; 11915 char zapchan[MAX_CHANLIST_LEN] = {}; 11916 11917 for (; v; v = v->next) { 11918 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 11919 continue; 11920 11921 /* Create the interface list */ 11922 if (!strcasecmp(v->name, "channel") 11923 #ifdef HAVE_PRI 11924 || !strcasecmp(v->name, "crv") 11925 #endif 11926 ) { 11927 int iscrv; 11928 if (skipchannels) 11929 continue; 11930 iscrv = !strcasecmp(v->name, "crv"); 11931 if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 11932 return -1; 11933 } else if (!strcasecmp(v->name, "zapchan")) { 11934 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 11935 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 11936 if (ast_true(v->value)) 11937 confp->chan.usedistinctiveringdetection = 1; 11938 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 11939 if (ast_true(v->value)) 11940 distinctiveringaftercid = 1; 11941 } else if (!strcasecmp(v->name, "dring1context")) { 11942 ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData)); 11943 } else if (!strcasecmp(v->name, "dring2context")) { 11944 ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData)); 11945 } else if (!strcasecmp(v->name, "dring3context")) { 11946 ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData)); 11947 } else if (!strcasecmp(v->name, "dring1")) { 11948 ringc = v->value; 11949 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 11950 } else if (!strcasecmp(v->name, "dring2")) { 11951 ringc = v->value; 11952 sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 11953 } else if (!strcasecmp(v->name, "dring3")) { 11954 ringc = v->value; 11955 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 11956 } else if (!strcasecmp(v->name, "usecallerid")) { 11957 confp->chan.use_callerid = ast_true(v->value); 11958 } else if (!strcasecmp(v->name, "cidsignalling")) { 11959 if (!strcasecmp(v->value, "bell")) 11960 confp->chan.cid_signalling = CID_SIG_BELL; 11961 else if (!strcasecmp(v->value, "v23")) 11962 confp->chan.cid_signalling = CID_SIG_V23; 11963 else if (!strcasecmp(v->value, "dtmf")) 11964 confp->chan.cid_signalling = CID_SIG_DTMF; 11965 else if (!strcasecmp(v->value, "smdi")) 11966 confp->chan.cid_signalling = CID_SIG_SMDI; 11967 else if (!strcasecmp(v->value, "v23_jp")) 11968 confp->chan.cid_signalling = CID_SIG_V23_JP; 11969 else if (ast_true(v->value)) 11970 confp->chan.cid_signalling = CID_SIG_BELL; 11971 } else if (!strcasecmp(v->name, "cidstart")) { 11972 if (!strcasecmp(v->value, "ring")) 11973 confp->chan.cid_start = CID_START_RING; 11974 else if (!strcasecmp(v->value, "polarity")) 11975 confp->chan.cid_start = CID_START_POLARITY; 11976 else if (ast_true(v->value)) 11977 confp->chan.cid_start = CID_START_RING; 11978 } else if (!strcasecmp(v->name, "threewaycalling")) { 11979 confp->chan.threewaycalling = ast_true(v->value); 11980 } else if (!strcasecmp(v->name, "cancallforward")) { 11981 confp->chan.cancallforward = ast_true(v->value); 11982 } else if (!strcasecmp(v->name, "relaxdtmf")) { 11983 if (ast_true(v->value)) 11984 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 11985 else 11986 confp->chan.dtmfrelax = 0; 11987 } else if (!strcasecmp(v->name, "mailbox")) { 11988 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 11989 } else if (!strcasecmp(v->name, "adsi")) { 11990 confp->chan.adsi = ast_true(v->value); 11991 } else if (!strcasecmp(v->name, "usesmdi")) { 11992 confp->chan.use_smdi = ast_true(v->value); 11993 } else if (!strcasecmp(v->name, "smdiport")) { 11994 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 11995 } else if (!strcasecmp(v->name, "transfer")) { 11996 confp->chan.transfer = ast_true(v->value); 11997 } else if (!strcasecmp(v->name, "canpark")) { 11998 confp->chan.canpark = ast_true(v->value); 11999 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 12000 confp->chan.echocanbridged = ast_true(v->value); 12001 } else if (!strcasecmp(v->name, "busydetect")) { 12002 confp->chan.busydetect = ast_true(v->value); 12003 } else if (!strcasecmp(v->name, "busycount")) { 12004 confp->chan.busycount = atoi(v->value); 12005 } else if (!strcasecmp(v->name, "busypattern")) { 12006 if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 12007 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 12008 } 12009 } else if (!strcasecmp(v->name, "callprogress")) { 12010 if (ast_true(v->value)) 12011 confp->chan.callprogress |= 1; 12012 else 12013 confp->chan.callprogress &= ~1; 12014 } else if (!strcasecmp(v->name, "faxdetect")) { 12015 if (!strcasecmp(v->value, "incoming")) { 12016 confp->chan.callprogress |= 4; 12017 confp->chan.callprogress &= ~2; 12018 } else if (!strcasecmp(v->value, "outgoing")) { 12019 confp->chan.callprogress &= ~4; 12020 confp->chan.callprogress |= 2; 12021 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 12022 confp->chan.callprogress |= 6; 12023 else 12024 confp->chan.callprogress &= ~6; 12025 } else if (!strcasecmp(v->name, "echocancel")) { 12026 if (!ast_strlen_zero(v->value)) { 12027 y = atoi(v->value); 12028 } else 12029 y = 0; 12030 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 12031 confp->chan.echocancel = y; 12032 else { 12033 confp->chan.echocancel = ast_true(v->value); 12034 if (confp->chan.echocancel) 12035 confp->chan.echocancel=128; 12036 } 12037 } else if (!strcasecmp(v->name, "echotraining")) { 12038 if (sscanf(v->value, "%d", &y) == 1) { 12039 if ((y < 10) || (y > 4000)) { 12040 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 12041 } else { 12042 confp->chan.echotraining = y; 12043 } 12044 } else if (ast_true(v->value)) { 12045 confp->chan.echotraining = 400; 12046 } else 12047 confp->chan.echotraining = 0; 12048 } else if (!strcasecmp(v->name, "hidecallerid")) { 12049 confp->chan.hidecallerid = ast_true(v->value); 12050 } else if (!strcasecmp(v->name, "hidecalleridname")) { 12051 confp->chan.hidecalleridname = ast_true(v->value); 12052 } else if (!strcasecmp(v->name, "pulsedial")) { 12053 confp->chan.pulse = ast_true(v->value); 12054 } else if (!strcasecmp(v->name, "callreturn")) { 12055 confp->chan.callreturn = ast_true(v->value); 12056 } else if (!strcasecmp(v->name, "callwaiting")) { 12057 confp->chan.callwaiting = ast_true(v->value); 12058 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 12059 confp->chan.callwaitingcallerid = ast_true(v->value); 12060 } else if (!strcasecmp(v->name, "context")) { 12061 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 12062 } else if (!strcasecmp(v->name, "language")) { 12063 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 12064 } else if (!strcasecmp(v->name, "progzone")) { 12065 ast_copy_string(progzone, v->value, sizeof(progzone)); 12066 } else if (!strcasecmp(v->name, "mohinterpret") 12067 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 12068 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 12069 } else if (!strcasecmp(v->name, "mohsuggest")) { 12070 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 12071 } else if (!strcasecmp(v->name, "stripmsd")) { 12072 confp->chan.stripmsd = atoi(v->value); 12073 } else if (!strcasecmp(v->name, "jitterbuffers")) { 12074 numbufs = atoi(v->value); 12075 } else if (!strcasecmp(v->name, "group")) { 12076 confp->chan.group = ast_get_group(v->value); 12077 } else if (!strcasecmp(v->name, "callgroup")) { 12078 confp->chan.callgroup = ast_get_group(v->value); 12079 } else if (!strcasecmp(v->name, "pickupgroup")) { 12080 confp->chan.pickupgroup = ast_get_group(v->value); 12081 } else if (!strcasecmp(v->name, "immediate")) { 12082 confp->chan.immediate = ast_true(v->value); 12083 } else if (!strcasecmp(v->name, "transfertobusy")) { 12084 confp->chan.transfertobusy = ast_true(v->value); 12085 } else if (!strcasecmp(v->name, "rxgain")) { 12086 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 12087 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 12088 } 12089 } else if (!strcasecmp(v->name, "txgain")) { 12090 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 12091 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 12092 } 12093 } else if (!strcasecmp(v->name, "tonezone")) { 12094 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 12095 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 12096 } 12097 } else if (!strcasecmp(v->name, "callerid")) { 12098 if (!strcasecmp(v->value, "asreceived")) { 12099 confp->chan.cid_num[0] = '\0'; 12100 confp->chan.cid_name[0] = '\0'; 12101 } else { 12102 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 12103 } 12104 } else if (!strcasecmp(v->name, "fullname")) { 12105 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 12106 } else if (!strcasecmp(v->name, "cid_number")) { 12107 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 12108 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 12109 confp->chan.zaptrcallerid = ast_true(v->value); 12110 } else if (!strcasecmp(v->name, "restrictcid")) { 12111 confp->chan.restrictcid = ast_true(v->value); 12112 } else if (!strcasecmp(v->name, "usecallingpres")) { 12113 confp->chan.use_callingpres = ast_true(v->value); 12114 } else if (!strcasecmp(v->name, "accountcode")) { 12115 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 12116 } else if (!strcasecmp(v->name, "amaflags")) { 12117 y = ast_cdr_amaflags2int(v->value); 12118 if (y < 0) 12119 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 12120 else 12121 confp->chan.amaflags = y; 12122 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 12123 confp->chan.polarityonanswerdelay = atoi(v->value); 12124 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 12125 confp->chan.answeronpolarityswitch = ast_true(v->value); 12126 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 12127 confp->chan.hanguponpolarityswitch = ast_true(v->value); 12128 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 12129 confp->chan.sendcalleridafter = atoi(v->value); 12130 } else if (!reload){ 12131 if (!strcasecmp(v->name, "signalling")) { 12132 confp->chan.outsigmod = -1; 12133 if (!strcasecmp(v->value, "em")) { 12134 confp->chan.sig = SIG_EM; 12135 } else if (!strcasecmp(v->value, "em_e1")) { 12136 confp->chan.sig = SIG_EM_E1; 12137 } else if (!strcasecmp(v->value, "em_w")) { 12138 confp->chan.sig = SIG_EMWINK; 12139 confp->chan.radio = 0; 12140 } else if (!strcasecmp(v->value, "fxs_ls")) { 12141 confp->chan.sig = SIG_FXSLS; 12142 confp->chan.radio = 0; 12143 } else if (!strcasecmp(v->value, "fxs_gs")) { 12144 confp->chan.sig = SIG_FXSGS; 12145 confp->chan.radio = 0; 12146 } else if (!strcasecmp(v->value, "fxs_ks")) { 12147 confp->chan.sig = SIG_FXSKS; 12148 confp->chan.radio = 0; 12149 } else if (!strcasecmp(v->value, "fxo_ls")) { 12150 confp->chan.sig = SIG_FXOLS; 12151 confp->chan.radio = 0; 12152 } else if (!strcasecmp(v->value, "fxo_gs")) { 12153 confp->chan.sig = SIG_FXOGS; 12154 confp->chan.radio = 0; 12155 } else if (!strcasecmp(v->value, "fxo_ks")) { 12156 confp->chan.sig = SIG_FXOKS; 12157 confp->chan.radio = 0; 12158 } else if (!strcasecmp(v->value, "fxs_rx")) { 12159 confp->chan.sig = SIG_FXSKS; 12160 confp->chan.radio = 1; 12161 } else if (!strcasecmp(v->value, "fxo_rx")) { 12162 confp->chan.sig = SIG_FXOLS; 12163 confp->chan.radio = 1; 12164 } else if (!strcasecmp(v->value, "fxs_tx")) { 12165 confp->chan.sig = SIG_FXSLS; 12166 confp->chan.radio = 1; 12167 } else if (!strcasecmp(v->value, "fxo_tx")) { 12168 confp->chan.sig = SIG_FXOGS; 12169 confp->chan.radio = 1; 12170 } else if (!strcasecmp(v->value, "em_rx")) { 12171 confp->chan.sig = SIG_EM; 12172 confp->chan.radio = 1; 12173 } else if (!strcasecmp(v->value, "em_tx")) { 12174 confp->chan.sig = SIG_EM; 12175 confp->chan.radio = 1; 12176 } else if (!strcasecmp(v->value, "em_rxtx")) { 12177 confp->chan.sig = SIG_EM; 12178 confp->chan.radio = 2; 12179 } else if (!strcasecmp(v->value, "em_txrx")) { 12180 confp->chan.sig = SIG_EM; 12181 confp->chan.radio = 2; 12182 } else if (!strcasecmp(v->value, "sf")) { 12183 confp->chan.sig = SIG_SF; 12184 confp->chan.radio = 0; 12185 } else if (!strcasecmp(v->value, "sf_w")) { 12186 confp->chan.sig = SIG_SFWINK; 12187 confp->chan.radio = 0; 12188 } else if (!strcasecmp(v->value, "sf_featd")) { 12189 confp->chan.sig = SIG_FEATD; 12190 confp->chan.radio = 0; 12191 } else if (!strcasecmp(v->value, "sf_featdmf")) { 12192 confp->chan.sig = SIG_FEATDMF; 12193 confp->chan.radio = 0; 12194 } else if (!strcasecmp(v->value, "sf_featb")) { 12195 confp->chan.sig = SIG_SF_FEATB; 12196 confp->chan.radio = 0; 12197 } else if (!strcasecmp(v->value, "sf")) { 12198 confp->chan.sig = SIG_SF; 12199 confp->chan.radio = 0; 12200 } else if (!strcasecmp(v->value, "sf_rx")) { 12201 confp->chan.sig = SIG_SF; 12202 confp->chan.radio = 1; 12203 } else if (!strcasecmp(v->value, "sf_tx")) { 12204 confp->chan.sig = SIG_SF; 12205 confp->chan.radio = 1; 12206 } else if (!strcasecmp(v->value, "sf_rxtx")) { 12207 confp->chan.sig = SIG_SF; 12208 confp->chan.radio = 2; 12209 } else if (!strcasecmp(v->value, "sf_txrx")) { 12210 confp->chan.sig = SIG_SF; 12211 confp->chan.radio = 2; 12212 } else if (!strcasecmp(v->value, "featd")) { 12213 confp->chan.sig = SIG_FEATD; 12214 confp->chan.radio = 0; 12215 } else if (!strcasecmp(v->value, "featdmf")) { 12216 confp->chan.sig = SIG_FEATDMF; 12217 confp->chan.radio = 0; 12218 } else if (!strcasecmp(v->value, "featdmf_ta")) { 12219 confp->chan.sig = SIG_FEATDMF_TA; 12220 confp->chan.radio = 0; 12221 } else if (!strcasecmp(v->value, "e911")) { 12222 confp->chan.sig = SIG_E911; 12223 confp->chan.radio = 0; 12224 } else if (!strcasecmp(v->value, "fgccama")) { 12225 confp->chan.sig = SIG_FGC_CAMA; 12226 confp->chan.radio = 0; 12227 } else if (!strcasecmp(v->value, "fgccamamf")) { 12228 confp->chan.sig = SIG_FGC_CAMAMF; 12229 confp->chan.radio = 0; 12230 } else if (!strcasecmp(v->value, "featb")) { 12231 confp->chan.sig = SIG_FEATB; 12232 confp->chan.radio = 0; 12233 #ifdef HAVE_PRI 12234 } else if (!strcasecmp(v->value, "pri_net")) { 12235 confp->chan.radio = 0; 12236 confp->chan.sig = SIG_PRI; 12237 confp->pri.nodetype = PRI_NETWORK; 12238 } else if (!strcasecmp(v->value, "pri_cpe")) { 12239 confp->chan.sig = SIG_PRI; 12240 confp->chan.radio = 0; 12241 confp->pri.nodetype = PRI_CPE; 12242 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 12243 confp->chan.sig = SIG_GR303FXOKS; 12244 confp->chan.radio = 0; 12245 confp->pri.nodetype = PRI_NETWORK; 12246 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 12247 confp->chan.sig = SIG_GR303FXSKS; 12248 confp->chan.radio = 0; 12249 confp->pri.nodetype = PRI_CPE; 12250 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 12251 confp->chan.radio = 0; 12252 confp->chan.sig = SIG_PRI; 12253 confp->pri.nodetype = BRI_NETWORK_PTMP; 12254 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 12255 confp->chan.sig = SIG_PRI; 12256 confp->chan.radio = 0; 12257 confp->pri.nodetype = BRI_CPE_PTMP; 12258 } else if (!strcasecmp(v->value, "bri_net")) { 12259 confp->chan.radio = 0; 12260 confp->chan.sig = SIG_PRI; 12261 confp->pri.nodetype = BRI_NETWORK; 12262 } else if (!strcasecmp(v->value, "bri_cpe")) { 12263 confp->chan.sig = SIG_PRI; 12264 confp->chan.radio = 0; 12265 confp->pri.nodetype = BRI_CPE; 12266 #endif 12267 #ifdef HAVE_GSMAT 12268 } else if (!strcasecmp(v->value, "gsm")) { 12269 confp->chan.sig = SIG_GSM; 12270 confp->chan.radio = 0; 12271 #endif 12272 } else { 12273 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 12274 } 12275 } else if (!strcasecmp(v->name, "outsignalling")) { 12276 if (!strcasecmp(v->value, "em")) { 12277 confp->chan.outsigmod = SIG_EM; 12278 } else if (!strcasecmp(v->value, "em_e1")) { 12279 confp->chan.outsigmod = SIG_EM_E1; 12280 } else if (!strcasecmp(v->value, "em_w")) { 12281 confp->chan.outsigmod = SIG_EMWINK; 12282 } else if (!strcasecmp(v->value, "sf")) { 12283 confp->chan.outsigmod = SIG_SF; 12284 } else if (!strcasecmp(v->value, "sf_w")) { 12285 confp->chan.outsigmod = SIG_SFWINK; 12286 } else if (!strcasecmp(v->value, "sf_featd")) { 12287 confp->chan.outsigmod = SIG_FEATD; 12288 } else if (!strcasecmp(v->value, "sf_featdmf")) { 12289 confp->chan.outsigmod = SIG_FEATDMF; 12290 } else if (!strcasecmp(v->value, "sf_featb")) { 12291 confp->chan.outsigmod = SIG_SF_FEATB; 12292 } else if (!strcasecmp(v->value, "sf")) { 12293 confp->chan.outsigmod = SIG_SF; 12294 } else if (!strcasecmp(v->value, "featd")) { 12295 confp->chan.outsigmod = SIG_FEATD; 12296 } else if (!strcasecmp(v->value, "featdmf")) { 12297 confp->chan.outsigmod = SIG_FEATDMF; 12298 } else if (!strcasecmp(v->value, "featdmf_ta")) { 12299 confp->chan.outsigmod = SIG_FEATDMF_TA; 12300 } else if (!strcasecmp(v->value, "e911")) { 12301 confp->chan.outsigmod = SIG_E911; 12302 } else if (!strcasecmp(v->value, "fgccama")) { 12303 confp->chan.outsigmod = SIG_FGC_CAMA; 12304 } else if (!strcasecmp(v->value, "fgccamamf")) { 12305 confp->chan.outsigmod = SIG_FGC_CAMAMF; 12306 } else if (!strcasecmp(v->value, "featb")) { 12307 confp->chan.outsigmod = SIG_FEATB; 12308 } else { 12309 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 12310 } 12311 #ifdef HAVE_PRI 12312 } else if (!strcasecmp(v->name, "pridialplan")) { 12313 if (!strcasecmp(v->value, "national")) { 12314 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 12315 } else if (!strcasecmp(v->value, "unknown")) { 12316 confp->pri.dialplan = PRI_UNKNOWN + 1; 12317 } else if (!strcasecmp(v->value, "private")) { 12318 confp->pri.dialplan = PRI_PRIVATE + 1; 12319 } else if (!strcasecmp(v->value, "international")) { 12320 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 12321 } else if (!strcasecmp(v->value, "local")) { 12322 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 12323 } else if (!strcasecmp(v->value, "dynamic")) { 12324 confp->pri.dialplan = -1; 12325 } else { 12326 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 12327 } 12328 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 12329 if (!strcasecmp(v->value, "national")) { 12330 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 12331 } else if (!strcasecmp(v->value, "unknown")) { 12332 confp->pri.localdialplan = PRI_UNKNOWN + 1; 12333 } else if (!strcasecmp(v->value, "private")) { 12334 confp->pri.localdialplan = PRI_PRIVATE + 1; 12335 } else if (!strcasecmp(v->value, "international")) { 12336 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 12337 } else if (!strcasecmp(v->value, "local")) { 12338 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 12339 } else if (!strcasecmp(v->value, "dynamic")) { 12340 confp->pri.localdialplan = -1; 12341 } else { 12342 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 12343 } 12344 } else if (!strcasecmp(v->name, "switchtype")) { 12345 if (!strcasecmp(v->value, "national")) 12346 confp->pri.switchtype = PRI_SWITCH_NI2; 12347 else if (!strcasecmp(v->value, "ni1")) 12348 confp->pri.switchtype = PRI_SWITCH_NI1; 12349 else if (!strcasecmp(v->value, "dms100")) 12350 confp->pri.switchtype = PRI_SWITCH_DMS100; 12351 else if (!strcasecmp(v->value, "4ess")) 12352 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 12353 else if (!strcasecmp(v->value, "5ess")) 12354 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 12355 else if (!strcasecmp(v->value, "euroisdn")) 12356 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 12357 else if (!strcasecmp(v->value, "qsig")) 12358 confp->pri.switchtype = PRI_SWITCH_QSIG; 12359 else { 12360 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 12361 return -1; 12362 } 12363 } else if (!strcasecmp(v->name, "nsf")) { 12364 if (!strcasecmp(v->value, "sdn")) 12365 confp->pri.nsf = PRI_NSF_SDN; 12366 else if (!strcasecmp(v->value, "megacom")) 12367 confp->pri.nsf = PRI_NSF_MEGACOM; 12368 else if (!strcasecmp(v->value, "tollfreemegacom")) 12369 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 12370 else if (!strcasecmp(v->value, "accunet")) 12371 confp->pri.nsf = PRI_NSF_ACCUNET; 12372 else if (!strcasecmp(v->value, "none")) 12373 confp->pri.nsf = PRI_NSF_NONE; 12374 else { 12375 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 12376 confp->pri.nsf = PRI_NSF_NONE; 12377 } 12378 } else if (!strcasecmp(v->name, "priindication")) { 12379 if (!strcasecmp(v->value, "outofband")) 12380 confp->chan.priindication_oob = 1; 12381 else if (!strcasecmp(v->value, "inband")) 12382 confp->chan.priindication_oob = 0; 12383 else if (!strcasecmp(v->value, "passthrough")) 12384 confp->chan.priindication_oob = 2; 12385 else 12386 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n", 12387 v->value, v->lineno); 12388 } else if (!strcasecmp(v->name, "pritransfer")) { 12389 if (!strcasecmp(v->value, "no")) 12390 confp->chan.pritransfer = 0; 12391 else if (!strcasecmp(v->value, "ect")) 12392 confp->chan.pritransfer = 1; 12393 else if (!strcasecmp(v->value, "hangup")) 12394 confp->chan.pritransfer = 2; 12395 else 12396 ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n", 12397 v->value, v->lineno); 12398 } else if (!strcasecmp(v->name, "priexclusive")) { 12399 confp->chan.priexclusive = ast_true(v->value); 12400 } else if (!strcasecmp(v->name, "internationalprefix")) { 12401 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 12402 } else if (!strcasecmp(v->name, "nationalprefix")) { 12403 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 12404 } else if (!strcasecmp(v->name, "localprefix")) { 12405 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 12406 } else if (!strcasecmp(v->name, "privateprefix")) { 12407 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 12408 } else if (!strcasecmp(v->name, "unknownprefix")) { 12409 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 12410 } else if (!strcasecmp(v->name, "nocid")) { 12411 ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid)); 12412 } else if (!strcasecmp(v->name, "withheldcid")) { 12413 ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid)); 12414 } else if (!strcasecmp(v->name, "pin")) { 12415 ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1); 12416 } else if (!strcasecmp(v->name, "exten")) { 12417 ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1); 12418 } else if (!strcasecmp(v->name, "resetinterval")) { 12419 if (!strcasecmp(v->value, "never")) 12420 confp->pri.resetinterval = -1; 12421 else if (atoi(v->value) >= 60) 12422 confp->pri.resetinterval = atoi(v->value); 12423 else 12424 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 12425 v->value, v->lineno); 12426 } else if (!strcasecmp(v->name, "minunused")) { 12427 confp->pri.minunused = atoi(v->value); 12428 } else if (!strcasecmp(v->name, "minidle")) { 12429 confp->pri.minidle = atoi(v->value); 12430 } else if (!strcasecmp(v->name, "idleext")) { 12431 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 12432 } else if (!strcasecmp(v->name, "idledial")) { 12433 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 12434 } else if (!strcasecmp(v->name, "pritrustusercid")) { 12435 confp->pri.usercid = ast_true(v->value); 12436 } else if (!strcasecmp(v->name, "overlapdial")) { 12437 confp->pri.overlapdial = ast_true(v->value); 12438 } else if (!strcasecmp(v->name, "pritimer")) { 12439 #ifdef PRI_GETSET_TIMERS 12440 char *timerc, *c; 12441 int timer, timeridx; 12442 c = v->value; 12443 timerc = strsep(&c, ","); 12444 if (timerc) { 12445 timer = atoi(c); 12446 if (!timer) 12447 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 12448 else { 12449 if ((timeridx = pri_timer2idx(timerc)) >= 0) 12450 pritimers[timeridx] = timer; 12451 else 12452 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 12453 } 12454 } else 12455 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 12456 12457 } else if (!strcasecmp(v->name, "facilityenable")) { 12458 confp->pri.facilityenable = ast_true(v->value); 12459 #endif /* PRI_GETSET_TIMERS */ 12460 #endif /* HAVE_PRI */ 12461 } else if (!strcasecmp(v->name, "cadence")) { 12462 /* setup to scan our argument */ 12463 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 12464 int i; 12465 struct zt_ring_cadence new_cadence; 12466 int cid_location = -1; 12467 int firstcadencepos = 0; 12468 char original_args[80]; 12469 int cadence_is_ok = 1; 12470 12471 ast_copy_string(original_args, v->value, sizeof(original_args)); 12472 /* 16 cadences allowed (8 pairs) */ 12473 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]); 12474 12475 /* Cadence must be even (on/off) */ 12476 if (element_count % 2 == 1) { 12477 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 12478 cadence_is_ok = 0; 12479 } 12480 12481 /* Ring cadences cannot be negative */ 12482 for (i = 0; i < element_count; i++) { 12483 if (c[i] == 0) { 12484 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 12485 cadence_is_ok = 0; 12486 break; 12487 } else if (c[i] < 0) { 12488 if (i % 2 == 1) { 12489 /* Silence duration, negative possibly okay */ 12490 if (cid_location == -1) { 12491 cid_location = i; 12492 c[i] *= -1; 12493 } else { 12494 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 12495 cadence_is_ok = 0; 12496 break; 12497 } 12498 } else { 12499 if (firstcadencepos == 0) { 12500 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 12501 /* duration will be passed negative to the zaptel driver */ 12502 } else { 12503 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 12504 cadence_is_ok = 0; 12505 break; 12506 } 12507 } 12508 } 12509 } 12510 12511 /* Substitute our scanned cadence */ 12512 for (i = 0; i < 16; i++) { 12513 new_cadence.ringcadence[i] = c[i]; 12514 } 12515 12516 if (cadence_is_ok) { 12517 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 12518 if (element_count < 2) { 12519 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 12520 } else { 12521 if (cid_location == -1) { 12522 /* user didn't say; default to first pause */ 12523 cid_location = 1; 12524 } else { 12525 /* convert element_index to cidrings value */ 12526 cid_location = (cid_location + 1) / 2; 12527 } 12528 /* ---we like their cadence; try to install it--- */ 12529 if (!user_has_defined_cadences++) 12530 /* this is the first user-defined cadence; clear the default user cadences */ 12531 num_cadence = 0; 12532 if ((num_cadence+1) >= NUM_CADENCE_MAX) 12533 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 12534 else { 12535 cadences[num_cadence] = new_cadence; 12536 cidrings[num_cadence++] = cid_location; 12537 if (option_verbose > 2) 12538 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 12539 } 12540 } 12541 } 12542 } else if (!strcasecmp(v->name, "ringtimeout")) { 12543 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 12544 } else if (!strcasecmp(v->name, "prewink")) { 12545 confp->timing.prewinktime = atoi(v->value); 12546 } else if (!strcasecmp(v->name, "preflash")) { 12547 confp->timing.preflashtime = atoi(v->value); 12548 } else if (!strcasecmp(v->name, "wink")) { 12549 confp->timing.winktime = atoi(v->value); 12550 } else if (!strcasecmp(v->name, "flash")) { 12551 confp->timing.flashtime = atoi(v->value); 12552 } else if (!strcasecmp(v->name, "start")) { 12553 confp->timing.starttime = atoi(v->value); 12554 } else if (!strcasecmp(v->name, "rxwink")) { 12555 confp->timing.rxwinktime = atoi(v->value); 12556 } else if (!strcasecmp(v->name, "rxflash")) { 12557 confp->timing.rxflashtime = atoi(v->value); 12558 } else if (!strcasecmp(v->name, "debounce")) { 12559 confp->timing.debouncetime = atoi(v->value); 12560 } else if (!strcasecmp(v->name, "toneduration")) { 12561 int toneduration; 12562 int ctlfd; 12563 int res; 12564 struct zt_dialparams dps; 12565 12566 ctlfd = open("/dev/zap/ctl", O_RDWR); 12567 if (ctlfd == -1) { 12568 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 12569 return -1; 12570 } 12571 12572 toneduration = atoi(v->value); 12573 if (toneduration > -1) { 12574 memset(&dps, 0, sizeof(dps)); 12575 12576 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 12577 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 12578 if (res < 0) { 12579 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 12580 return -1; 12581 } 12582 } 12583 close(ctlfd); 12584 } else if (!strcasecmp(v->name, "defaultcic")) { 12585 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 12586 } else if (!strcasecmp(v->name, "defaultozz")) { 12587 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 12588 } 12589 } else if (!skipchannels) 12590 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12591 } 12592 if (zapchan[0]) { 12593 /* The user has set 'zapchan' */ 12594 /*< \todo pass proper line number instead of 0 */ 12595 if (build_channels(confp, 0, zapchan, reload, 0, &found_pseudo)) { 12596 return -1; 12597 } 12598 } 12599 /*< \todo why check for the pseudo in the per-channel section. 12600 * Any actual use for manual setup of the pseudo channel? */ 12601 if (!found_pseudo && reload == 0) { 12602 /* Make sure pseudo isn't a member of any groups if 12603 we're automatically making it. */ 12604 12605 confp->chan.group = 0; 12606 confp->chan.callgroup = 0; 12607 confp->chan.pickupgroup = 0; 12608 12609 tmp = mkintf(CHAN_PSEUDO, confp, NULL, reload); 12610 12611 if (tmp) { 12612 if (option_verbose > 2) 12613 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 12614 } else { 12615 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 12616 } 12617 } 12618 return 0; 12619 }
static int reload | ( | void | ) | [static] |
Definition at line 12975 of file chan_zap.c.
References ast_log(), and setup_zap().
12976 { 12977 int res = 0; 12978 12979 res = setup_zap(1); 12980 if (res) { 12981 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 12982 return -1; 12983 } 12984 return 0; 12985 }
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 7195 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), and LOG_ERROR.
07196 { 07197 pthread_attr_t attr; 07198 pthread_attr_init(&attr); 07199 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07200 /* If we're supposed to be stopped -- stay stopped */ 07201 if (monitor_thread == AST_PTHREADT_STOP) 07202 return 0; 07203 ast_mutex_lock(&monlock); 07204 if (monitor_thread == pthread_self()) { 07205 ast_mutex_unlock(&monlock); 07206 ast_log(LOG_WARNING, "Cannot kill myself\n"); 07207 return -1; 07208 } 07209 if (monitor_thread != AST_PTHREADT_NULL) { 07210 /* Wake up the thread */ 07211 pthread_kill(monitor_thread, SIGURG); 07212 } else { 07213 /* Start a new monitor */ 07214 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 07215 ast_mutex_unlock(&monlock); 07216 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 07217 pthread_attr_destroy(&attr); 07218 return -1; 07219 } 07220 } 07221 ast_mutex_unlock(&monlock); 07222 pthread_attr_destroy(&attr); 07223 return 0; 07224 }
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(), 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 12621 of file chan_zap.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), default_jbconf, global_jbconf, ast_variable::lineno, LOG_ERROR, ast_variable::name, ast_variable::next, option_verbose, process_zap(), restart_monitor(), ast_variable::value, VERBOSE_PREFIX_2, and zt_chan_conf_default().
Referenced by load_module(), reload(), and zap_restart().
12622 { 12623 struct ast_config *cfg; 12624 struct ast_variable *v; 12625 struct zt_chan_conf conf = zt_chan_conf_default(); 12626 int res; 12627 12628 #ifdef HAVE_PRI 12629 char *c; 12630 int spanno; 12631 int i, x; 12632 int logicalspan; 12633 int trunkgroup; 12634 int dchannels[NUM_DCHANS]; 12635 #endif 12636 12637 cfg = ast_config_load(config); 12638 12639 /* Error if we have no config file */ 12640 if (!cfg) { 12641 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 12642 return 0; 12643 } 12644 12645 /* It's a little silly to lock it, but we mind as well just to be sure */ 12646 ast_mutex_lock(&iflock); 12647 #ifdef HAVE_PRI 12648 if (!reload) { 12649 /* Process trunkgroups first */ 12650 v = ast_variable_browse(cfg, "trunkgroups"); 12651 while (v) { 12652 if (!strcasecmp(v->name, "trunkgroup")) { 12653 trunkgroup = atoi(v->value); 12654 if (trunkgroup > 0) { 12655 if ((c = strchr(v->value, ','))) { 12656 i = 0; 12657 memset(dchannels, 0, sizeof(dchannels)); 12658 while (c && (i < NUM_DCHANS)) { 12659 dchannels[i] = atoi(c + 1); 12660 if (dchannels[i] < 0) { 12661 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); 12662 } else 12663 i++; 12664 c = strchr(c + 1, ','); 12665 } 12666 if (i) { 12667 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 12668 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); 12669 } else if (option_verbose > 1) 12670 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"); 12671 } else 12672 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 12673 } else 12674 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 12675 } else 12676 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 12677 } else if (!strcasecmp(v->name, "spanmap")) { 12678 spanno = atoi(v->value); 12679 if (spanno > 0) { 12680 if ((c = strchr(v->value, ','))) { 12681 trunkgroup = atoi(c + 1); 12682 if (trunkgroup > 0) { 12683 if ((c = strchr(c + 1, ','))) 12684 logicalspan = atoi(c + 1); 12685 else 12686 logicalspan = 0; 12687 if (logicalspan >= 0) { 12688 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 12689 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 12690 } else if (option_verbose > 1) 12691 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 12692 } else 12693 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 12694 } else 12695 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 12696 } else 12697 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 12698 } else 12699 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 12700 } else { 12701 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 12702 } 12703 v = v->next; 12704 } 12705 } 12706 #endif 12707 12708 /* Copy the default jb config over global_jbconf */ 12709 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 12710 12711 v = ast_variable_browse(cfg, "channels"); 12712 res = process_zap(&conf, v, reload, 0); 12713 ast_mutex_unlock(&iflock); 12714 ast_config_destroy(cfg); 12715 if (res) 12716 return res; 12717 cfg = ast_config_load("users.conf"); 12718 if (cfg) { 12719 char *cat; 12720 const char *chans; 12721 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 12722 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 12723 if (!strcasecmp(cat, "general")) 12724 continue; 12725 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 12726 if (!ast_strlen_zero(chans)) { 12727 struct zt_chan_conf sect_conf; 12728 memcpy(§_conf, &conf, sizeof(sect_conf)); 12729 12730 process_zap(§_conf, ast_variable_browse(cfg, cat), reload, 0); 12731 } 12732 } 12733 ast_config_destroy(cfg); 12734 } 12735 #ifdef HAVE_PRI 12736 if (!reload) { 12737 for (x = 0; x < NUM_SPANS; x++) { 12738 pris[x].debugfd = -1; 12739 if (pris[x].pvts[0]) { 12740 if (start_pri(pris + x)) { 12741 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 12742 return -1; 12743 } else if (option_verbose > 1) 12744 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 12745 } 12746 } 12747 } 12748 #endif 12749 /* And start the monitor for the first time */ 12750 restart_monitor(); 12751 return 0; 12752 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5586 of file chan_zap.c.
References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), ast_smdi_md_message::calling_st, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, errno, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, f, free, func, ast_smdi_md_message::fwd_st, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, zt_pvt::lastcid_num, len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, manager_event(), my_getsigstr(), name, NEED_MFDETECT, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, zt_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zap_tech, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().
Referenced by handle_init_event(), and zt_handle_event().
05587 { 05588 struct ast_channel *chan = data; 05589 struct zt_pvt *p = chan->tech_pvt; 05590 char exten[AST_MAX_EXTENSION] = ""; 05591 char exten2[AST_MAX_EXTENSION] = ""; 05592 unsigned char buf[256]; 05593 char dtmfcid[300]; 05594 char dtmfbuf[300]; 05595 struct callerid_state *cs = NULL; 05596 char *name = NULL, *number = NULL; 05597 int distMatches; 05598 int curRingData[3]; 05599 int receivedRingT; 05600 int counter1; 05601 int counter; 05602 int samples = 0; 05603 struct ast_smdi_md_message *smdi_msg = NULL; 05604 int flags; 05605 int i; 05606 int timeout; 05607 int getforward = 0; 05608 char *s1, *s2; 05609 int len = 0; 05610 int res; 05611 int index; 05612 int network; 05613 05614 /* in the bizarre case where the channel has become a zombie before we 05615 even get started here, abort safely 05616 */ 05617 if (!p) { 05618 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05619 ast_hangup(chan); 05620 return NULL; 05621 } 05622 05623 if (option_verbose > 2) 05624 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05625 index = zt_get_index(chan, p, 1); 05626 if (index < 0) { 05627 ast_log(LOG_WARNING, "Huh?\n"); 05628 ast_hangup(chan); 05629 return NULL; 05630 } 05631 if (p->dsp) 05632 ast_dsp_digitreset(p->dsp); 05633 switch (p->sig) { 05634 #ifdef HAVE_PRI 05635 case SIG_PRI: 05636 /* Now loop looking for an extension */ 05637 ast_copy_string(exten, p->exten, sizeof(exten)); 05638 len = strlen(exten); 05639 res = 0; 05640 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05641 if (len && !ast_ignore_pattern(chan->context, exten)) { 05642 tone_zone_play_tone(p->subs[index].zfd, -1); 05643 } else { 05644 network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP; 05645 if (network) { 05646 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05647 } else { 05648 /* cpe be quiet */ 05649 tone_zone_play_tone(p->subs[index].zfd, -1); 05650 } 05651 } 05652 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05653 timeout = matchdigittimeout; 05654 else 05655 timeout = gendigittimeout; 05656 res = ast_waitfordigit(chan, timeout); 05657 if (res < 0) { 05658 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05659 ast_hangup(chan); 05660 return NULL; 05661 } else if (res) { 05662 exten[len++] = res; 05663 exten[len] = '\0'; 05664 } else 05665 break; 05666 } 05667 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05668 if (ast_strlen_zero(exten)) { 05669 if (option_verbose > 2) 05670 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05671 exten[0] = 's'; 05672 exten[1] = '\0'; 05673 } 05674 tone_zone_play_tone(p->subs[index].zfd, -1); 05675 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05676 /* Start the real PBX */ 05677 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05678 if (p->dsp) ast_dsp_digitreset(p->dsp); 05679 zt_enable_ec(p); 05680 ast_setstate(chan, AST_STATE_RING); 05681 res = ast_pbx_run(chan); 05682 if (res) { 05683 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05684 } 05685 } else { 05686 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05687 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05688 ast_hangup(chan); 05689 p->exten[0] = '\0'; 05690 /* Since we send release complete here, we won't get one */ 05691 p->call = NULL; 05692 } 05693 return NULL; 05694 break; 05695 #endif 05696 case SIG_FEATD: 05697 case SIG_FEATDMF: 05698 case SIG_FEATDMF_TA: 05699 case SIG_E911: 05700 case SIG_FGC_CAMAMF: 05701 case SIG_FEATB: 05702 case SIG_EMWINK: 05703 case SIG_SF_FEATD: 05704 case SIG_SF_FEATDMF: 05705 case SIG_SF_FEATB: 05706 case SIG_SFWINK: 05707 if (zt_wink(p, index)) 05708 return NULL; 05709 /* Fall through */ 05710 case SIG_EM: 05711 case SIG_EM_E1: 05712 case SIG_SF: 05713 case SIG_FGC_CAMA: 05714 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05715 if (p->dsp) 05716 ast_dsp_digitreset(p->dsp); 05717 /* set digit mode appropriately */ 05718 if (p->dsp) { 05719 if (NEED_MFDETECT(p)) 05720 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05721 else 05722 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05723 } 05724 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05725 /* Wait for the first digit only if immediate=no */ 05726 if (!p->immediate) 05727 /* Wait for the first digit (up to 5 seconds). */ 05728 res = ast_waitfordigit(chan, 5000); 05729 else 05730 res = 0; 05731 if (res > 0) { 05732 /* save first char */ 05733 dtmfbuf[0] = res; 05734 switch (p->sig) { 05735 case SIG_FEATD: 05736 case SIG_SF_FEATD: 05737 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05738 if (res > 0) 05739 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05740 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05741 break; 05742 case SIG_FEATDMF_TA: 05743 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05744 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05745 if (zt_wink(p, index)) return NULL; 05746 dtmfbuf[0] = 0; 05747 /* Wait for the first digit (up to 5 seconds). */ 05748 res = ast_waitfordigit(chan, 5000); 05749 if (res <= 0) break; 05750 dtmfbuf[0] = res; 05751 /* fall through intentionally */ 05752 case SIG_FEATDMF: 05753 case SIG_E911: 05754 case SIG_FGC_CAMAMF: 05755 case SIG_SF_FEATDMF: 05756 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05757 /* if international caca, do it again to get real ANO */ 05758 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05759 { 05760 if (zt_wink(p, index)) return NULL; 05761 dtmfbuf[0] = 0; 05762 /* Wait for the first digit (up to 5 seconds). */ 05763 res = ast_waitfordigit(chan, 5000); 05764 if (res <= 0) break; 05765 dtmfbuf[0] = res; 05766 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05767 } 05768 if (res > 0) { 05769 /* if E911, take off hook */ 05770 if (p->sig == SIG_E911) 05771 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05772 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05773 } 05774 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05775 break; 05776 case SIG_FEATB: 05777 case SIG_SF_FEATB: 05778 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05779 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05780 break; 05781 case SIG_EMWINK: 05782 /* if we received a '*', we are actually receiving Feature Group D 05783 dial syntax, so use that mode; otherwise, fall through to normal 05784 mode 05785 */ 05786 if (res == '*') { 05787 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05788 if (res > 0) 05789 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05790 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05791 break; 05792 } 05793 default: 05794 /* If we got the first digit, get the rest */ 05795 len = 1; 05796 dtmfbuf[len] = '\0'; 05797 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05798 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05799 timeout = matchdigittimeout; 05800 } else { 05801 timeout = gendigittimeout; 05802 } 05803 res = ast_waitfordigit(chan, timeout); 05804 if (res < 0) { 05805 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05806 ast_hangup(chan); 05807 return NULL; 05808 } else if (res) { 05809 dtmfbuf[len++] = res; 05810 dtmfbuf[len] = '\0'; 05811 } else { 05812 break; 05813 } 05814 } 05815 break; 05816 } 05817 } 05818 if (res == -1) { 05819 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05820 ast_hangup(chan); 05821 return NULL; 05822 } else if (res < 0) { 05823 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05824 ast_hangup(chan); 05825 return NULL; 05826 } 05827 05828 if (p->sig == SIG_FGC_CAMA) { 05829 char anibuf[100]; 05830 05831 if (ast_safe_sleep(chan,1000) == -1) { 05832 ast_hangup(chan); 05833 return NULL; 05834 } 05835 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05836 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05837 res = my_getsigstr(chan, anibuf, "#", 10000); 05838 if ((res > 0) && (strlen(anibuf) > 2)) { 05839 if (anibuf[strlen(anibuf) - 1] == '#') 05840 anibuf[strlen(anibuf) - 1] = 0; 05841 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05842 } 05843 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05844 } 05845 05846 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05847 if (ast_strlen_zero(exten)) 05848 ast_copy_string(exten, "s", sizeof(exten)); 05849 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05850 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05851 if (exten[0] == '*') { 05852 char *stringp=NULL; 05853 ast_copy_string(exten2, exten, sizeof(exten2)); 05854 /* Parse out extension and callerid */ 05855 stringp=exten2 +1; 05856 s1 = strsep(&stringp, "*"); 05857 s2 = strsep(&stringp, "*"); 05858 if (s2) { 05859 if (!ast_strlen_zero(p->cid_num)) 05860 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05861 else 05862 ast_set_callerid(chan, s1, NULL, s1); 05863 ast_copy_string(exten, s2, sizeof(exten)); 05864 } else 05865 ast_copy_string(exten, s1, sizeof(exten)); 05866 } else if (p->sig == SIG_FEATD) 05867 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05868 } 05869 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05870 if (exten[0] == '*') { 05871 char *stringp=NULL; 05872 ast_copy_string(exten2, exten, sizeof(exten2)); 05873 /* Parse out extension and callerid */ 05874 stringp=exten2 +1; 05875 s1 = strsep(&stringp, "#"); 05876 s2 = strsep(&stringp, "#"); 05877 if (s2) { 05878 if (!ast_strlen_zero(p->cid_num)) 05879 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05880 else 05881 if (*(s1 + 2)) 05882 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05883 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05884 } else 05885 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05886 } else 05887 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05888 } 05889 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05890 if (exten[0] == '*') { 05891 char *stringp=NULL; 05892 ast_copy_string(exten2, exten, sizeof(exten2)); 05893 /* Parse out extension and callerid */ 05894 stringp=exten2 +1; 05895 s1 = strsep(&stringp, "#"); 05896 s2 = strsep(&stringp, "#"); 05897 if (s2 && (*(s2 + 1) == '0')) { 05898 if (*(s2 + 2)) 05899 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05900 } 05901 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05902 else ast_copy_string(exten, "911", sizeof(exten)); 05903 } else 05904 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 05905 } 05906 if (p->sig == SIG_FEATB) { 05907 if (exten[0] == '*') { 05908 char *stringp=NULL; 05909 ast_copy_string(exten2, exten, sizeof(exten2)); 05910 /* Parse out extension and callerid */ 05911 stringp=exten2 +1; 05912 s1 = strsep(&stringp, "#"); 05913 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05914 } else 05915 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05916 } 05917 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05918 zt_wink(p, index); 05919 /* some switches require a minimum guard time between 05920 the last FGD wink and something that answers 05921 immediately. This ensures it */ 05922 if (ast_safe_sleep(chan,100)) return NULL; 05923 } 05924 zt_enable_ec(p); 05925 if (NEED_MFDETECT(p)) { 05926 if (p->dsp) { 05927 if (!p->hardwaredtmf) 05928 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05929 else { 05930 ast_dsp_free(p->dsp); 05931 p->dsp = NULL; 05932 } 05933 } 05934 } 05935 05936 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05937 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05938 if (p->dsp) ast_dsp_digitreset(p->dsp); 05939 res = ast_pbx_run(chan); 05940 if (res) { 05941 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05942 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05943 } 05944 return NULL; 05945 } else { 05946 if (option_verbose > 2) 05947 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05948 sleep(2); 05949 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05950 if (res < 0) 05951 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05952 else 05953 sleep(1); 05954 res = ast_streamfile(chan, "ss-noservice", chan->language); 05955 if (res >= 0) 05956 ast_waitstream(chan, ""); 05957 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05958 ast_hangup(chan); 05959 return NULL; 05960 } 05961 break; 05962 case SIG_FXOLS: 05963 case SIG_FXOGS: 05964 case SIG_FXOKS: 05965 /* Read the first digit */ 05966 timeout = firstdigittimeout; 05967 /* If starting a threeway call, never timeout on the first digit so someone 05968 can use flash-hook as a "hold" feature */ 05969 if (p->subs[SUB_THREEWAY].owner) 05970 timeout = 999999; 05971 while (len < AST_MAX_EXTENSION-1) { 05972 /* Read digit unless it's supposed to be immediate, in which case the 05973 only answer is 's' */ 05974 if (p->immediate) 05975 res = 's'; 05976 else 05977 res = ast_waitfordigit(chan, timeout); 05978 timeout = 0; 05979 if (res < 0) { 05980 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05981 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05982 ast_hangup(chan); 05983 return NULL; 05984 } else if (res) { 05985 exten[len++]=res; 05986 exten[len] = '\0'; 05987 } 05988 if (!ast_ignore_pattern(chan->context, exten)) 05989 tone_zone_play_tone(p->subs[index].zfd, -1); 05990 else 05991 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05992 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05993 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05994 if (getforward) { 05995 /* Record this as the forwarding extension */ 05996 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05997 if (option_verbose > 2) 05998 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 05999 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06000 if (res) 06001 break; 06002 usleep(500000); 06003 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06004 sleep(1); 06005 memset(exten, 0, sizeof(exten)); 06006 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 06007 len = 0; 06008 getforward = 0; 06009 } else { 06010 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06011 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06012 if (!ast_strlen_zero(p->cid_num)) { 06013 if (!p->hidecallerid) 06014 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 06015 else 06016 ast_set_callerid(chan, NULL, NULL, p->cid_num); 06017 } 06018 if (!ast_strlen_zero(p->cid_name)) { 06019 if (!p->hidecallerid) 06020 ast_set_callerid(chan, NULL, p->cid_name, NULL); 06021 } 06022 ast_setstate(chan, AST_STATE_RING); 06023 zt_enable_ec(p); 06024 res = ast_pbx_run(chan); 06025 if (res) { 06026 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06027 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06028 } 06029 return NULL; 06030 } 06031 } else { 06032 /* It's a match, but they just typed a digit, and there is an ambiguous match, 06033 so just set the timeout to matchdigittimeout and wait some more */ 06034 timeout = matchdigittimeout; 06035 } 06036 } else if (res == 0) { 06037 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 06038 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06039 zt_wait_event(p->subs[index].zfd); 06040 ast_hangup(chan); 06041 return NULL; 06042 } else if (p->callwaiting && !strcmp(exten, "*70")) { 06043 if (option_verbose > 2) 06044 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 06045 /* Disable call waiting if enabled */ 06046 p->callwaiting = 0; 06047 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06048 if (res) { 06049 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06050 chan->name, strerror(errno)); 06051 } 06052 len = 0; 06053 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 06054 memset(exten, 0, sizeof(exten)); 06055 timeout = firstdigittimeout; 06056 06057 } else if (!strcmp(exten,ast_pickup_ext())) { 06058 /* Scan all channels and see if there are any 06059 * ringing channels that have call groups 06060 * that equal this channels pickup group 06061 */ 06062 if (index == SUB_REAL) { 06063 /* Switch us from Third call to Call Wait */ 06064 if (p->subs[SUB_THREEWAY].owner) { 06065 /* If you make a threeway call and the *8# a call, it should actually 06066 look like a callwait */ 06067 alloc_sub(p, SUB_CALLWAIT); 06068 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06069 unalloc_sub(p, SUB_THREEWAY); 06070 } 06071 zt_enable_ec(p); 06072 if (ast_pickup_call(chan)) { 06073 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 06074 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06075 zt_wait_event(p->subs[index].zfd); 06076 } 06077 ast_hangup(chan); 06078 return NULL; 06079 } else { 06080 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 06081 ast_hangup(chan); 06082 return NULL; 06083 } 06084 06085 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 06086 if (option_verbose > 2) 06087 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 06088 /* Disable Caller*ID if enabled */ 06089 p->hidecallerid = 1; 06090 if (chan->cid.cid_num) 06091 free(chan->cid.cid_num); 06092 chan->cid.cid_num = NULL; 06093 if (chan->cid.cid_name) 06094 free(chan->cid.cid_name); 06095 chan->cid.cid_name = NULL; 06096 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06097 if (res) { 06098 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06099 chan->name, strerror(errno)); 06100 } 06101 len = 0; 06102 memset(exten, 0, sizeof(exten)); 06103 timeout = firstdigittimeout; 06104 } else if (p->callreturn && !strcmp(exten, "*69")) { 06105 res = 0; 06106 if (!ast_strlen_zero(p->lastcid_num)) { 06107 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 06108 } 06109 if (!res) 06110 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06111 break; 06112 } else if (!strcmp(exten, "*78")) { 06113 /* Do not disturb */ 06114 if (option_verbose > 2) 06115 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 06116 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 06117 "Channel: Zap/%d\r\n" 06118 "Status: enabled\r\n", p->channel); 06119 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06120 p->dnd = 1; 06121 getforward = 0; 06122 memset(exten, 0, sizeof(exten)); 06123 len = 0; 06124 } else if (!strcmp(exten, "*79")) { 06125 /* Do not disturb */ 06126 if (option_verbose > 2) 06127 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 06128 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 06129 "Channel: Zap/%d\r\n" 06130 "Status: disabled\r\n", p->channel); 06131 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06132 p->dnd = 0; 06133 getforward = 0; 06134 memset(exten, 0, sizeof(exten)); 06135 len = 0; 06136 } else if (p->cancallforward && !strcmp(exten, "*72")) { 06137 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06138 getforward = 1; 06139 memset(exten, 0, sizeof(exten)); 06140 len = 0; 06141 } else if (p->cancallforward && !strcmp(exten, "*73")) { 06142 if (option_verbose > 2) 06143 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 06144 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06145 memset(p->call_forward, 0, sizeof(p->call_forward)); 06146 getforward = 0; 06147 memset(exten, 0, sizeof(exten)); 06148 len = 0; 06149 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 06150 p->subs[SUB_THREEWAY].owner && 06151 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06152 /* This is a three way call, the main call being a real channel, 06153 and we're parking the first call. */ 06154 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 06155 if (option_verbose > 2) 06156 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 06157 break; 06158 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 06159 if (option_verbose > 2) 06160 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 06161 res = ast_db_put("blacklist", p->lastcid_num, "1"); 06162 if (!res) { 06163 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06164 memset(exten, 0, sizeof(exten)); 06165 len = 0; 06166 } 06167 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 06168 if (option_verbose > 2) 06169 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 06170 /* Enable Caller*ID if enabled */ 06171 p->hidecallerid = 0; 06172 if (chan->cid.cid_num) 06173 free(chan->cid.cid_num); 06174 chan->cid.cid_num = NULL; 06175 if (chan->cid.cid_name) 06176 free(chan->cid.cid_name); 06177 chan->cid.cid_name = NULL; 06178 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 06179 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06180 if (res) { 06181 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06182 chan->name, strerror(errno)); 06183 } 06184 len = 0; 06185 memset(exten, 0, sizeof(exten)); 06186 timeout = firstdigittimeout; 06187 } else if (!strcmp(exten, "*0")) { 06188 struct ast_channel *nbridge = 06189 p->subs[SUB_THREEWAY].owner; 06190 struct zt_pvt *pbridge = NULL; 06191 /* set up the private struct of the bridged one, if any */ 06192 if (nbridge && ast_bridged_channel(nbridge)) 06193 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 06194 if (nbridge && pbridge && 06195 (nbridge->tech == &zap_tech) && 06196 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 06197 ISTRUNK(pbridge)) { 06198 int func = ZT_FLASH; 06199 /* Clear out the dial buffer */ 06200 p->dop.dialstr[0] = '\0'; 06201 /* flash hookswitch */ 06202 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 06203 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 06204 nbridge->name, strerror(errno)); 06205 } 06206 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06207 unalloc_sub(p, SUB_THREEWAY); 06208 p->owner = p->subs[SUB_REAL].owner; 06209 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06210 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06211 ast_hangup(chan); 06212 return NULL; 06213 } else { 06214 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06215 zt_wait_event(p->subs[index].zfd); 06216 tone_zone_play_tone(p->subs[index].zfd, -1); 06217 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06218 unalloc_sub(p, SUB_THREEWAY); 06219 p->owner = p->subs[SUB_REAL].owner; 06220 ast_hangup(chan); 06221 return NULL; 06222 } 06223 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06224 ((exten[0] != '*') || (strlen(exten) > 2))) { 06225 if (option_debug) 06226 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); 06227 break; 06228 } 06229 if (!timeout) 06230 timeout = gendigittimeout; 06231 if (len && !ast_ignore_pattern(chan->context, exten)) 06232 tone_zone_play_tone(p->subs[index].zfd, -1); 06233 } 06234 break; 06235 case SIG_FXSLS: 06236 case SIG_FXSGS: 06237 case SIG_FXSKS: 06238 #ifdef HAVE_PRI 06239 if (p->pri) { 06240 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06241 struct ast_frame *f; 06242 int res; 06243 time_t start; 06244 06245 time(&start); 06246 ast_setstate(chan, AST_STATE_RING); 06247 while (time(NULL) < start + 3) { 06248 res = ast_waitfor(chan, 1000); 06249 if (res) { 06250 f = ast_read(chan); 06251 if (!f) { 06252 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06253 ast_hangup(chan); 06254 return NULL; 06255 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06256 res = 1; 06257 } else 06258 res = 0; 06259 ast_frfree(f); 06260 if (res) { 06261 ast_log(LOG_DEBUG, "Got ring!\n"); 06262 res = 0; 06263 break; 06264 } 06265 } 06266 } 06267 } 06268 #endif 06269 /* check for SMDI messages */ 06270 if (p->use_smdi && p->smdi_iface) { 06271 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06272 06273 if (smdi_msg != NULL) { 06274 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06275 06276 if (smdi_msg->type == 'B') 06277 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06278 else if (smdi_msg->type == 'N') 06279 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06280 06281 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06282 } else { 06283 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06284 } 06285 } 06286 06287 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06288 number = smdi_msg->calling_st; 06289 06290 /* If we want caller id, we're in a prering state due to a polarity reversal 06291 * and we're set to use a polarity reversal to trigger the start of caller id, 06292 * grab the caller id and wait for ringing to start... */ 06293 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06294 /* If set to use DTMF CID signalling, listen for DTMF */ 06295 if (p->cid_signalling == CID_SIG_DTMF) { 06296 int i = 0; 06297 cs = NULL; 06298 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06299 "channel %s\n", chan->name); 06300 zt_setlinear(p->subs[index].zfd, 0); 06301 res = 2000; 06302 for (;;) { 06303 struct ast_frame *f; 06304 res = ast_waitfor(chan, res); 06305 if (res <= 0) { 06306 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06307 "Exiting simple switch\n"); 06308 ast_hangup(chan); 06309 return NULL; 06310 } 06311 f = ast_read(chan); 06312 if (!f) 06313 break; 06314 if (f->frametype == AST_FRAME_DTMF) { 06315 dtmfbuf[i++] = f->subclass; 06316 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06317 res = 2000; 06318 } 06319 ast_frfree(f); 06320 if (chan->_state == AST_STATE_RING || 06321 chan->_state == AST_STATE_RINGING) 06322 break; /* Got ring */ 06323 } 06324 dtmfbuf[i] = '\0'; 06325 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06326 /* Got cid and ring. */ 06327 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06328 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06329 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06330 dtmfcid, flags); 06331 /* If first byte is NULL, we have no cid */ 06332 if (!ast_strlen_zero(dtmfcid)) 06333 number = dtmfcid; 06334 else 06335 number = NULL; 06336 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06337 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06338 cs = callerid_new(p->cid_signalling); 06339 if (cs) { 06340 samples = 0; 06341 #if 1 06342 bump_gains(p); 06343 #endif 06344 /* Take out of linear mode for Caller*ID processing */ 06345 zt_setlinear(p->subs[index].zfd, 0); 06346 06347 /* First we wait and listen for the Caller*ID */ 06348 for (;;) { 06349 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06350 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06351 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06352 callerid_free(cs); 06353 ast_hangup(chan); 06354 return NULL; 06355 } 06356 if (i & ZT_IOMUX_SIGEVENT) { 06357 res = zt_get_event(p->subs[index].zfd); 06358 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06359 06360 if (p->cid_signalling == CID_SIG_V23_JP) { 06361 #ifdef ZT_EVENT_RINGBEGIN 06362 if (res == ZT_EVENT_RINGBEGIN) { 06363 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06364 usleep(1); 06365 } 06366 #endif 06367 } else { 06368 res = 0; 06369 break; 06370 } 06371 } else if (i & ZT_IOMUX_READ) { 06372 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06373 if (res < 0) { 06374 if (errno != ELAST) { 06375 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06376 callerid_free(cs); 06377 ast_hangup(chan); 06378 return NULL; 06379 } 06380 break; 06381 } 06382 samples += res; 06383 06384 if (p->cid_signalling == CID_SIG_V23_JP) { 06385 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06386 } else { 06387 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06388 } 06389 06390 if (res < 0) { 06391 ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name); 06392 break; 06393 } else if (res) 06394 break; 06395 else if (samples > (8000 * 10)) 06396 break; 06397 } 06398 } 06399 if (res == 1) { 06400 callerid_get(cs, &name, &number, &flags); 06401 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06402 } 06403 06404 if (p->cid_signalling == CID_SIG_V23_JP) { 06405 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06406 usleep(1); 06407 res = 4000; 06408 } else { 06409 06410 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06411 res = 2000; 06412 } 06413 06414 for (;;) { 06415 struct ast_frame *f; 06416 res = ast_waitfor(chan, res); 06417 if (res <= 0) { 06418 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06419 "Exiting simple switch\n"); 06420 ast_hangup(chan); 06421 return NULL; 06422 } 06423 f = ast_read(chan); 06424 ast_frfree(f); 06425 if (chan->_state == AST_STATE_RING || 06426 chan->_state == AST_STATE_RINGING) 06427 break; /* Got ring */ 06428 } 06429 06430 /* We must have a ring by now, so, if configured, lets try to listen for 06431 * distinctive ringing */ 06432 if (p->usedistinctiveringdetection == 1) { 06433 len = 0; 06434 distMatches = 0; 06435 /* Clear the current ring data array so we dont have old data in it. */ 06436 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06437 curRingData[receivedRingT] = 0; 06438 receivedRingT = 0; 06439 counter = 0; 06440 counter1 = 0; 06441 /* Check to see if context is what it should be, if not set to be. */ 06442 if (strcmp(p->context,p->defcontext) != 0) { 06443 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06444 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06445 } 06446 06447 for (;;) { 06448 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06449 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06450 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06451 callerid_free(cs); 06452 ast_hangup(chan); 06453 return NULL; 06454 } 06455 if (i & ZT_IOMUX_SIGEVENT) { 06456 res = zt_get_event(p->subs[index].zfd); 06457 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06458 res = 0; 06459 /* Let us detect distinctive ring */ 06460 06461 curRingData[receivedRingT] = p->ringt; 06462 06463 if (p->ringt < p->ringt_base/2) 06464 break; 06465 /* Increment the ringT counter so we can match it against 06466 values in zapata.conf for distinctive ring */ 06467 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06468 break; 06469 } else if (i & ZT_IOMUX_READ) { 06470 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06471 if (res < 0) { 06472 if (errno != ELAST) { 06473 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06474 callerid_free(cs); 06475 ast_hangup(chan); 06476 return NULL; 06477 } 06478 break; 06479 } 06480 if (p->ringt) 06481 p->ringt--; 06482 if (p->ringt == 1) { 06483 res = -1; 06484 break; 06485 } 06486 } 06487 } 06488 if (option_verbose > 2) 06489 /* this only shows up if you have n of the dring patterns filled in */ 06490 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06491 06492 for (counter = 0; counter < 3; counter++) { 06493 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06494 channel */ 06495 distMatches = 0; 06496 for (counter1 = 0; counter1 < 3; counter1++) { 06497 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06498 (p->drings.ringnum[counter].ring[counter1]-10)) { 06499 distMatches++; 06500 } 06501 } 06502 if (distMatches == 3) { 06503 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06504 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06505 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06506 if (option_verbose > 2) 06507 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06508 break; 06509 } 06510 } 06511 } 06512 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06513 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06514 #if 1 06515 restore_gains(p); 06516 #endif 06517 } else 06518 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06519 } else { 06520 ast_log(LOG_WARNING, "Channel %s in prering " 06521 "state, but I have nothing to do. " 06522 "Terminating simple switch, should be " 06523 "restarted by the actual ring.\n", 06524 chan->name); 06525 ast_hangup(chan); 06526 return NULL; 06527 } 06528 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06529 /* FSK Bell202 callerID */ 06530 cs = callerid_new(p->cid_signalling); 06531 if (cs) { 06532 #if 1 06533 bump_gains(p); 06534 #endif 06535 samples = 0; 06536 len = 0; 06537 distMatches = 0; 06538 /* Clear the current ring data array so we dont have old data in it. */ 06539 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06540 curRingData[receivedRingT] = 0; 06541 receivedRingT = 0; 06542 counter = 0; 06543 counter1 = 0; 06544 /* Check to see if context is what it should be, if not set to be. */ 06545 if (strcmp(p->context,p->defcontext) != 0) { 06546 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06547 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06548 } 06549 06550 /* Take out of linear mode for Caller*ID processing */ 06551 zt_setlinear(p->subs[index].zfd, 0); 06552 for (;;) { 06553 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06554 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06555 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06556 callerid_free(cs); 06557 ast_hangup(chan); 06558 return NULL; 06559 } 06560 if (i & ZT_IOMUX_SIGEVENT) { 06561 res = zt_get_event(p->subs[index].zfd); 06562 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06563 /* If we get a PR event, they hung up while processing calerid */ 06564 if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 06565 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 06566 p->polarity = POLARITY_IDLE; 06567 callerid_free(cs); 06568 ast_hangup(chan); 06569 return NULL; 06570 } 06571 res = 0; 06572 /* Let us detect callerid when the telco uses distinctive ring */ 06573 06574 curRingData[receivedRingT] = p->ringt; 06575 06576 if (p->ringt < p->ringt_base/2) 06577 break; 06578 /* Increment the ringT counter so we can match it against 06579 values in zapata.conf for distinctive ring */ 06580 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06581 break; 06582 } else if (i & ZT_IOMUX_READ) { 06583 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06584 if (res < 0) { 06585 if (errno != ELAST) { 06586 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06587 callerid_free(cs); 06588 ast_hangup(chan); 06589 return NULL; 06590 } 06591 break; 06592 } 06593 if (p->ringt) 06594 p->ringt--; 06595 if (p->ringt == 1) { 06596 res = -1; 06597 break; 06598 } 06599 samples += res; 06600 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06601 if (res < 0) { 06602 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06603 break; 06604 } else if (res) 06605 break; 06606 else if (samples > (8000 * 10)) 06607 break; 06608 } 06609 } 06610 if (res == 1) { 06611 callerid_get(cs, &name, &number, &flags); 06612 if (option_debug) 06613 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06614 } 06615 if (distinctiveringaftercid == 1) { 06616 /* Clear the current ring data array so we dont have old data in it. */ 06617 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06618 curRingData[receivedRingT] = 0; 06619 } 06620 receivedRingT = 0; 06621 if (option_verbose > 2) 06622 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06623 for (;;) { 06624 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06625 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06626 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06627 callerid_free(cs); 06628 ast_hangup(chan); 06629 return NULL; 06630 } 06631 if (i & ZT_IOMUX_SIGEVENT) { 06632 res = zt_get_event(p->subs[index].zfd); 06633 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06634 res = 0; 06635 /* Let us detect callerid when the telco uses distinctive ring */ 06636 06637 curRingData[receivedRingT] = p->ringt; 06638 06639 if (p->ringt < p->ringt_base/2) 06640 break; 06641 /* Increment the ringT counter so we can match it against 06642 values in zapata.conf for distinctive ring */ 06643 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06644 break; 06645 } else if (i & ZT_IOMUX_READ) { 06646 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06647 if (res < 0) { 06648 if (errno != ELAST) { 06649 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06650 callerid_free(cs); 06651 ast_hangup(chan); 06652 return NULL; 06653 } 06654 break; 06655 } 06656 if (p->ringt) 06657 p->ringt--; 06658 if (p->ringt == 1) { 06659 res = -1; 06660 break; 06661 } 06662 } 06663 } 06664 } 06665 if (p->usedistinctiveringdetection == 1) { 06666 if (option_verbose > 2) 06667 /* this only shows up if you have n of the dring patterns filled in */ 06668 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06669 06670 for (counter = 0; counter < 3; counter++) { 06671 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06672 channel */ 06673 if (option_verbose > 2) 06674 /* this only shows up if you have n of the dring patterns filled in */ 06675 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06676 p->drings.ringnum[counter].ring[0], 06677 p->drings.ringnum[counter].ring[1], 06678 p->drings.ringnum[counter].ring[2]); 06679 distMatches = 0; 06680 for (counter1 = 0; counter1 < 3; counter1++) { 06681 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06682 (p->drings.ringnum[counter].ring[counter1]-10)) { 06683 distMatches++; 06684 } 06685 } 06686 if (distMatches == 3) { 06687 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06688 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06689 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06690 if (option_verbose > 2) 06691 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06692 break; 06693 } 06694 } 06695 } 06696 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06697 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06698 #if 1 06699 restore_gains(p); 06700 #endif 06701 if (res < 0) { 06702 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06703 } 06704 } else 06705 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06706 } 06707 else 06708 cs = NULL; 06709 06710 if (number) 06711 ast_shrink_phone_number(number); 06712 ast_set_callerid(chan, number, name, number); 06713 06714 if (smdi_msg) 06715 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06716 06717 if (cs) 06718 callerid_free(cs); 06719 06720 ast_setstate(chan, AST_STATE_RING); 06721 chan->rings = 1; 06722 p->ringt = p->ringt_base; 06723 res = ast_pbx_run(chan); 06724 if (res) { 06725 ast_hangup(chan); 06726 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06727 } 06728 return NULL; 06729 default: 06730 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06731 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06732 if (res < 0) 06733 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06734 } 06735 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06736 if (res < 0) 06737 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06738 ast_hangup(chan); 06739 return NULL; 06740 }
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 11806 of file chan_zap.c.
References __unload_module(), and ast_mutex_destroy().
11807 { 11808 #ifdef HAVE_PRI 11809 int y; 11810 for (y = 0; y < NUM_SPANS; y++) 11811 ast_mutex_destroy(&pris[y].lock); 11812 #endif 11813 return __unload_module(); 11814 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1411 of file chan_zap.c.
References conf_add(), conf_del(), zt_subchannel::inthreeway, isslavenative(), zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), zt_bridge(), zt_handle_event(), and zt_hangup().
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_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 11158 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
11159 { 11160 int channel; 11161 11162 if (argc != 4) 11163 return RESULT_SHOWUSAGE; 11164 11165 channel = atoi(argv[3]); 11166 11167 return zap_destroy_channel_bynum(channel); 11168 }
static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6743 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().
06744 { 06745 struct zt_pvt *tmp = NULL; 06746 struct zt_pvt *prev = NULL; 06747 06748 tmp = iflist; 06749 while (tmp) { 06750 if (tmp->channel == channel) { 06751 destroy_channel(prev, tmp, 1); 06752 return RESULT_SUCCESS; 06753 } 06754 prev = tmp; 06755 tmp = tmp->next; 06756 } 06757 return RESULT_FAILURE; 06758 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 11546 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
11547 { 11548 if (p) { 11549 switch (mode) { 11550 case TRANSFER: 11551 p->fake_event = ZT_EVENT_WINKFLASH; 11552 break; 11553 case HANGUP: 11554 p->fake_event = ZT_EVENT_ONHOOK; 11555 break; 11556 default: 11557 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 11558 } 11559 } 11560 return 0; 11561 }
Definition at line 869 of file chan_zap.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, 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 11171 of file chan_zap.c.
References ast_log(), ast_verbose(), destroy_channel(), iflist, option_debug, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.
Referenced by action_zaprestart(), and zap_restart_cmd().
11172 { 11173 if (option_verbose > 0) 11174 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 11175 while (iflist) { 11176 if (option_debug) 11177 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 11178 /* Also updates iflist: */ 11179 destroy_channel(NULL, iflist, 1); 11180 } 11181 if (option_debug) 11182 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 11183 if (setup_zap(0) != 0) { 11184 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 11185 return 1; 11186 } 11187 return 0; 11188 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11190 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
11191 { 11192 if (argc != 2) { 11193 return RESULT_SHOWUSAGE; 11194 } 11195 11196 if (zap_restart() != 0) 11197 return RESULT_FAILURE; 11198 return RESULT_SUCCESS; 11199 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11272 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, zt_pvt::master, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
11273 { 11274 int channel; 11275 struct zt_pvt *tmp = NULL; 11276 ZT_CONFINFO ci; 11277 ZT_PARAMS ps; 11278 int x; 11279 ast_mutex_t *lock; 11280 struct zt_pvt *start; 11281 #ifdef HAVE_PRI 11282 char *c; 11283 int trunkgroup; 11284 struct zt_pri *pri=NULL; 11285 #endif 11286 11287 lock = &iflock; 11288 start = iflist; 11289 11290 if (argc != 4) 11291 return RESULT_SHOWUSAGE; 11292 #ifdef HAVE_PRI 11293 if ((c = strchr(argv[3], ':'))) { 11294 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 11295 return RESULT_SHOWUSAGE; 11296 if ((trunkgroup < 1) || (channel < 1)) 11297 return RESULT_SHOWUSAGE; 11298 for (x = 0; x < NUM_SPANS; x++) { 11299 if (pris[x].trunkgroup == trunkgroup) { 11300 pri = pris + x; 11301 break; 11302 } 11303 } 11304 if (pri) { 11305 start = pri->crvs; 11306 lock = &pri->lock; 11307 } else { 11308 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 11309 return RESULT_FAILURE; 11310 } 11311 } else 11312 #endif 11313 channel = atoi(argv[3]); 11314 11315 ast_mutex_lock(lock); 11316 tmp = start; 11317 while (tmp) { 11318 if (tmp->channel == channel) { 11319 #ifdef HAVE_PRI 11320 if (pri) 11321 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 11322 else 11323 #endif 11324 ast_cli(fd, "Channel: %d\n", tmp->channel); 11325 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 11326 ast_cli(fd, "Span: %d\n", tmp->span); 11327 ast_cli(fd, "Extension: %s\n", tmp->exten); 11328 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 11329 ast_cli(fd, "Context: %s\n", tmp->context); 11330 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 11331 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 11332 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 11333 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 11334 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 11335 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 11336 ast_cli(fd, "Radio: %d\n", tmp->radio); 11337 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 11338 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)" : ""); 11339 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)" : ""); 11340 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)" : ""); 11341 ast_cli(fd, "Confno: %d\n", tmp->confno); 11342 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 11343 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 11344 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 11345 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 11346 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 11347 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 11348 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 11349 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 11350 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 11351 if (tmp->master) 11352 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 11353 for (x = 0; x < MAX_SLAVES; x++) { 11354 if (tmp->slaves[x]) 11355 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 11356 } 11357 #ifdef HAVE_PRI 11358 if (tmp->pri) { 11359 ast_cli(fd, "PRI Flags: "); 11360 if (tmp->resetting) 11361 ast_cli(fd, "Resetting "); 11362 if (tmp->call) 11363 ast_cli(fd, "Call "); 11364 if (tmp->bearer) 11365 ast_cli(fd, "Bearer "); 11366 ast_cli(fd, "\n"); 11367 if (tmp->logicalspan) 11368 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 11369 else 11370 ast_cli(fd, "PRI Logical Span: Implicit\n"); 11371 } 11372 11373 #endif 11374 memset(&ci, 0, sizeof(ci)); 11375 ps.channo = tmp->channel; 11376 if (tmp->subs[SUB_REAL].zfd > -1) { 11377 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 11378 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 11379 } 11380 #ifdef ZT_GETCONFMUTE 11381 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 11382 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 11383 } 11384 #endif 11385 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 11386 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 11387 } else { 11388 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 11389 } 11390 } 11391 ast_mutex_unlock(lock); 11392 return RESULT_SUCCESS; 11393 } 11394 tmp = tmp->next; 11395 } 11396 11397 ast_cli(fd, "Unable to find given channel %d\n", channel); 11398 ast_mutex_unlock(lock); 11399 return RESULT_FAILURE; 11400 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11211 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, zt_pvt::mohinterpret, zt_pvt::next, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11212 { 11213 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 11214 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 11215 struct zt_pvt *tmp = NULL; 11216 char tmps[20] = ""; 11217 ast_mutex_t *lock; 11218 struct zt_pvt *start; 11219 #ifdef HAVE_PRI 11220 int trunkgroup; 11221 struct zt_pri *pri = NULL; 11222 int x; 11223 #endif 11224 11225 lock = &iflock; 11226 start = iflist; 11227 11228 #ifdef HAVE_PRI 11229 if (argc == 4) { 11230 if ((trunkgroup = atoi(argv[3])) < 1) 11231 return RESULT_SHOWUSAGE; 11232 for (x = 0; x < NUM_SPANS; x++) { 11233 if (pris[x].trunkgroup == trunkgroup) { 11234 pri = pris + x; 11235 break; 11236 } 11237 } 11238 if (pri) { 11239 start = pri->crvs; 11240 lock = &pri->lock; 11241 } else { 11242 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 11243 return RESULT_FAILURE; 11244 } 11245 } else 11246 #endif 11247 if (argc != 3) 11248 return RESULT_SHOWUSAGE; 11249 11250 ast_mutex_lock(lock); 11251 #ifdef HAVE_PRI 11252 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 11253 #else 11254 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 11255 #endif 11256 11257 tmp = start; 11258 while (tmp) { 11259 if (tmp->channel > 0) { 11260 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 11261 } else 11262 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 11263 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 11264 tmp = tmp->next; 11265 } 11266 ast_mutex_unlock(lock); 11267 return RESULT_SUCCESS; 11268 #undef FORMAT 11269 #undef FORMAT2 11270 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11433 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), errno, FORMAT, FORMAT2, and RESULT_FAILURE.
11433 { 11434 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 11435 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 11436 11437 int span; 11438 int res; 11439 char alarms[50]; 11440 11441 int ctl; 11442 ZT_SPANINFO s; 11443 11444 ctl = open("/dev/zap/ctl", O_RDWR); 11445 if (ctl < 0) { 11446 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 11447 ast_cli(fd, "No Zaptel interface found.\n"); 11448 return RESULT_FAILURE; 11449 } 11450 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 11451 11452 for (span = 1; span < ZT_MAX_SPANS; ++span) { 11453 s.spanno = span; 11454 res = ioctl(ctl, ZT_SPANSTAT, &s); 11455 if (res) { 11456 continue; 11457 } 11458 alarms[0] = '\0'; 11459 if (s.alarms > 0) { 11460 if (s.alarms & ZT_ALARM_BLUE) 11461 strcat(alarms, "BLU/"); 11462 if (s.alarms & ZT_ALARM_YELLOW) 11463 strcat(alarms, "YEL/"); 11464 if (s.alarms & ZT_ALARM_RED) 11465 strcat(alarms, "RED/"); 11466 if (s.alarms & ZT_ALARM_LOOPBACK) 11467 strcat(alarms, "LB/"); 11468 if (s.alarms & ZT_ALARM_RECOVER) 11469 strcat(alarms, "REC/"); 11470 if (s.alarms & ZT_ALARM_NOTOPEN) 11471 strcat(alarms, "NOP/"); 11472 if (!strlen(alarms)) 11473 strcat(alarms, "UUU/"); 11474 if (strlen(alarms)) { 11475 /* Strip trailing / */ 11476 alarms[strlen(alarms) - 1] = '\0'; 11477 } 11478 } else { 11479 if (s.numchans) 11480 strcpy(alarms, "OK"); 11481 else 11482 strcpy(alarms, "UNCONFIGURED"); 11483 } 11484 11485 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 11486 } 11487 close(ctl); 11488 11489 return RESULT_SUCCESS; 11490 #undef FORMAT 11491 #undef FORMAT2 11492 }
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 2875 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().
02876 { 02877 struct zt_pvt *p = ast->tech_pvt; 02878 int res = 0; 02879 int index; 02880 int oldstate = ast->_state; 02881 ast_setstate(ast, AST_STATE_UP); 02882 ast_mutex_lock(&p->lock); 02883 index = zt_get_index(ast, p, 0); 02884 if (index < 0) 02885 index = SUB_REAL; 02886 /* nothing to do if a radio channel */ 02887 if ((p->radio || (p->oprmode < 0))) { 02888 ast_mutex_unlock(&p->lock); 02889 return 0; 02890 } 02891 switch (p->sig) { 02892 case SIG_FXSLS: 02893 case SIG_FXSGS: 02894 case SIG_FXSKS: 02895 p->ringt = 0; 02896 /* Fall through */ 02897 case SIG_EM: 02898 case SIG_EM_E1: 02899 case SIG_EMWINK: 02900 case SIG_FEATD: 02901 case SIG_FEATDMF: 02902 case SIG_FEATDMF_TA: 02903 case SIG_E911: 02904 case SIG_FGC_CAMA: 02905 case SIG_FGC_CAMAMF: 02906 case SIG_FEATB: 02907 case SIG_SF: 02908 case SIG_SFWINK: 02909 case SIG_SF_FEATD: 02910 case SIG_SF_FEATDMF: 02911 case SIG_SF_FEATB: 02912 case SIG_FXOLS: 02913 case SIG_FXOGS: 02914 case SIG_FXOKS: 02915 /* Pick up the line */ 02916 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02917 if (p->hanguponpolarityswitch) { 02918 gettimeofday(&p->polaritydelaytv, NULL); 02919 } 02920 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02921 tone_zone_play_tone(p->subs[index].zfd, -1); 02922 p->dialing = 0; 02923 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02924 if (oldstate == AST_STATE_RINGING) { 02925 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02926 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02927 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02928 p->owner = p->subs[SUB_REAL].owner; 02929 } 02930 } 02931 if (p->sig & __ZT_SIG_FXS) { 02932 zt_enable_ec(p); 02933 zt_train_ec(p); 02934 } 02935 break; 02936 #ifdef HAVE_PRI 02937 case SIG_PRI: 02938 /* Send a pri acknowledge */ 02939 if (!pri_grab(p, p->pri)) { 02940 p->proceeding = 1; 02941 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02942 pri_rel(p->pri); 02943 /* stop ignoring inband dtmf */ 02944 enable_dtmf_detect(p); 02945 } else { 02946 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02947 res = -1; 02948 } 02949 /* the audio path is complete now, train the echo canceler */ 02950 zt_train_ec(p); 02951 break; 02952 #endif 02953 #ifdef HAVE_GSMAT 02954 case SIG_GSM: 02955 if (p->gsm.modul) { 02956 gsm_answer(p->gsm.modul); 02957 } 02958 break; 02959 #endif 02960 case 0: 02961 ast_mutex_unlock(&p->lock); 02962 return 0; 02963 default: 02964 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02965 res = -1; 02966 } 02967 ast_mutex_unlock(&p->lock); 02968 return res; 02969 }
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 3293 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(), f, ast_channel::fds, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, master, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().
03294 { 03295 struct ast_channel *who; 03296 struct zt_pvt *p0, *p1, *op0, *op1; 03297 struct zt_pvt *master = NULL, *slave = NULL; 03298 struct ast_frame *f; 03299 int inconf = 0; 03300 int nothingok = 1; 03301 int ofd0, ofd1; 03302 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03303 int os0 = -1, os1 = -1; 03304 int priority = 0; 03305 struct ast_channel *oc0, *oc1; 03306 enum ast_bridge_result res; 03307 03308 #ifdef PRI_2BCT 03309 int triedtopribridge = 0; 03310 q931_call *q931c0 = NULL, *q931c1 = NULL; 03311 #endif 03312 03313 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03314 There is code below to handle it properly until DTMF is actually seen, 03315 but due to currently unresolved issues it's ignored... 03316 */ 03317 03318 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03319 return AST_BRIDGE_FAILED_NOWARN; 03320 03321 ast_mutex_lock(&c0->lock); 03322 while (ast_mutex_trylock(&c1->lock)) { 03323 DEADLOCK_AVOIDANCE(&c0->lock); 03324 } 03325 03326 p0 = c0->tech_pvt; 03327 p1 = c1->tech_pvt; 03328 /* cant do pseudo-channels here */ 03329 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03330 ast_mutex_unlock(&c0->lock); 03331 ast_mutex_unlock(&c1->lock); 03332 return AST_BRIDGE_FAILED_NOWARN; 03333 } 03334 03335 oi0 = zt_get_index(c0, p0, 0); 03336 oi1 = zt_get_index(c1, p1, 0); 03337 if ((oi0 < 0) || (oi1 < 0)) { 03338 ast_mutex_unlock(&c0->lock); 03339 ast_mutex_unlock(&c1->lock); 03340 return AST_BRIDGE_FAILED; 03341 } 03342 03343 op0 = p0 = c0->tech_pvt; 03344 op1 = p1 = c1->tech_pvt; 03345 ofd0 = c0->fds[0]; 03346 ofd1 = c1->fds[0]; 03347 oc0 = p0->owner; 03348 oc1 = p1->owner; 03349 03350 if (ast_mutex_trylock(&p0->lock)) { 03351 /* Don't block, due to potential for deadlock */ 03352 ast_mutex_unlock(&c0->lock); 03353 ast_mutex_unlock(&c1->lock); 03354 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03355 return AST_BRIDGE_RETRY; 03356 } 03357 if (ast_mutex_trylock(&p1->lock)) { 03358 /* Don't block, due to potential for deadlock */ 03359 ast_mutex_unlock(&p0->lock); 03360 ast_mutex_unlock(&c0->lock); 03361 ast_mutex_unlock(&c1->lock); 03362 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03363 return AST_BRIDGE_RETRY; 03364 } 03365 03366 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03367 if (p0->owner && p1->owner) { 03368 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03369 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03370 master = p0; 03371 slave = p1; 03372 inconf = 1; 03373 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03374 master = p1; 03375 slave = p0; 03376 inconf = 1; 03377 } else { 03378 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03379 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03380 p0->channel, 03381 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03382 p0->subs[SUB_REAL].inthreeway, p0->channel, 03383 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03384 p1->subs[SUB_REAL].inthreeway); 03385 } 03386 nothingok = 0; 03387 } 03388 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03389 if (p1->subs[SUB_THREEWAY].inthreeway) { 03390 master = p1; 03391 slave = p0; 03392 nothingok = 0; 03393 } 03394 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03395 if (p0->subs[SUB_THREEWAY].inthreeway) { 03396 master = p0; 03397 slave = p1; 03398 nothingok = 0; 03399 } 03400 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03401 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03402 don't put us in anything */ 03403 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03404 master = p1; 03405 slave = p0; 03406 nothingok = 0; 03407 } 03408 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03409 /* Same as previous */ 03410 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03411 master = p0; 03412 slave = p1; 03413 nothingok = 0; 03414 } 03415 } 03416 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03417 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03418 if (master && slave) { 03419 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03420 in an active threeway call with a channel that is ringing, we should 03421 indicate ringing. */ 03422 if ((oi1 == SUB_THREEWAY) && 03423 p1->subs[SUB_THREEWAY].inthreeway && 03424 p1->subs[SUB_REAL].owner && 03425 p1->subs[SUB_REAL].inthreeway && 03426 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03427 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03428 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03429 os1 = p1->subs[SUB_REAL].owner->_state; 03430 } else { 03431 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03432 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03433 } 03434 if ((oi0 == SUB_THREEWAY) && 03435 p0->subs[SUB_THREEWAY].inthreeway && 03436 p0->subs[SUB_REAL].owner && 03437 p0->subs[SUB_REAL].inthreeway && 03438 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03439 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03440 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03441 os0 = p0->subs[SUB_REAL].owner->_state; 03442 } else { 03443 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03444 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03445 } 03446 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03447 if (!p0->echocanbridged || !p1->echocanbridged) { 03448 /* Disable echo cancellation if appropriate */ 03449 zt_disable_ec(p0); 03450 zt_disable_ec(p1); 03451 } 03452 } 03453 zt_link(slave, master); 03454 master->inconference = inconf; 03455 } else if (!nothingok) 03456 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03457 03458 update_conf(p0); 03459 update_conf(p1); 03460 t0 = p0->subs[SUB_REAL].inthreeway; 03461 t1 = p1->subs[SUB_REAL].inthreeway; 03462 03463 ast_mutex_unlock(&p0->lock); 03464 ast_mutex_unlock(&p1->lock); 03465 03466 ast_mutex_unlock(&c0->lock); 03467 ast_mutex_unlock(&c1->lock); 03468 03469 /* Native bridge failed */ 03470 if ((!master || !slave) && !nothingok) { 03471 zt_enable_ec(p0); 03472 zt_enable_ec(p1); 03473 return AST_BRIDGE_FAILED; 03474 } 03475 03476 if (option_verbose > 2) 03477 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03478 03479 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03480 disable_dtmf_detect(op0); 03481 03482 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03483 disable_dtmf_detect(op1); 03484 03485 for (;;) { 03486 struct ast_channel *c0_priority[2] = {c0, c1}; 03487 struct ast_channel *c1_priority[2] = {c1, c0}; 03488 03489 /* Here's our main loop... Start by locking things, looking for private parts, 03490 and then balking if anything is wrong */ 03491 ast_mutex_lock(&c0->lock); 03492 while (ast_mutex_trylock(&c1->lock)) { 03493 DEADLOCK_AVOIDANCE(&c0->lock); 03494 } 03495 03496 p0 = c0->tech_pvt; 03497 p1 = c1->tech_pvt; 03498 03499 if (op0 == p0) 03500 i0 = zt_get_index(c0, p0, 1); 03501 if (op1 == p1) 03502 i1 = zt_get_index(c1, p1, 1); 03503 ast_mutex_unlock(&c0->lock); 03504 ast_mutex_unlock(&c1->lock); 03505 03506 if (!timeoutms || 03507 (op0 != p0) || 03508 (op1 != p1) || 03509 (ofd0 != c0->fds[0]) || 03510 (ofd1 != c1->fds[0]) || 03511 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03512 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03513 (oc0 != p0->owner) || 03514 (oc1 != p1->owner) || 03515 (t0 != p0->subs[SUB_REAL].inthreeway) || 03516 (t1 != p1->subs[SUB_REAL].inthreeway) || 03517 (oi0 != i0) || 03518 (oi1 != i1)) { 03519 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03520 op0->channel, oi0, op1->channel, oi1); 03521 res = AST_BRIDGE_RETRY; 03522 goto return_from_bridge; 03523 } 03524 03525 #ifdef PRI_2BCT 03526 q931c0 = p0->call; 03527 q931c1 = p1->call; 03528 if (p0->transfer && p1->transfer 03529 && q931c0 && q931c1 03530 && !triedtopribridge) { 03531 pri_channel_bridge(q931c0, q931c1); 03532 triedtopribridge = 1; 03533 } 03534 #endif 03535 03536 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03537 if (!who) { 03538 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03539 continue; 03540 } 03541 f = ast_read(who); 03542 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03543 *fo = f; 03544 *rc = who; 03545 res = AST_BRIDGE_COMPLETE; 03546 goto return_from_bridge; 03547 } 03548 if (f->frametype == AST_FRAME_DTMF) { 03549 if ((who == c0) && p0->pulsedial) { 03550 ast_write(c1, f); 03551 } else if ((who == c1) && p1->pulsedial) { 03552 ast_write(c0, f); 03553 } else { 03554 *fo = f; 03555 *rc = who; 03556 res = AST_BRIDGE_COMPLETE; 03557 goto return_from_bridge; 03558 } 03559 } 03560 ast_frfree(f); 03561 03562 /* Swap who gets priority */ 03563 priority = !priority; 03564 } 03565 03566 return_from_bridge: 03567 if (op0 == p0) 03568 zt_enable_ec(p0); 03569 03570 if (op1 == p1) 03571 zt_enable_ec(p1); 03572 03573 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03574 enable_dtmf_detect(op0); 03575 03576 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03577 enable_dtmf_detect(op1); 03578 03579 zt_unlink(slave, master, 1); 03580 03581 return res; 03582 }
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] |
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(), 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] |
Definition at line 4776 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), f, zt_pvt::lock, and ast_channel::tech_pvt.
04777 { 04778 struct zt_pvt *p = ast->tech_pvt; 04779 struct ast_frame *f; 04780 ast_mutex_lock(&p->lock); 04781 f = __zt_exception(ast); 04782 ast_mutex_unlock(&p->lock); 04783 return f; 04784 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3584 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, LOG_ERROR, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, and zt_unlink().
03585 { 03586 struct zt_pvt *p = newchan->tech_pvt; 03587 int x; 03588 if (newchan && newchan->tech_pvt) { 03589 p = newchan->tech_pvt; 03590 } 03591 if (!p) { 03592 if (newchan) { 03593 ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name); 03594 } 03595 return 0; 03596 } 03597 ast_mutex_lock(&p->lock); 03598 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03599 if (p->owner == oldchan) { 03600 p->owner = newchan; 03601 } 03602 for (x = 0; x < 3; x++) 03603 if (p->subs[x].owner == oldchan) { 03604 if (!x) 03605 zt_unlink(NULL, p, 0); 03606 p->subs[x].owner = newchan; 03607 } 03608 if (newchan->_state == AST_STATE_RINGING) 03609 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03610 update_conf(p); 03611 ast_mutex_unlock(&p->lock); 03612 return 0; 03613 }
static int zt_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3156 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.
03157 { 03158 struct zt_pvt *p = chan->tech_pvt; 03159 03160 if (!strcasecmp(data, "rxgain")) { 03161 ast_mutex_lock(&p->lock); 03162 snprintf(buf, len, "%f", p->rxgain); 03163 ast_mutex_unlock(&p->lock); 03164 } else if (!strcasecmp(data, "txgain")) { 03165 ast_mutex_lock(&p->lock); 03166 snprintf(buf, len, "%f", p->txgain); 03167 ast_mutex_unlock(&p->lock); 03168 } else { 03169 ast_copy_string(buf, "", len); 03170 } 03171 return 0; 03172 }
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(), 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 3761 of file chan_zap.c.
References ast_async_goto(), AST_CONTROL_ANSWER, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), ast_verbose(), zt_pvt::callprogress, zt_pvt::callwaitcas, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_channel::exten, zt_subchannel::f, f, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, ast_channel::macrocontext, option_debug, option_verbose, pbx_builtin_setvar_helper(), S_OR, send_cwcidspill(), ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, VERBOSE_PREFIX_3, and zt_confmute().
Referenced by zt_handle_event(), and zt_read().
03762 { 03763 struct zt_pvt *p = ast->tech_pvt; 03764 struct ast_frame *f = *dest; 03765 03766 if (option_debug) 03767 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03768 03769 if (p->confirmanswer) { 03770 if (option_debug) 03771 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03772 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03773 of a DTMF digit */ 03774 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03775 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03776 *dest = &p->subs[index].f; 03777 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03778 p->confirmanswer = 0; 03779 } else if (p->callwaitcas) { 03780 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03781 if (option_debug) 03782 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03783 if (p->cidspill) 03784 free(p->cidspill); 03785 send_cwcidspill(p); 03786 } 03787 if ((f->subclass != 'm') && (f->subclass != 'u')) 03788 p->callwaitcas = 0; 03789 p->subs[index].f.frametype = AST_FRAME_NULL; 03790 p->subs[index].f.subclass = 0; 03791 *dest = &p->subs[index].f; 03792 } else if (f->subclass == 'f') { 03793 /* Fax tone -- Handle and return NULL */ 03794 if ((p->callprogress & 0x6) && !p->faxhandled) { 03795 p->faxhandled++; 03796 if (strcmp(ast->exten, "fax")) { 03797 const char *target_context = S_OR(ast->macrocontext, ast->context); 03798 03799 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03800 if (option_verbose > 2) 03801 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03802 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03803 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03804 if (ast_async_goto(ast, target_context, "fax", 1)) 03805 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03806 } else { 03807 if (option_verbose > 2) 03808 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03809 } 03810 } else if (option_debug) 03811 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03812 } else if (option_debug) 03813 ast_log(LOG_DEBUG, "Fax already handled\n"); 03814 zt_confmute(p, 0); 03815 p->subs[index].f.frametype = AST_FRAME_NULL; 03816 p->subs[index].f.subclass = 0; 03817 *dest = &p->subs[index].f; 03818 } else if (f->subclass == 'm') { 03819 /* Confmute request */ 03820 zt_confmute(p, 1); 03821 p->subs[index].f.frametype = AST_FRAME_NULL; 03822 p->subs[index].f.subclass = 0; 03823 *dest = &p->subs[index].f; 03824 } else if (f->subclass == 'u') { 03825 /* Unmute */ 03826 zt_confmute(p, 0); 03827 p->subs[index].f.frametype = AST_FRAME_NULL; 03828 p->subs[index].f.subclass = 0; 03829 *dest = &p->subs[index].f; 03830 } else 03831 zt_confmute(p, 0); 03832 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3834 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callwaitcas, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, cid_num, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, DEADLOCK_AVOIDANCE, zt_pvt::dialdest, zt_pvt::dialing, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echocanon, zt_pvt::echorest, zt_pvt::echotraining, errno, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::onhooktime, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::overlapdial, zt_subchannel::owner, zt_pvt::owner, ast_channel::pbx, zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, zt_pvt::polaritydelaytv, zt_pvt::polarityonanswerdelay, zt_pvt::pulsedial, zt_pvt::radio, restore_conference(), ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, S_OR, ast_frame::samples, save_conference(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::threewaycalling, zt_pvt::transfer, zt_pvt::transfertobusy, unalloc_sub(), zt_pvt::unknown_alarm, update_conf(), VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_enable_ec(), ZT_EVENT_DTMFDOWN, ZT_EVENT_DTMFUP, zt_get_event(), zt_get_index(), zt_handle_dtmfup(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().
Referenced by __zt_exception().
03835 { 03836 int res, x; 03837 int index, mysig; 03838 char *c; 03839 struct zt_pvt *p = ast->tech_pvt; 03840 pthread_t threadid; 03841 pthread_attr_t attr; 03842 struct ast_channel *chan; 03843 struct ast_frame *f; 03844 03845 index = zt_get_index(ast, p, 0); 03846 mysig = p->sig; 03847 if (p->outsigmod > -1) 03848 mysig = p->outsigmod; 03849 p->subs[index].f.frametype = AST_FRAME_NULL; 03850 p->subs[index].f.subclass = 0; 03851 p->subs[index].f.datalen = 0; 03852 p->subs[index].f.samples = 0; 03853 p->subs[index].f.mallocd = 0; 03854 p->subs[index].f.offset = 0; 03855 p->subs[index].f.src = "zt_handle_event"; 03856 p->subs[index].f.data = NULL; 03857 f = &p->subs[index].f; 03858 03859 if (index < 0) 03860 return &p->subs[index].f; 03861 if (p->fake_event) { 03862 res = p->fake_event; 03863 p->fake_event = 0; 03864 } else 03865 res = zt_get_event(p->subs[index].zfd); 03866 03867 if (option_debug) 03868 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03869 03870 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03871 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 03872 03873 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03874 #ifdef HAVE_PRI 03875 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03876 /* absorb event */ 03877 } else { 03878 #endif 03879 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 03880 p->subs[index].f.subclass = res & 0xff; 03881 #ifdef HAVE_PRI 03882 } 03883 #endif 03884 zt_handle_dtmfup(ast, index, &f); 03885 return f; 03886 } 03887 03888 if (res & ZT_EVENT_DTMFDOWN) { 03889 if (option_debug) 03890 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03891 /* Mute conference */ 03892 zt_confmute(p, 1); 03893 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 03894 p->subs[index].f.subclass = res & 0xff; 03895 return &p->subs[index].f; 03896 } 03897 03898 switch (res) { 03899 #ifdef ZT_EVENT_EC_DISABLED 03900 case ZT_EVENT_EC_DISABLED: 03901 if (option_verbose > 2) 03902 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 03903 p->echocanon = 0; 03904 break; 03905 #endif 03906 case ZT_EVENT_BITSCHANGED: 03907 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03908 case ZT_EVENT_PULSE_START: 03909 /* Stop tone if there's a pulse start and the PBX isn't started */ 03910 if (!ast->pbx) 03911 tone_zone_play_tone(p->subs[index].zfd, -1); 03912 break; 03913 case ZT_EVENT_DIALCOMPLETE: 03914 if (p->inalarm) break; 03915 if ((p->radio || (p->oprmode < 0))) break; 03916 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03917 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03918 return NULL; 03919 } 03920 if (!x) { /* if not still dialing in driver */ 03921 zt_enable_ec(p); 03922 if (p->echobreak) { 03923 zt_train_ec(p); 03924 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03925 p->dop.op = ZT_DIAL_OP_REPLACE; 03926 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03927 p->echobreak = 0; 03928 } else { 03929 p->dialing = 0; 03930 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 03931 /* if thru with dialing after offhook */ 03932 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03933 ast_setstate(ast, AST_STATE_UP); 03934 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03935 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03936 break; 03937 } else { /* if to state wait for offhook to dial rest */ 03938 /* we now wait for off hook */ 03939 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03940 } 03941 } 03942 if (ast->_state == AST_STATE_DIALING) { 03943 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03944 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03945 } 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)))) { 03946 ast_setstate(ast, AST_STATE_RINGING); 03947 } else if (!p->answeronpolarityswitch) { 03948 ast_setstate(ast, AST_STATE_UP); 03949 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03950 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03951 /* If aops=0 and hops=1, this is necessary */ 03952 p->polarity = POLARITY_REV; 03953 } else { 03954 /* Start clean, so we can catch the change to REV polarity when party answers */ 03955 p->polarity = POLARITY_IDLE; 03956 } 03957 } 03958 } 03959 } 03960 break; 03961 case ZT_EVENT_ALARM: 03962 #ifdef HAVE_PRI 03963 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 03964 /* T309 is not enabled : hangup calls when alarm occurs */ 03965 if (p->call) { 03966 if (p->pri && p->pri->pri) { 03967 if (!pri_grab(p, p->pri)) { 03968 pri_hangup(p->pri->pri, p->call, -1, -1); 03969 pri_destroycall(p->pri->pri, p->call); 03970 p->call = NULL; 03971 pri_rel(p->pri); 03972 } else 03973 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03974 } else 03975 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 03976 } 03977 if (p->owner) 03978 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03979 } 03980 if (p->bearer) 03981 p->bearer->inalarm = 1; 03982 else 03983 #endif 03984 p->inalarm = 1; 03985 res = get_alarms(p); 03986 do { 03987 const char *alarm_str = alarm2str(res); 03988 03989 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 03990 * doesn't know what to do with it. Don't confuse users with log messages. */ 03991 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 03992 p->unknown_alarm = 1; 03993 break; 03994 } else { 03995 p->unknown_alarm = 0; 03996 } 03997 03998 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 03999 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 04000 "Alarm: %s\r\n" 04001 "Channel: %d\r\n", 04002 alarm_str, p->channel); 04003 } while (0); 04004 #ifdef HAVE_LIBPRI 04005 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 04006 /* fall through intentionally */ 04007 } else { 04008 break; 04009 } 04010 #endif 04011 case ZT_EVENT_ONHOOK: 04012 if (p->radio) { 04013 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04014 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04015 break; 04016 } 04017 if (p->oprmode < 0) 04018 { 04019 if (p->oprmode != -1) break; 04020 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04021 { 04022 /* Make sure it starts ringing */ 04023 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04024 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 04025 save_conference(p->oprpeer); 04026 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04027 } 04028 break; 04029 } 04030 switch (p->sig) { 04031 case SIG_FXOLS: 04032 case SIG_FXOGS: 04033 case SIG_FXOKS: 04034 p->onhooktime = time(NULL); 04035 p->msgstate = -1; 04036 /* Check for some special conditions regarding call waiting */ 04037 if (index == SUB_REAL) { 04038 /* The normal line was hung up */ 04039 if (p->subs[SUB_CALLWAIT].owner) { 04040 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 04041 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 04042 if (option_verbose > 2) 04043 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 04044 unalloc_sub(p, SUB_CALLWAIT); 04045 #if 0 04046 p->subs[index].needanswer = 0; 04047 p->subs[index].needringing = 0; 04048 #endif 04049 p->callwaitingrepeat = 0; 04050 p->cidcwexpire = 0; 04051 p->owner = NULL; 04052 /* Don't start streaming audio yet if the incoming call isn't up yet */ 04053 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 04054 p->dialing = 1; 04055 zt_ring_phone(p); 04056 } else if (p->subs[SUB_THREEWAY].owner) { 04057 unsigned int mssinceflash; 04058 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 04059 the private structure -- not especially easy or clean */ 04060 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 04061 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 04062 ast_mutex_unlock(&p->lock); 04063 DEADLOCK_AVOIDANCE(&ast->lock); 04064 /* We can grab ast and p in that order, without worry. We should make sure 04065 nothing seriously bad has happened though like some sort of bizarre double 04066 masquerade! */ 04067 ast_mutex_lock(&p->lock); 04068 if (p->owner != ast) { 04069 ast_log(LOG_WARNING, "This isn't good...\n"); 04070 return NULL; 04071 } 04072 } 04073 if (!p->subs[SUB_THREEWAY].owner) { 04074 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 04075 return NULL; 04076 } 04077 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 04078 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 04079 if (mssinceflash < MIN_MS_SINCE_FLASH) { 04080 /* It hasn't been long enough since the last flashook. This is probably a bounce on 04081 hanging up. Hangup both channels now */ 04082 if (p->subs[SUB_THREEWAY].owner) 04083 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 04084 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04085 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 04086 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04087 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 04088 if (p->transfer) { 04089 /* In any case this isn't a threeway call anymore */ 04090 p->subs[SUB_REAL].inthreeway = 0; 04091 p->subs[SUB_THREEWAY].inthreeway = 0; 04092 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 04093 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 04094 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04095 /* Swap subs and dis-own channel */ 04096 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04097 p->owner = NULL; 04098 /* Ring the phone */ 04099 zt_ring_phone(p); 04100 } else { 04101 if ((res = attempt_transfer(p)) < 0) { 04102 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04103 if (p->subs[SUB_THREEWAY].owner) 04104 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04105 } else if (res) { 04106 /* Don't actually hang up at this point */ 04107 if (p->subs[SUB_THREEWAY].owner) 04108 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04109 break; 04110 } 04111 } 04112 } else { 04113 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04114 if (p->subs[SUB_THREEWAY].owner) 04115 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04116 } 04117 } else { 04118 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04119 /* Swap subs and dis-own channel */ 04120 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04121 p->owner = NULL; 04122 /* Ring the phone */ 04123 zt_ring_phone(p); 04124 } 04125 } 04126 } else { 04127 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 04128 } 04129 /* Fall through */ 04130 default: 04131 zt_disable_ec(p); 04132 return NULL; 04133 } 04134 break; 04135 case ZT_EVENT_RINGOFFHOOK: 04136 if (p->inalarm) break; 04137 if (p->oprmode < 0) 04138 { 04139 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04140 { 04141 /* Make sure it stops ringing */ 04142 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04143 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 04144 restore_conference(p->oprpeer); 04145 } 04146 break; 04147 } 04148 if (p->radio) 04149 { 04150 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04151 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04152 break; 04153 } 04154 /* for E911, its supposed to wait for offhook then dial 04155 the second half of the dial string */ 04156 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 04157 c = strchr(p->dialdest, '/'); 04158 if (c) 04159 c++; 04160 else 04161 c = p->dialdest; 04162 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 04163 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 04164 if (strlen(p->dop.dialstr) > 4) { 04165 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 04166 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 04167 p->echorest[sizeof(p->echorest) - 1] = '\0'; 04168 p->echobreak = 1; 04169 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 04170 } else 04171 p->echobreak = 0; 04172 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 04173 x = ZT_ONHOOK; 04174 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 04175 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 04176 return NULL; 04177 } 04178 p->dialing = 1; 04179 return &p->subs[index].f; 04180 } 04181 switch (p->sig) { 04182 case SIG_FXOLS: 04183 case SIG_FXOGS: 04184 case SIG_FXOKS: 04185 switch (ast->_state) { 04186 case AST_STATE_RINGING: 04187 zt_enable_ec(p); 04188 zt_train_ec(p); 04189 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04190 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04191 /* Make sure it stops ringing */ 04192 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04193 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 04194 if (p->cidspill) { 04195 /* Cancel any running CallerID spill */ 04196 free(p->cidspill); 04197 p->cidspill = NULL; 04198 } 04199 p->dialing = 0; 04200 p->callwaitcas = 0; 04201 if (p->confirmanswer) { 04202 /* Ignore answer if "confirm answer" is enabled */ 04203 p->subs[index].f.frametype = AST_FRAME_NULL; 04204 p->subs[index].f.subclass = 0; 04205 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04206 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04207 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04208 if (res < 0) { 04209 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04210 p->dop.dialstr[0] = '\0'; 04211 return NULL; 04212 } else { 04213 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04214 p->subs[index].f.frametype = AST_FRAME_NULL; 04215 p->subs[index].f.subclass = 0; 04216 p->dialing = 1; 04217 } 04218 p->dop.dialstr[0] = '\0'; 04219 ast_setstate(ast, AST_STATE_DIALING); 04220 } else 04221 ast_setstate(ast, AST_STATE_UP); 04222 return &p->subs[index].f; 04223 case AST_STATE_DOWN: 04224 ast_setstate(ast, AST_STATE_RING); 04225 ast->rings = 1; 04226 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04227 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04228 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04229 return &p->subs[index].f; 04230 case AST_STATE_UP: 04231 /* Make sure it stops ringing */ 04232 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04233 /* Okay -- probably call waiting*/ 04234 if (ast_bridged_channel(p->owner)) 04235 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04236 p->subs[index].needunhold = 1; 04237 break; 04238 case AST_STATE_RESERVED: 04239 /* Start up dialtone */ 04240 if (has_voicemail(p)) 04241 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04242 else 04243 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04244 break; 04245 default: 04246 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04247 } 04248 break; 04249 case SIG_FXSLS: 04250 case SIG_FXSGS: 04251 case SIG_FXSKS: 04252 if (ast->_state == AST_STATE_RING) { 04253 p->ringt = p->ringt_base; 04254 } 04255 04256 /* Fall through */ 04257 case SIG_EM: 04258 case SIG_EM_E1: 04259 case SIG_EMWINK: 04260 case SIG_FEATD: 04261 case SIG_FEATDMF: 04262 case SIG_FEATDMF_TA: 04263 case SIG_E911: 04264 case SIG_FGC_CAMA: 04265 case SIG_FGC_CAMAMF: 04266 case SIG_FEATB: 04267 case SIG_SF: 04268 case SIG_SFWINK: 04269 case SIG_SF_FEATD: 04270 case SIG_SF_FEATDMF: 04271 case SIG_SF_FEATB: 04272 if (ast->_state == AST_STATE_PRERING) 04273 ast_setstate(ast, AST_STATE_RING); 04274 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04275 if (option_debug) 04276 ast_log(LOG_DEBUG, "Ring detected\n"); 04277 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04278 p->subs[index].f.subclass = AST_CONTROL_RING; 04279 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04280 if (option_debug) 04281 ast_log(LOG_DEBUG, "Line answered\n"); 04282 if (p->confirmanswer) { 04283 p->subs[index].f.frametype = AST_FRAME_NULL; 04284 p->subs[index].f.subclass = 0; 04285 } else { 04286 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04287 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04288 ast_setstate(ast, AST_STATE_UP); 04289 } 04290 } else if (ast->_state != AST_STATE_RING) 04291 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04292 break; 04293 default: 04294 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04295 } 04296 break; 04297 #ifdef ZT_EVENT_RINGBEGIN 04298 case ZT_EVENT_RINGBEGIN: 04299 switch (p->sig) { 04300 case SIG_FXSLS: 04301 case SIG_FXSGS: 04302 case SIG_FXSKS: 04303 if (ast->_state == AST_STATE_RING) { 04304 p->ringt = p->ringt_base; 04305 } 04306 break; 04307 } 04308 break; 04309 #endif 04310 case ZT_EVENT_RINGEROFF: 04311 if (p->inalarm) break; 04312 if ((p->radio || (p->oprmode < 0))) break; 04313 ast->rings++; 04314 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04315 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04316 free(p->cidspill); 04317 p->cidspill = NULL; 04318 p->callwaitcas = 0; 04319 } 04320 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04321 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04322 break; 04323 case ZT_EVENT_RINGERON: 04324 break; 04325 case ZT_EVENT_NOALARM: 04326 p->inalarm = 0; 04327 #ifdef HAVE_PRI 04328 /* Extremely unlikely but just in case */ 04329 if (p->bearer) 04330 p->bearer->inalarm = 0; 04331 #endif 04332 if (!p->unknown_alarm) { 04333 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04334 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04335 "Channel: %d\r\n", p->channel); 04336 } else { 04337 p->unknown_alarm = 0; 04338 } 04339 break; 04340 case ZT_EVENT_WINKFLASH: 04341 if (p->inalarm) break; 04342 if (p->radio) break; 04343 if (p->oprmode < 0) break; 04344 if (p->oprmode > 1) 04345 { 04346 struct zt_params par; 04347 04348 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04349 { 04350 if (!par.rxisoffhook) 04351 { 04352 /* Make sure it stops ringing */ 04353 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04354 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04355 save_conference(p); 04356 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04357 } 04358 } 04359 break; 04360 } 04361 /* Remember last time we got a flash-hook */ 04362 gettimeofday(&p->flashtime, NULL); 04363 switch (mysig) { 04364 case SIG_FXOLS: 04365 case SIG_FXOGS: 04366 case SIG_FXOKS: 04367 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04368 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04369 p->callwaitcas = 0; 04370 04371 if (index != SUB_REAL) { 04372 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04373 goto winkflashdone; 04374 } 04375 04376 if (p->subs[SUB_CALLWAIT].owner) { 04377 /* Swap to call-wait */ 04378 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04379 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04380 p->owner = p->subs[SUB_REAL].owner; 04381 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04382 if (p->owner->_state == AST_STATE_RINGING) { 04383 ast_setstate(p->owner, AST_STATE_UP); 04384 p->subs[SUB_REAL].needanswer = 1; 04385 } 04386 p->callwaitingrepeat = 0; 04387 p->cidcwexpire = 0; 04388 /* Start music on hold if appropriate */ 04389 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04390 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04391 S_OR(p->mohsuggest, NULL), 04392 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04393 } 04394 p->subs[SUB_CALLWAIT].needhold = 1; 04395 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04396 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04397 S_OR(p->mohsuggest, NULL), 04398 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04399 } 04400 p->subs[SUB_REAL].needunhold = 1; 04401 } else if (!p->subs[SUB_THREEWAY].owner) { 04402 char cid_num[256]; 04403 char cid_name[256]; 04404 04405 if (!p->threewaycalling) { 04406 /* Just send a flash if no 3-way calling */ 04407 p->subs[SUB_REAL].needflash = 1; 04408 goto winkflashdone; 04409 } else if (!check_for_conference(p)) { 04410 if (p->zaptrcallerid && p->owner) { 04411 if (p->owner->cid.cid_num) 04412 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04413 if (p->owner->cid.cid_name) 04414 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04415 } 04416 /* XXX This section needs much more error checking!!! XXX */ 04417 /* Start a 3-way call if feasible */ 04418 if (!((ast->pbx) || 04419 (ast->_state == AST_STATE_UP) || 04420 (ast->_state == AST_STATE_RING))) { 04421 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04422 goto winkflashdone; 04423 } 04424 if (alloc_sub(p, SUB_THREEWAY)) { 04425 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04426 goto winkflashdone; 04427 } 04428 /* Make new channel */ 04429 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04430 if (p->zaptrcallerid) { 04431 if (!p->origcid_num) 04432 p->origcid_num = ast_strdup(p->cid_num); 04433 if (!p->origcid_name) 04434 p->origcid_name = ast_strdup(p->cid_name); 04435 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04436 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04437 } 04438 /* Swap things around between the three-way and real call */ 04439 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04440 /* Disable echo canceller for better dialing */ 04441 zt_disable_ec(p); 04442 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04443 if (res) 04444 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04445 p->owner = chan; 04446 pthread_attr_init(&attr); 04447 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04448 if (!chan) { 04449 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04450 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04451 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04452 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04453 zt_enable_ec(p); 04454 ast_hangup(chan); 04455 } else { 04456 if (option_verbose > 2) 04457 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04458 /* Start music on hold if appropriate */ 04459 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04460 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04461 S_OR(p->mohsuggest, NULL), 04462 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04463 } 04464 p->subs[SUB_THREEWAY].needhold = 1; 04465 } 04466 pthread_attr_destroy(&attr); 04467 } 04468 } else { 04469 /* Already have a 3 way call */ 04470 if (p->subs[SUB_THREEWAY].inthreeway) { 04471 /* Call is already up, drop the last person */ 04472 if (option_debug) 04473 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04474 /* If the primary call isn't answered yet, use it */ 04475 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04476 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04477 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04478 p->owner = p->subs[SUB_REAL].owner; 04479 } 04480 /* Drop the last call and stop the conference */ 04481 if (option_verbose > 2) 04482 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04483 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04484 p->subs[SUB_REAL].inthreeway = 0; 04485 p->subs[SUB_THREEWAY].inthreeway = 0; 04486 } else { 04487 /* Lets see what we're up to */ 04488 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04489 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04490 int otherindex = SUB_THREEWAY; 04491 04492 if (option_verbose > 2) 04493 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); 04494 /* Put them in the threeway, and flip */ 04495 p->subs[SUB_THREEWAY].inthreeway = 1; 04496 p->subs[SUB_REAL].inthreeway = 1; 04497 if (ast->_state == AST_STATE_UP) { 04498 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04499 otherindex = SUB_REAL; 04500 } 04501 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04502 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04503 p->subs[otherindex].needunhold = 1; 04504 p->owner = p->subs[SUB_REAL].owner; 04505 if (ast->_state == AST_STATE_RINGING) { 04506 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04507 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04508 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04509 } 04510 } else { 04511 if (option_verbose > 2) 04512 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04513 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04514 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04515 p->owner = p->subs[SUB_REAL].owner; 04516 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04517 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04518 p->subs[SUB_REAL].needunhold = 1; 04519 zt_enable_ec(p); 04520 } 04521 04522 } 04523 } 04524 winkflashdone: 04525 update_conf(p); 04526 break; 04527 case SIG_EM: 04528 case SIG_EM_E1: 04529 case SIG_EMWINK: 04530 case SIG_FEATD: 04531 case SIG_SF: 04532 case SIG_SFWINK: 04533 case SIG_SF_FEATD: 04534 case SIG_FXSLS: 04535 case SIG_FXSGS: 04536 if (p->dialing) 04537 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04538 else 04539 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04540 break; 04541 case SIG_FEATDMF_TA: 04542 switch (p->whichwink) { 04543 case 0: 04544 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04545 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04546 break; 04547 case 1: 04548 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04549 break; 04550 case 2: 04551 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04552 return NULL; 04553 } 04554 p->whichwink++; 04555 /* Fall through */ 04556 case SIG_FEATDMF: 04557 case SIG_E911: 04558 case SIG_FGC_CAMAMF: 04559 case SIG_FGC_CAMA: 04560 case SIG_FEATB: 04561 case SIG_SF_FEATDMF: 04562 case SIG_SF_FEATB: 04563 /* FGD MF *Must* wait for wink */ 04564 if (!ast_strlen_zero(p->dop.dialstr)) { 04565 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04566 if (res < 0) { 04567 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04568 p->dop.dialstr[0] = '\0'; 04569 return NULL; 04570 } else 04571 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04572 } 04573 p->dop.dialstr[0] = '\0'; 04574 break; 04575 default: 04576 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04577 } 04578 break; 04579 case ZT_EVENT_HOOKCOMPLETE: 04580 if (p->inalarm) break; 04581 if ((p->radio || (p->oprmode < 0))) break; 04582 switch (mysig) { 04583 case SIG_FXSLS: /* only interesting for FXS */ 04584 case SIG_FXSGS: 04585 case SIG_FXSKS: 04586 case SIG_EM: 04587 case SIG_EM_E1: 04588 case SIG_EMWINK: 04589 case SIG_FEATD: 04590 case SIG_SF: 04591 case SIG_SFWINK: 04592 case SIG_SF_FEATD: 04593 if (!ast_strlen_zero(p->dop.dialstr)) { 04594 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04595 if (res < 0) { 04596 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04597 p->dop.dialstr[0] = '\0'; 04598 return NULL; 04599 } else 04600 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04601 } 04602 p->dop.dialstr[0] = '\0'; 04603 p->dop.op = ZT_DIAL_OP_REPLACE; 04604 break; 04605 case SIG_FEATDMF: 04606 case SIG_FEATDMF_TA: 04607 case SIG_E911: 04608 case SIG_FGC_CAMA: 04609 case SIG_FGC_CAMAMF: 04610 case SIG_FEATB: 04611 case SIG_SF_FEATDMF: 04612 case SIG_SF_FEATB: 04613 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04614 break; 04615 default: 04616 break; 04617 } 04618 break; 04619 case ZT_EVENT_POLARITY: 04620 /* 04621 * If we get a Polarity Switch event, check to see 04622 * if we should change the polarity state and 04623 * mark the channel as UP or if this is an indication 04624 * of remote end disconnect. 04625 */ 04626 if (p->polarity == POLARITY_IDLE) { 04627 p->polarity = POLARITY_REV; 04628 if (p->answeronpolarityswitch && 04629 ((ast->_state == AST_STATE_DIALING) || 04630 (ast->_state == AST_STATE_RINGING))) { 04631 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04632 ast_setstate(p->owner, AST_STATE_UP); 04633 if (p->hanguponpolarityswitch) { 04634 gettimeofday(&p->polaritydelaytv, NULL); 04635 } 04636 } else 04637 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04638 } 04639 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04640 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04641 if (p->hanguponpolarityswitch && 04642 (p->polarityonanswerdelay > 0) && 04643 (p->polarity == POLARITY_REV) && 04644 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04645 /* Added log_debug information below to provide a better indication of what is going on */ 04646 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) ); 04647 04648 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04649 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04650 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04651 p->polarity = POLARITY_IDLE; 04652 } else { 04653 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); 04654 } 04655 } else { 04656 p->polarity = POLARITY_IDLE; 04657 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04658 } 04659 /* Added more log_debug information below to provide a better indication of what is going on */ 04660 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) ); 04661 break; 04662 default: 04663 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04664 } 04665 return &p->subs[index].f; 04666 }
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 p->call = NULL; 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 } 02744 02745 if (p->pri->nodetype == BRI_NETWORK_PTMP) { 02746 if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) { 02747 if (outgoing) { 02748 p->call = NULL; 02749 } 02750 } 02751 } 02752 02753 02754 } 02755 if (res < 0) 02756 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02757 pri_rel(p->pri); 02758 } else { 02759 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02760 res = -1; 02761 } 02762 } else { 02763 if (p->bearer) 02764 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02765 p->call = NULL; 02766 res = 0; 02767 } 02768 } 02769 #endif 02770 #ifdef HAVE_GSMAT 02771 if (p->gsm.modul) { 02772 if (!p->alreadyhungup) 02773 gsm_hangup(p->gsm.modul); 02774 } 02775 #endif 02776 if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM)) 02777 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02778 if (res < 0) { 02779 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02780 } 02781 switch (p->sig) { 02782 case SIG_FXOGS: 02783 case SIG_FXOLS: 02784 case SIG_FXOKS: 02785 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02786 if (!res) { 02787 #if 0 02788 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02789 #endif 02790 /* If they're off hook, try playing congestion */ 02791 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02792 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02793 else 02794 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02795 } 02796 break; 02797 case SIG_FXSGS: 02798 case SIG_FXSLS: 02799 case SIG_FXSKS: 02800 /* Make sure we're not made available for at least two seconds assuming 02801 we were actually used for an inbound or outbound call. */ 02802 if (ast->_state != AST_STATE_RESERVED) { 02803 time(&p->guardtime); 02804 p->guardtime += 2; 02805 } 02806 break; 02807 default: 02808 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02809 } 02810 if (p->cidspill) 02811 free(p->cidspill); 02812 if (p->sig) 02813 zt_disable_ec(p); 02814 x = 0; 02815 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02816 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02817 p->didtdd = 0; 02818 p->cidspill = NULL; 02819 p->callwaitcas = 0; 02820 p->callwaiting = p->permcallwaiting; 02821 p->hidecallerid = p->permhidecallerid; 02822 p->dialing = 0; 02823 p->rdnis[0] = '\0'; 02824 update_conf(p); 02825 reset_conf(p); 02826 /* Restore data mode */ 02827 if (p->sig == SIG_PRI) { 02828 x = 0; 02829 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02830 } 02831 #ifdef HAVE_PRI 02832 if (p->bearer) { 02833 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02834 /* Free up the bearer channel as well, and 02835 don't use its file descriptor anymore */ 02836 update_conf(p->bearer); 02837 reset_conf(p->bearer); 02838 p->bearer->owner = NULL; 02839 p->bearer->realcall = NULL; 02840 p->bearer = NULL; 02841 p->subs[SUB_REAL].zfd = -1; 02842 p->pri = NULL; 02843 } 02844 #endif 02845 restart_monitor(); 02846 } 02847 02848 p->callwaitingrepeat = 0; 02849 p->cidcwexpire = 0; 02850 p->oprmode = 0; 02851 ast->tech_pvt = NULL; 02852 ast_mutex_unlock(&p->lock); 02853 ast_module_unref(ast_module_info->self); 02854 if (option_verbose > 2) 02855 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02856 02857 ast_mutex_lock(&iflock); 02858 tmp = iflist; 02859 prev = NULL; 02860 if (p->destroy) { 02861 while (tmp) { 02862 if (tmp == p) { 02863 destroy_channel(prev, tmp, 0); 02864 break; 02865 } else { 02866 prev = tmp; 02867 tmp = tmp->next; 02868 } 02869 } 02870 } 02871 ast_mutex_unlock(&iflock); 02872 return 0; 02873 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5184 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, zt_pvt::digital, zt_pvt::dop, errno, func, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, zt_pvt::mohinterpret, option_debug, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().
05185 { 05186 struct zt_pvt *p = chan->tech_pvt; 05187 int res=-1; 05188 int index; 05189 int func = ZT_FLASH; 05190 ast_mutex_lock(&p->lock); 05191 index = zt_get_index(chan, p, 0); 05192 if (option_debug) 05193 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 05194 if (index == SUB_REAL) { 05195 switch (condition) { 05196 case AST_CONTROL_BUSY: 05197 #ifdef HAVE_PRI 05198 if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { 05199 chan->hangupcause = AST_CAUSE_USER_BUSY; 05200 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05201 res = 0; 05202 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05203 if (p->pri->pri) { 05204 if (!pri_grab(p, p->pri)) { 05205 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05206 pri_rel(p->pri); 05207 } 05208 else 05209 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05210 } 05211 p->progress = 1; 05212 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05213 } else 05214 #endif 05215 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05216 break; 05217 case AST_CONTROL_RINGING: 05218 #ifdef HAVE_PRI 05219 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05220 if (p->pri->pri) { 05221 if (!pri_grab(p, p->pri)) { 05222 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05223 pri_rel(p->pri); 05224 } 05225 else 05226 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05227 } 05228 p->alerting = 1; 05229 } 05230 #endif 05231 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05232 if (chan->_state != AST_STATE_UP) { 05233 if ((chan->_state != AST_STATE_RING) || 05234 ((p->sig != SIG_FXSKS) && 05235 (p->sig != SIG_FXSLS) && 05236 (p->sig != SIG_FXSGS))) 05237 ast_setstate(chan, AST_STATE_RINGING); 05238 } 05239 break; 05240 case AST_CONTROL_PROCEEDING: 05241 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05242 #ifdef HAVE_PRI 05243 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05244 if (p->pri->pri) { 05245 if (!pri_grab(p, p->pri)) { 05246 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05247 pri_rel(p->pri); 05248 } 05249 else 05250 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05251 } 05252 p->proceeding = 1; 05253 } 05254 #endif 05255 /* don't continue in ast_indicate */ 05256 res = 0; 05257 break; 05258 case AST_CONTROL_PROGRESS: 05259 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05260 #ifdef HAVE_PRI 05261 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05262 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05263 if (p->pri->pri) { 05264 if (!pri_grab(p, p->pri)) { 05265 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05266 pri_rel(p->pri); 05267 } 05268 else 05269 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05270 } 05271 p->progress = 1; 05272 } 05273 #endif 05274 /* don't continue in ast_indicate */ 05275 res = 0; 05276 break; 05277 case AST_CONTROL_CONGESTION: 05278 chan->hangupcause = AST_CAUSE_CONGESTION; 05279 #ifdef HAVE_PRI 05280 if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { 05281 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05282 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05283 res = 0; 05284 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05285 if (p->pri) { 05286 if (!pri_grab(p, p->pri)) { 05287 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05288 pri_rel(p->pri); 05289 } else 05290 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05291 } 05292 p->progress = 1; 05293 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05294 } else 05295 #endif 05296 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05297 break; 05298 case AST_CONTROL_HOLD: 05299 #ifdef HAVE_PRI 05300 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05301 if (!pri_grab(p, p->pri)) { 05302 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05303 pri_rel(p->pri); 05304 } else 05305 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05306 } else 05307 #endif 05308 ast_moh_start(chan, data, p->mohinterpret); 05309 break; 05310 case AST_CONTROL_UNHOLD: 05311 #ifdef HAVE_PRI 05312 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05313 if (!pri_grab(p, p->pri)) { 05314 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05315 pri_rel(p->pri); 05316 } else 05317 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05318 } else 05319 #endif 05320 ast_moh_stop(chan); 05321 break; 05322 case AST_CONTROL_RADIO_KEY: 05323 if (p->radio) 05324 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05325 res = 0; 05326 break; 05327 case AST_CONTROL_RADIO_UNKEY: 05328 if (p->radio) 05329 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05330 res = 0; 05331 break; 05332 case AST_CONTROL_FLASH: 05333 /* flash hookswitch */ 05334 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05335 /* Clear out the dial buffer */ 05336 p->dop.dialstr[0] = '\0'; 05337 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05338 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05339 chan->name, strerror(errno)); 05340 } else 05341 res = 0; 05342 } else 05343 res = 0; 05344 break; 05345 case AST_CONTROL_SRCUPDATE: 05346 res = 0; 05347 break; 05348 case -1: 05349 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05350 break; 05351 } 05352 } else 05353 res = 0; 05354 ast_mutex_unlock(&p->lock); 05355 return res; 05356 }
Definition at line 3231 of file chan_zap.c.
References ast_log(), LOG_WARNING, and master.
Referenced by zt_bridge().
03231 { 03232 int x; 03233 if (!slave || !master) { 03234 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03235 return; 03236 } 03237 for (x = 0; x < MAX_SLAVES; x++) { 03238 if (!master->slaves[x]) { 03239 master->slaves[x] = slave; 03240 break; 03241 } 03242 } 03243 if (x >= MAX_SLAVES) { 03244 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03245 master->slaves[MAX_SLAVES - 1] = slave; 03246 } 03247 if (slave->master) 03248 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03249 slave->master = master; 03250 03251 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03252 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | , | |
int | , | |||
int | , | |||
int | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5358 of file chan_zap.c.
References accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_random(), ast_safe_string_alloc(), AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_transfercapability2str(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::call_forward, zt_pvt::callgroup, ast_channel::callgroup, zt_pvt::callingpres, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, zt_pvt::cid_name, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, ast_channel::context, zt_pvt::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, zt_pvt::dsp_features, DSP_PROGRESS_TALK, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, free, global_jbconf, zt_pvt::hardwaredtmf, language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, PRI_TRANS_CAP_DIGITAL, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::writeformat, zap_tech, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
05359 { 05360 struct ast_channel *tmp; 05361 int deflaw; 05362 int res; 05363 int x,y; 05364 int features; 05365 char *b2 = NULL; 05366 ZT_PARAMS ps; 05367 if (i->subs[index].owner) { 05368 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05369 return NULL; 05370 } 05371 y = 1; 05372 do { 05373 if (b2) 05374 free(b2); 05375 #ifdef HAVE_PRI 05376 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05377 b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05378 else 05379 #endif 05380 if (i->channel == CHAN_PSEUDO) 05381 b2 = ast_safe_string_alloc("pseudo-%ld", ast_random()); 05382 else 05383 b2 = ast_safe_string_alloc("%d-%d", i->channel, y); 05384 for (x = 0; x < 3; x++) { 05385 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05386 break; 05387 } 05388 y++; 05389 } while (x < 3); 05390 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2); 05391 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05392 free(b2); 05393 if (!tmp) 05394 return NULL; 05395 tmp->tech = &zap_tech; 05396 ps.channo = i->channel; 05397 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05398 if (res) { 05399 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05400 ps.curlaw = ZT_LAW_MULAW; 05401 } 05402 if (ps.curlaw == ZT_LAW_ALAW) 05403 deflaw = AST_FORMAT_ALAW; 05404 else 05405 deflaw = AST_FORMAT_ULAW; 05406 if (law) { 05407 if (law == ZT_LAW_ALAW) 05408 deflaw = AST_FORMAT_ALAW; 05409 else 05410 deflaw = AST_FORMAT_ULAW; 05411 } 05412 tmp->fds[0] = i->subs[index].zfd; 05413 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05414 /* Start out assuming ulaw since it's smaller :) */ 05415 tmp->rawreadformat = deflaw; 05416 tmp->readformat = deflaw; 05417 tmp->rawwriteformat = deflaw; 05418 tmp->writeformat = deflaw; 05419 i->subs[index].linear = 0; 05420 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05421 features = 0; 05422 if (index == SUB_REAL) { 05423 if (i->busydetect && CANBUSYDETECT(i)) 05424 features |= DSP_FEATURE_BUSY_DETECT; 05425 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05426 features |= DSP_FEATURE_CALL_PROGRESS; 05427 if ((!i->outgoing && (i->callprogress & 4)) || 05428 (i->outgoing && (i->callprogress & 2))) { 05429 features |= DSP_FEATURE_FAX_DETECT; 05430 } 05431 #ifdef ZT_TONEDETECT 05432 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05433 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05434 #endif 05435 i->hardwaredtmf = 0; 05436 features |= DSP_FEATURE_DTMF_DETECT; 05437 #ifdef ZT_TONEDETECT 05438 } else if (NEED_MFDETECT(i)) { 05439 i->hardwaredtmf = 1; 05440 features |= DSP_FEATURE_DTMF_DETECT; 05441 } 05442 #endif 05443 } 05444 if (features) { 05445 if (i->dsp) { 05446 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05447 } else { 05448 if (i->channel != CHAN_PSEUDO) 05449 i->dsp = ast_dsp_new(); 05450 else 05451 i->dsp = NULL; 05452 if (i->dsp) { 05453 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05454 #ifdef HAVE_PRI 05455 /* We cannot do progress detection until receives PROGRESS message */ 05456 if (i->outgoing && (i->sig == SIG_PRI)) { 05457 /* Remember requested DSP features, don't treat 05458 talking as ANSWER */ 05459 features = 0; 05460 } 05461 #endif 05462 ast_dsp_set_features(i->dsp, features); 05463 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05464 if (!ast_strlen_zero(progzone)) 05465 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05466 if (i->busydetect && CANBUSYDETECT(i)) { 05467 ast_dsp_set_busy_count(i->dsp, i->busycount); 05468 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05469 } 05470 } 05471 } 05472 } 05473 05474 if (state == AST_STATE_RING) 05475 tmp->rings = 1; 05476 tmp->tech_pvt = i; 05477 #ifdef HAVE_PRI 05478 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) { 05479 #else 05480 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05481 #endif 05482 /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */ 05483 tmp->callgroup = i->callgroup; 05484 tmp->pickupgroup = i->pickupgroup; 05485 } 05486 if (!ast_strlen_zero(i->language)) 05487 ast_string_field_set(tmp, language, i->language); 05488 if (!i->owner) 05489 i->owner = tmp; 05490 if (!ast_strlen_zero(i->accountcode)) 05491 ast_string_field_set(tmp, accountcode, i->accountcode); 05492 if (i->amaflags) 05493 tmp->amaflags = i->amaflags; 05494 i->subs[index].owner = tmp; 05495 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05496 ast_string_field_set(tmp, call_forward, i->call_forward); 05497 /* If we've been told "no ADSI" then enforce it */ 05498 if (!i->adsi) 05499 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05500 if (!ast_strlen_zero(i->exten)) 05501 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05502 if (!ast_strlen_zero(i->rdnis)) 05503 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05504 if (!ast_strlen_zero(i->dnid)) 05505 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05506 05507 /* Don't use ast_set_callerid() here because it will 05508 * generate a needless NewCallerID event */ 05509 #ifdef PRI_ANI 05510 if (!ast_strlen_zero(i->cid_ani)) 05511 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05512 else 05513 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05514 #else 05515 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05516 #endif 05517 tmp->cid.cid_pres = i->callingpres; 05518 tmp->cid.cid_ton = i->cid_ton; 05519 #ifdef HAVE_PRI 05520 tmp->transfercapability = transfercapability; 05521 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05522 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05523 i->digital = 1; 05524 /* Assume calls are not idle calls unless we're told differently */ 05525 i->isidlecall = 0; 05526 i->alreadyhungup = 0; 05527 #endif 05528 /* clear the fake event in case we posted one before we had ast_channel */ 05529 i->fake_event = 0; 05530 /* Assure there is no confmute on this channel */ 05531 zt_confmute(i, 0); 05532 /* Configure the new channel jb */ 05533 ast_jb_configure(tmp, &global_jbconf); 05534 if (startpbx) { 05535 if (ast_pbx_start(tmp)) { 05536 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05537 ast_hangup(tmp); 05538 i->owner = NULL; 05539 return NULL; 05540 } 05541 } 05542 05543 ast_module_ref(ast_module_info->self); 05544 05545 return tmp; 05546 }
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] |
Definition at line 4786 of file chan_zap.c.
References __zt_exception(), ast_channel::_state, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_dsp_process(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_callerid(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_subchannel::buffer, zt_pvt::busydetect, zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::channel, CHECK_BLOCKING, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, zt_pvt::dsp, errno, zt_subchannel::f, f, zt_pvt::fake_event, zt_pvt::firstradio, ast_frame::frametype, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, S_OR, ast_frame::samples, send_callerid(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_get_index(), zt_handle_dtmfup(), and zt_setlinear().
04787 { 04788 struct zt_pvt *p = ast->tech_pvt; 04789 int res; 04790 int index; 04791 void *readbuf; 04792 struct ast_frame *f; 04793 04794 04795 ast_mutex_lock(&p->lock); 04796 04797 index = zt_get_index(ast, p, 0); 04798 04799 /* Hang up if we don't really exist */ 04800 if (index < 0) { 04801 ast_log(LOG_WARNING, "We dont exist?\n"); 04802 ast_mutex_unlock(&p->lock); 04803 return NULL; 04804 } 04805 04806 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04807 04808 p->subs[index].f.frametype = AST_FRAME_NULL; 04809 p->subs[index].f.datalen = 0; 04810 p->subs[index].f.samples = 0; 04811 p->subs[index].f.mallocd = 0; 04812 p->subs[index].f.offset = 0; 04813 p->subs[index].f.subclass = 0; 04814 p->subs[index].f.delivery = ast_tv(0,0); 04815 p->subs[index].f.src = "zt_read"; 04816 p->subs[index].f.data = NULL; 04817 04818 /* make sure it sends initial key state as first frame */ 04819 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04820 { 04821 ZT_PARAMS ps; 04822 04823 ps.channo = p->channel; 04824 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04825 ast_mutex_unlock(&p->lock); 04826 return NULL; 04827 } 04828 p->firstradio = 1; 04829 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04830 if (ps.rxisoffhook) 04831 { 04832 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04833 } 04834 else 04835 { 04836 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04837 } 04838 ast_mutex_unlock(&p->lock); 04839 return &p->subs[index].f; 04840 } 04841 if (p->ringt == 1) { 04842 ast_mutex_unlock(&p->lock); 04843 return NULL; 04844 } 04845 else if (p->ringt > 0) 04846 p->ringt--; 04847 04848 if (p->subs[index].needringing) { 04849 /* Send ringing frame if requested */ 04850 p->subs[index].needringing = 0; 04851 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04852 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04853 ast_setstate(ast, AST_STATE_RINGING); 04854 ast_mutex_unlock(&p->lock); 04855 return &p->subs[index].f; 04856 } 04857 04858 if (p->subs[index].needbusy) { 04859 /* Send busy frame if requested */ 04860 p->subs[index].needbusy = 0; 04861 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04862 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04863 ast_mutex_unlock(&p->lock); 04864 return &p->subs[index].f; 04865 } 04866 04867 if (p->subs[index].needcongestion) { 04868 /* Send congestion frame if requested */ 04869 p->subs[index].needcongestion = 0; 04870 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04871 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04872 ast_mutex_unlock(&p->lock); 04873 return &p->subs[index].f; 04874 } 04875 04876 if (p->subs[index].needcallerid) { 04877 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04878 S_OR(p->lastcid_name, NULL), 04879 S_OR(p->lastcid_num, NULL) 04880 ); 04881 p->subs[index].needcallerid = 0; 04882 } 04883 04884 if (p->subs[index].needanswer) { 04885 /* Send answer frame if requested */ 04886 p->subs[index].needanswer = 0; 04887 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04888 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04889 ast_mutex_unlock(&p->lock); 04890 return &p->subs[index].f; 04891 } 04892 04893 if (p->subs[index].needflash) { 04894 /* Send answer frame if requested */ 04895 p->subs[index].needflash = 0; 04896 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04897 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04898 ast_mutex_unlock(&p->lock); 04899 return &p->subs[index].f; 04900 } 04901 04902 if (p->subs[index].needhold) { 04903 /* Send answer frame if requested */ 04904 p->subs[index].needhold = 0; 04905 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04906 p->subs[index].f.subclass = AST_CONTROL_HOLD; 04907 ast_mutex_unlock(&p->lock); 04908 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 04909 return &p->subs[index].f; 04910 } 04911 04912 if (p->subs[index].needunhold) { 04913 /* Send answer frame if requested */ 04914 p->subs[index].needunhold = 0; 04915 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04916 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 04917 ast_mutex_unlock(&p->lock); 04918 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 04919 return &p->subs[index].f; 04920 } 04921 04922 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04923 if (!p->subs[index].linear) { 04924 p->subs[index].linear = 1; 04925 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04926 if (res) 04927 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04928 } 04929 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04930 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04931 if (p->subs[index].linear) { 04932 p->subs[index].linear = 0; 04933 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04934 if (res) 04935 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04936 } 04937 } else { 04938 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04939 ast_mutex_unlock(&p->lock); 04940 return NULL; 04941 } 04942 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04943 CHECK_BLOCKING(ast); 04944 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04945 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04946 /* Check for hangup */ 04947 if (res < 0) { 04948 f = NULL; 04949 if (res == -1) { 04950 if (errno == EAGAIN) { 04951 /* Return "NULL" frame if there is nobody there */ 04952 ast_mutex_unlock(&p->lock); 04953 return &p->subs[index].f; 04954 } else if (errno == ELAST) { 04955 f = __zt_exception(ast); 04956 } else 04957 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04958 } 04959 ast_mutex_unlock(&p->lock); 04960 return f; 04961 } 04962 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04963 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04964 f = __zt_exception(ast); 04965 ast_mutex_unlock(&p->lock); 04966 return f; 04967 } 04968 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04969 int c; 04970 04971 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04972 if (c < 0) { 04973 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04974 ast_mutex_unlock(&p->lock); 04975 return NULL; 04976 } 04977 if (c) { /* if a char to return */ 04978 p->subs[index].f.subclass = 0; 04979 p->subs[index].f.frametype = AST_FRAME_TEXT; 04980 p->subs[index].f.mallocd = 0; 04981 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04982 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04983 p->subs[index].f.datalen = 1; 04984 *((char *) p->subs[index].f.data) = c; 04985 ast_mutex_unlock(&p->lock); 04986 return &p->subs[index].f; 04987 } 04988 } 04989 /* Ensure the CW timer decrements only on a single subchannel */ 04990 if (p->callwaitingrepeat && zt_get_index(ast, p, 1) == SUB_REAL) { 04991 p->callwaitingrepeat--; 04992 } 04993 if (p->cidcwexpire) 04994 p->cidcwexpire--; 04995 /* Repeat callwaiting */ 04996 if (p->callwaitingrepeat == 1) { 04997 p->callwaitrings++; 04998 zt_callwait(ast); 04999 } 05000 /* Expire CID/CW */ 05001 if (p->cidcwexpire == 1) { 05002 if (option_verbose > 2) 05003 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 05004 restore_conference(p); 05005 } 05006 if (p->subs[index].linear) { 05007 p->subs[index].f.datalen = READ_SIZE * 2; 05008 } else 05009 p->subs[index].f.datalen = READ_SIZE; 05010 05011 /* Handle CallerID Transmission */ 05012 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 05013 send_callerid(p); 05014 } 05015 05016 p->subs[index].f.frametype = AST_FRAME_VOICE; 05017 p->subs[index].f.subclass = ast->rawreadformat; 05018 p->subs[index].f.samples = READ_SIZE; 05019 p->subs[index].f.mallocd = 0; 05020 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 05021 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 05022 #if 0 05023 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 05024 #endif 05025 if (p->dialing || /* Transmitting something */ 05026 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 05027 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 05028 ) { 05029 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 05030 don't send anything */ 05031 p->subs[index].f.frametype = AST_FRAME_NULL; 05032 p->subs[index].f.subclass = 0; 05033 p->subs[index].f.samples = 0; 05034 p->subs[index].f.mallocd = 0; 05035 p->subs[index].f.offset = 0; 05036 p->subs[index].f.data = NULL; 05037 p->subs[index].f.datalen= 0; 05038 } 05039 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 05040 /* Perform busy detection. etc on the zap line */ 05041 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 05042 if (f) { 05043 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 05044 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 05045 /* Treat this as a "hangup" instead of a "busy" on the assumption that 05046 a busy */ 05047 f = NULL; 05048 } 05049 } else if (f->frametype == AST_FRAME_DTMF) { 05050 #ifdef HAVE_PRI 05051 if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) { 05052 /* Don't accept in-band DTMF when in overlap dial mode 05053 or when in non-overlap overlapdialing mode ... */ 05054 f->frametype = AST_FRAME_NULL; 05055 f->subclass = 0; 05056 } 05057 #endif 05058 /* DSP clears us of being pulse */ 05059 p->pulsedial = 0; 05060 } 05061 } 05062 } else 05063 f = &p->subs[index].f; 05064 05065 if (f && (f->frametype == AST_FRAME_DTMF)) 05066 zt_handle_dtmfup(ast, index, &f); 05067 05068 /* If we have a fake_event, trigger exception to handle it */ 05069 if (p->fake_event) 05070 ast_set_flag(ast, AST_FLAG_EXCEPTION); 05071 05072 ast_mutex_unlock(&p->lock); 05073 return f; 05074 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 8040 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, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), round_robin, s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, zt_subchannel::zfd, and zt_new().
08041 { 08042 ast_group_t groupmatch = 0; 08043 int channelmatch = -1; 08044 int roundrobin = 0; 08045 int callwait = 0; 08046 int busy = 0; 08047 struct zt_pvt *p; 08048 struct ast_channel *tmp = NULL; 08049 char *dest=NULL; 08050 int x; 08051 char *s; 08052 char opt=0; 08053 int res=0, y=0; 08054 int backwards = 0; 08055 #ifdef HAVE_PRI 08056 int crv; 08057 int bearer = -1; 08058 int trunkgroup; 08059 struct zt_pri *pri=NULL; 08060 #endif 08061 struct zt_pvt *exit, *start, *end; 08062 ast_mutex_t *lock; 08063 int channelmatched = 0; 08064 int groupmatched = 0; 08065 08066 /* Assume we're locking the iflock */ 08067 lock = &iflock; 08068 start = iflist; 08069 end = ifend; 08070 if (data) { 08071 dest = ast_strdupa((char *)data); 08072 } else { 08073 ast_log(LOG_WARNING, "Channel requested with no data\n"); 08074 return NULL; 08075 } 08076 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 08077 /* Retrieve the group number */ 08078 char *stringp=NULL; 08079 stringp=dest + 1; 08080 s = strsep(&stringp, "/"); 08081 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 08082 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 08083 return NULL; 08084 } 08085 groupmatch = ((ast_group_t) 1 << x); 08086 if (toupper(dest[0]) == 'G') { 08087 if (dest[0] == 'G') { 08088 backwards = 1; 08089 p = ifend; 08090 } else 08091 p = iflist; 08092 } else { 08093 if (dest[0] == 'R') { 08094 backwards = 1; 08095 p = round_robin[x]?round_robin[x]->prev:ifend; 08096 if (!p) 08097 p = ifend; 08098 } else { 08099 p = round_robin[x]?round_robin[x]->next:iflist; 08100 if (!p) 08101 p = iflist; 08102 } 08103 roundrobin = 1; 08104 } 08105 } else { 08106 char *stringp=NULL; 08107 stringp=dest; 08108 s = strsep(&stringp, "/"); 08109 p = iflist; 08110 if (!strcasecmp(s, "pseudo")) { 08111 /* Special case for pseudo */ 08112 x = CHAN_PSEUDO; 08113 channelmatch = x; 08114 } 08115 #ifdef HAVE_PRI 08116 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 08117 if ((trunkgroup < 1) || (crv < 1)) { 08118 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 08119 return NULL; 08120 } 08121 res--; 08122 for (x = 0; x < NUM_SPANS; x++) { 08123 if (pris[x].trunkgroup == trunkgroup) { 08124 pri = pris + x; 08125 lock = &pri->lock; 08126 start = pri->crvs; 08127 end = pri->crvend; 08128 break; 08129 } 08130 } 08131 if (!pri) { 08132 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 08133 return NULL; 08134 } 08135 channelmatch = crv; 08136 p = pris[x].crvs; 08137 } 08138 #endif 08139 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 08140 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 08141 return NULL; 08142 } else { 08143 channelmatch = x; 08144 } 08145 } 08146 /* Search for an unowned channel */ 08147 ast_mutex_lock(lock); 08148 exit = p; 08149 while (p && !tmp) { 08150 if (roundrobin) 08151 round_robin[x] = p; 08152 #if 0 08153 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 08154 #endif 08155 08156 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 08157 if (option_debug) 08158 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 08159 if (p->inalarm) 08160 goto next; 08161 08162 callwait = (p->owner != NULL); 08163 #ifdef HAVE_PRI 08164 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 08165 if (p->sig != SIG_FXSKS) { 08166 /* Gotta find an actual channel to use for this 08167 CRV if this isn't a callwait */ 08168 bearer = pri_find_empty_chan(pri, 0); 08169 if (bearer < 0) { 08170 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 08171 p = NULL; 08172 break; 08173 } 08174 pri_assign_bearer(p, pri, pri->pvts[bearer]); 08175 } else { 08176 if (alloc_sub(p, 0)) { 08177 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 08178 p = NULL; 08179 break; 08180 } else 08181 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 08182 p->pri = pri; 08183 } 08184 } 08185 #endif 08186 if (p->channel == CHAN_PSEUDO) { 08187 p = chandup(p); 08188 if (!p) { 08189 break; 08190 } 08191 } 08192 if (p->owner) { 08193 if (alloc_sub(p, SUB_CALLWAIT)) { 08194 p = NULL; 08195 break; 08196 } 08197 } 08198 p->outgoing = 1; 08199 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 08200 #ifdef HAVE_PRI 08201 if (p->bearer) { 08202 /* Log owner to bearer channel, too */ 08203 p->bearer->owner = tmp; 08204 } 08205 #endif 08206 /* Make special notes */ 08207 if (res > 1) { 08208 if (opt == 'c') { 08209 /* Confirm answer */ 08210 p->confirmanswer = 1; 08211 } else if (opt == 'r') { 08212 /* Distinctive ring */ 08213 if (res < 3) 08214 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 08215 else 08216 p->distinctivering = y; 08217 } else if (opt == 'd') { 08218 /* If this is an ISDN call, make it digital */ 08219 p->digital = 1; 08220 if (tmp) 08221 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 08222 } else if (opt == 'm') { 08223 /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */ 08224 p->faxhandled = 1; 08225 if (tmp) 08226 tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO; 08227 } else { 08228 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 08229 } 08230 } 08231 /* Note if the call is a call waiting call */ 08232 if (tmp && callwait) 08233 tmp->cdrflags |= AST_CDR_CALLWAIT; 08234 break; 08235 } 08236 next: 08237 if (backwards) { 08238 p = p->prev; 08239 if (!p) 08240 p = end; 08241 } else { 08242 p = p->next; 08243 if (!p) 08244 p = start; 08245 } 08246 /* stop when you roll to the one that we started from */ 08247 if (p == exit) 08248 break; 08249 } 08250 ast_mutex_unlock(lock); 08251 restart_monitor(); 08252 if (callwait) 08253 *cause = AST_CAUSE_BUSY; 08254 else if (!tmp) { 08255 if (channelmatched) { 08256 if (busy) 08257 *cause = AST_CAUSE_BUSY; 08258 } else if (groupmatched) { 08259 *cause = AST_CAUSE_CONGESTION; 08260 } else { 08261 *cause = AST_CAUSE_CONGESTION; 08262 } 08263 } 08264 08265 return tmp; 08266 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3615 of file chan_zap.c.
References ast_log(), errno, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), and zt_handle_event().
03616 { 03617 int x; 03618 int res; 03619 /* Make sure our transmit state is on hook */ 03620 x = 0; 03621 x = ZT_ONHOOK; 03622 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03623 do { 03624 x = ZT_RING; 03625 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03626 if (res) { 03627 switch (errno) { 03628 case EBUSY: 03629 case EINTR: 03630 /* Wait just in case */ 03631 usleep(10000); 03632 continue; 03633 case EINPROGRESS: 03634 res = 0; 03635 break; 03636 default: 03637 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03638 res = 0; 03639 } 03640 } 03641 } while (res); 03642 return res; 03643 }
static int zt_sendmessage | ( | struct ast_channel * | c, | |
const char * | dest, | |||
const char * | text, | |||
int | ispdu | |||
) | [static] |
Definition at line 12848 of file chan_zap.c.
References ast_log(), zt_pvt::sig, SIG_GSM, SIG_PRI, ast_channel::tech_pvt, and zt_tdd_sendtext().
12848 { 12849 struct zt_pvt *p = c->tech_pvt; 12850 if (!p) return -1; 12851 if (p->sig == SIG_PRI) { 12852 #ifdef HAVE_PRI 12853 if (ispdu) { 12854 ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n"); 12855 return -1; 12856 } 12857 return zt_pri_sendtext(c, text); 12858 #endif 12859 } else if (p->sig == SIG_GSM) { 12860 #ifdef HAVE_GSMAT 12861 return zt_gsm_sendtext(c, dest, text, ispdu); 12862 #endif 12863 } else { 12864 if (ispdu) { 12865 ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP channel\n"); 12866 return -1; 12867 } 12868 return zt_tdd_sendtext(c, text); 12869 } 12870 return -1; 12871 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 12834 of file chan_zap.c.
References zt_pvt::sig, SIG_GSM, SIG_PRI, ast_channel::tech_pvt, and zt_tdd_sendtext().
12834 { 12835 struct zt_pvt *p = c->tech_pvt; 12836 if (!p) return -1; 12837 if (p->sig == SIG_PRI) { 12838 #ifdef HAVE_PRI 12839 return zt_pri_sendtext(c, text); 12840 #endif 12841 } else if (p->sig == SIG_GSM) { 12842 } else { 12843 return zt_tdd_sendtext(c, text); 12844 } 12845 return -1; 12846 }
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(), 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 2971 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().
02972 { 02973 char *cp; 02974 signed char *scp; 02975 int x; 02976 int index; 02977 struct zt_pvt *p = chan->tech_pvt, *pp; 02978 struct oprmode *oprmode; 02979 02980 02981 /* all supported options require data */ 02982 if (!data || (datalen < 1)) { 02983 errno = EINVAL; 02984 return -1; 02985 } 02986 02987 switch (option) { 02988 case AST_OPTION_TXGAIN: 02989 scp = (signed char *) data; 02990 index = zt_get_index(chan, p, 0); 02991 if (index < 0) { 02992 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02993 return -1; 02994 } 02995 if (option_debug) 02996 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02997 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02998 case AST_OPTION_RXGAIN: 02999 scp = (signed char *) data; 03000 index = zt_get_index(chan, p, 0); 03001 if (index < 0) { 03002 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 03003 return -1; 03004 } 03005 if (option_debug) 03006 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 03007 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 03008 case AST_OPTION_TONE_VERIFY: 03009 if (!p->dsp) 03010 break; 03011 cp = (char *) data; 03012 switch (*cp) { 03013 case 1: 03014 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 03015 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 03016 break; 03017 case 2: 03018 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 03019 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 03020 break; 03021 default: 03022 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 03023 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 03024 break; 03025 } 03026 break; 03027 case AST_OPTION_TDD: 03028 /* turn on or off TDD */ 03029 cp = (char *) data; 03030 p->mate = 0; 03031 if (!*cp) { /* turn it off */ 03032 if (option_debug) 03033 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 03034 if (p->tdd) 03035 tdd_free(p->tdd); 03036 p->tdd = 0; 03037 break; 03038 } 03039 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 03040 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 03041 zt_disable_ec(p); 03042 /* otherwise, turn it on */ 03043 if (!p->didtdd) { /* if havent done it yet */ 03044 unsigned char mybuf[41000], *buf; 03045 int size, res, fd, len; 03046 struct pollfd fds[1]; 03047 03048 buf = mybuf; 03049 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 03050 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 03051 len = 40000; 03052 index = zt_get_index(chan, p, 0); 03053 if (index < 0) { 03054 ast_log(LOG_WARNING, "No index in TDD?\n"); 03055 return -1; 03056 } 03057 fd = p->subs[index].zfd; 03058 while (len) { 03059 if (ast_check_hangup(chan)) 03060 return -1; 03061 size = len; 03062 if (size > READ_SIZE) 03063 size = READ_SIZE; 03064 fds[0].fd = fd; 03065 fds[0].events = POLLPRI | POLLOUT; 03066 fds[0].revents = 0; 03067 res = poll(fds, 1, -1); 03068 if (!res) { 03069 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 03070 continue; 03071 } 03072 /* if got exception */ 03073 if (fds[0].revents & POLLPRI) 03074 return -1; 03075 if (!(fds[0].revents & POLLOUT)) { 03076 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 03077 continue; 03078 } 03079 res = write(fd, buf, size); 03080 if (res != size) { 03081 if (res == -1) return -1; 03082 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 03083 break; 03084 } 03085 len -= size; 03086 buf += size; 03087 } 03088 p->didtdd = 1; /* set to have done it now */ 03089 } 03090 if (*cp == 2) { /* Mate mode */ 03091 if (p->tdd) 03092 tdd_free(p->tdd); 03093 p->tdd = 0; 03094 p->mate = 1; 03095 break; 03096 } 03097 if (!p->tdd) { /* if we dont have one yet */ 03098 p->tdd = tdd_new(); /* allocate one */ 03099 } 03100 break; 03101 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 03102 if (!p->dsp) 03103 break; 03104 cp = (char *) data; 03105 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 03106 *cp ? "ON" : "OFF", (int) *cp, chan->name); 03107 p->dtmfrelax = 0; 03108 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 03109 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 03110 break; 03111 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 03112 cp = (char *) data; 03113 if (!*cp) { 03114 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 03115 x = 0; 03116 zt_disable_ec(p); 03117 } else { 03118 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 03119 x = 1; 03120 } 03121 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 03122 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 03123 break; 03124 case AST_OPTION_OPRMODE: /* Operator services mode */ 03125 oprmode = (struct oprmode *) data; 03126 pp = oprmode->peer->tech_pvt; 03127 p->oprmode = pp->oprmode = 0; 03128 /* setup peers */ 03129 p->oprpeer = pp; 03130 pp->oprpeer = p; 03131 /* setup modes, if any */ 03132 if (oprmode->mode) 03133 { 03134 pp->oprmode = oprmode->mode; 03135 p->oprmode = -oprmode->mode; 03136 } 03137 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 03138 oprmode->mode, chan->name,oprmode->peer->name);; 03139 break; 03140 case AST_OPTION_ECHOCAN: 03141 cp = (char *) data; 03142 if (*cp) { 03143 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 03144 zt_enable_ec(p); 03145 } else { 03146 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 03147 zt_disable_ec(p); 03148 } 03149 break; 03150 } 03151 errno = 0; 03152 03153 return 0; 03154 }
static int zt_tdd_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 12873 of file chan_zap.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), ast_free, AST_LAW, ast_log(), ast_malloc, zt_pvt::channel, END_SILENCE_LEN, errno, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_ERROR, zt_pvt::mate, option_debug, poll(), POLLOUT, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, TRAILER_MS, zt_subchannel::zfd, and zt_get_index().
Referenced by zt_sendmessage(), and zt_sendtext().
12874 { 12875 #define END_SILENCE_LEN 400 12876 #define HEADER_MS 50 12877 #define TRAILER_MS 5 12878 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 12879 #define ASCII_BYTES_PER_CHAR 80 12880 12881 unsigned char *buf,*mybuf; 12882 struct zt_pvt *p = c->tech_pvt; 12883 struct pollfd fds[1]; 12884 int size,res,fd,len,x; 12885 int bytes=0; 12886 /* Initial carrier (imaginary) */ 12887 float cr = 1.0; 12888 float ci = 0.0; 12889 float scont = 0.0; 12890 int index; 12891 12892 12893 index = zt_get_index(c, p, 0); 12894 if (index < 0) { 12895 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 12896 return -1; 12897 } 12898 if (!text[0]) return(0); /* if nothing to send, dont */ 12899 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 12900 if (p->mate) 12901 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 12902 else 12903 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 12904 if (!buf) 12905 return -1; 12906 mybuf = buf; 12907 if (p->mate) { 12908 int codec = AST_LAW(p); 12909 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 12910 PUT_CLID_MARKMS; 12911 } 12912 /* Put actual message */ 12913 for (x = 0; text[x]; x++) { 12914 PUT_CLID(text[x]); 12915 } 12916 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 12917 PUT_CLID_MARKMS; 12918 } 12919 len = bytes; 12920 buf = mybuf; 12921 } else { 12922 len = tdd_generate(p->tdd, buf, text); 12923 if (len < 1) { 12924 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 12925 free(mybuf); 12926 return -1; 12927 } 12928 } 12929 memset(buf + len, 0x7f, END_SILENCE_LEN); 12930 len += END_SILENCE_LEN; 12931 fd = p->subs[index].zfd; 12932 while (len) { 12933 if (ast_check_hangup(c)) { 12934 free(mybuf); 12935 return -1; 12936 } 12937 size = len; 12938 if (size > READ_SIZE) 12939 size = READ_SIZE; 12940 fds[0].fd = fd; 12941 fds[0].events = POLLOUT | POLLPRI; 12942 fds[0].revents = 0; 12943 res = poll(fds, 1, -1); 12944 if (!res) { 12945 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 12946 continue; 12947 } 12948 /* if got exception */ 12949 if (fds[0].revents & POLLPRI) { 12950 ast_free(mybuf); 12951 return -1; 12952 } 12953 if (!(fds[0].revents & POLLOUT)) { 12954 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 12955 continue; 12956 } 12957 res = write(fd, buf, size); 12958 if (res != size) { 12959 if (res == -1) { 12960 free(mybuf); 12961 return -1; 12962 } 12963 if (option_debug) 12964 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 12965 break; 12966 } 12967 len -= size; 12968 buf += size; 12969 } 12970 free(mybuf); 12971 return(0); 12972 }
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 3175 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), conf_del(), DEADLOCK_AVOIDANCE, zt_pvt::lock, LOG_DEBUG, master, and SUB_REAL.
Referenced by zt_bridge(), and zt_fixup().
03176 { 03177 /* Unlink a specific slave or all slaves/masters from a given master */ 03178 int x; 03179 int hasslaves; 03180 if (!master) 03181 return; 03182 if (needlock) { 03183 ast_mutex_lock(&master->lock); 03184 if (slave) { 03185 while (ast_mutex_trylock(&slave->lock)) { 03186 DEADLOCK_AVOIDANCE(&master->lock); 03187 } 03188 } 03189 } 03190 hasslaves = 0; 03191 for (x = 0; x < MAX_SLAVES; x++) { 03192 if (master->slaves[x]) { 03193 if (!slave || (master->slaves[x] == slave)) { 03194 /* Take slave out of the conference */ 03195 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03196 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03197 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03198 master->slaves[x]->master = NULL; 03199 master->slaves[x] = NULL; 03200 } else 03201 hasslaves = 1; 03202 } 03203 if (!hasslaves) 03204 master->inconference = 0; 03205 } 03206 if (!slave) { 03207 if (master->master) { 03208 /* Take master out of the conference */ 03209 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03210 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03211 hasslaves = 0; 03212 for (x = 0; x < MAX_SLAVES; x++) { 03213 if (master->master->slaves[x] == master) 03214 master->master->slaves[x] = NULL; 03215 else if (master->master->slaves[x]) 03216 hasslaves = 1; 03217 } 03218 if (!hasslaves) 03219 master->master->inconference = 0; 03220 } 03221 master->master = NULL; 03222 } 03223 update_conf(master); 03224 if (needlock) { 03225 if (slave) 03226 ast_mutex_unlock(&slave->lock); 03227 ast_mutex_unlock(&master->lock); 03228 } 03229 }
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 5568 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05569 { 05570 int j; 05571 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05572 for (;;) 05573 { 05574 /* set bits of interest */ 05575 j = ZT_IOMUX_SIGEVENT; 05576 /* wait for some happening */ 05577 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05578 /* exit loop if we have it */ 05579 if (j & ZT_IOMUX_SIGEVENT) break; 05580 } 05581 /* get the event info */ 05582 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05583 return 0; 05584 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 5099 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, 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().
05100 { 05101 struct zt_pvt *p = ast->tech_pvt; 05102 int res; 05103 int index; 05104 index = zt_get_index(ast, p, 0); 05105 if (index < 0) { 05106 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 05107 return -1; 05108 } 05109 05110 #if 0 05111 #ifdef HAVE_PRI 05112 ast_mutex_lock(&p->lock); 05113 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05114 if (p->pri->pri) { 05115 if (!pri_grab(p, p->pri)) { 05116 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05117 pri_rel(p->pri); 05118 } else 05119 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05120 } 05121 p->proceeding=1; 05122 } 05123 ast_mutex_unlock(&p->lock); 05124 #endif 05125 #endif 05126 /* Write a frame of (presumably voice) data */ 05127 if (frame->frametype != AST_FRAME_VOICE) { 05128 if (frame->frametype == AST_FRAME_TEXT) { 05129 ast_log(LOG_NOTICE, "text\n"); 05130 } else if (frame->frametype != AST_FRAME_IMAGE) 05131 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 05132 return 0; 05133 } 05134 if ((frame->subclass != AST_FORMAT_SLINEAR) && 05135 (frame->subclass != AST_FORMAT_ULAW) && 05136 (frame->subclass != AST_FORMAT_ALAW)) { 05137 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 05138 return -1; 05139 } 05140 if (p->dialing) { 05141 if (option_debug) 05142 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 05143 return 0; 05144 } 05145 if (!p->owner) { 05146 if (option_debug) 05147 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 05148 return 0; 05149 } 05150 if (p->cidspill) { 05151 if (option_debug) 05152 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 05153 return 0; 05154 } 05155 /* Return if it's not valid data */ 05156 if (!frame->data || !frame->datalen) 05157 return 0; 05158 05159 if (frame->subclass == AST_FORMAT_SLINEAR) { 05160 if (!p->subs[index].linear) { 05161 p->subs[index].linear = 1; 05162 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05163 if (res) 05164 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 05165 } 05166 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 05167 } else { 05168 /* x-law already */ 05169 if (p->subs[index].linear) { 05170 p->subs[index].linear = 0; 05171 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05172 if (res) 05173 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 05174 } 05175 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 05176 } 05177 if (res < 0) { 05178 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05179 return -1; 05180 } 05181 return 0; 05182 }
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 11506 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] |
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 11498 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 11494 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] |
char zap_restart_usage[] [static] |
Definition at line 11510 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 11402 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 11502 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 737 of file chan_zap.c.
Referenced by __unload_module(), load_module(), ss_thread(), and zt_new().
char* zapEC_app = "zapEC" [static] |
char* zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel" [static] |
char* zapEC_tdesc = "Enable/disable Echo cancelation" [static] |