#include "asterisk.h"
#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <math.h>
#include <ctype.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj.h"
Go to the source code of this file.
Data Structures | |
struct | distRingData |
struct | ringContextData |
struct | zt_chan_conf |
Channel configuration from zapata.conf . This struct is used for parsing the [channels] section of zapata.conf. Generally there is a field here for every possible configuration item. More... | |
struct | zt_distRings |
struct | zt_pvt |
struct | zt_subchannel |
Defines | |
#define | ASCII_BYTES_PER_CHAR 80 |
#define | AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
#define | CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define | CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
#define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CHAN_PSEUDO -2 |
#define | CHANNEL_PSEUDO -12 |
#define | CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define | CONF_USER_REAL (1 << 0) |
#define | CONF_USER_THIRDCALL (1 << 1) |
#define | DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 1) |
#define | DCHAN_PROVISIONED (1 << 0) |
#define | DCHAN_UP (1 << 2) |
#define | DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID. | |
#define | DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
#define | END_SILENCE_LEN 400 |
#define | FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | GET_CHANNEL(p) ((p)->channel) |
#define | HANGUP 1 |
#define | HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
#define | HEADER_MS 50 |
#define | ISTRUNK(p) |
#define | MASK_AVAIL (1 << 0) |
#define | MASK_INUSE (1 << 1) |
#define | MAX_CHANLIST_LEN 80 |
#define | MAX_CHANNELS 672 |
#define | MAX_SLAVES 4 |
#define | MIN_MS_SINCE_FLASH ( (2000) ) |
#define | NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro. | |
#define | NUM_CADENCE_MAX 25 |
#define | NUM_DCHANS 4 |
#define | NUM_SPANS 32 |
#define | POLARITY_IDLE 0 |
#define | POLARITY_REV 1 |
#define | READ_SIZE 160 |
#define | sig2str zap_sig2str |
#define | SIG_E911 (0x1000000 | ZT_SIG_EM) |
#define | SIG_EM ZT_SIG_EM |
#define | SIG_EM_E1 ZT_SIG_EM_E1 |
#define | SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
#define | SIG_FEATB (0x0800000 | ZT_SIG_EM) |
#define | SIG_FEATD (0x0200000 | ZT_SIG_EM) |
#define | SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
#define | SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
#define | SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
#define | SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
#define | SIG_FXOGS ZT_SIG_FXOGS |
#define | SIG_FXOKS ZT_SIG_FXOKS |
#define | SIG_FXOLS ZT_SIG_FXOLS |
#define | SIG_FXSGS ZT_SIG_FXSGS |
#define | SIG_FXSKS ZT_SIG_FXSKS |
#define | SIG_FXSLS ZT_SIG_FXSLS |
#define | SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
#define | SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
#define | SIG_PRI ZT_SIG_CLEAR |
#define | SIG_SF ZT_SIG_SF |
#define | SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
#define | SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
#define | SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
#define | SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
#define | SMDI_MD_WAIT_TIMEOUT 1500 |
#define | SUB_CALLWAIT 1 |
#define | SUB_REAL 0 |
#define | SUB_THREEWAY 2 |
#define | tdesc "Zapata Telephony" |
#define | TRAILER_MS 5 |
#define | TRANSFER 0 |
#define | ZT_EVENT_DTMFDOWN 0 |
#define | ZT_EVENT_DTMFUP 0 |
Functions | |
static int | __unload_module (void) |
static struct ast_frame * | __zt_exception (struct ast_channel *ast) |
static int | action_transfer (struct mansession *s, const struct message *m) |
static int | action_transferhangup (struct mansession *s, const struct message *m) |
static int | action_zapdialoffhook (struct mansession *s, const struct message *m) |
static int | action_zapdndoff (struct mansession *s, const struct message *m) |
static int | action_zapdndon (struct mansession *s, const struct message *m) |
static int | action_zaprestart (struct mansession *s, const struct message *m) |
static int | action_zapshowchannels (struct mansession *s, const struct message *m) |
static char * | alarm2str (int alarm) |
static int | alloc_sub (struct zt_pvt *p, int x) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the interface list (of zt_pvt's). | |
static int | attempt_transfer (struct zt_pvt *p) |
static int | available (struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched) |
static int | build_channels (struct zt_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo) |
static int | bump_gains (struct zt_pvt *p) |
static struct zt_pvt * | chandup (struct zt_pvt *src) |
static int | check_for_conference (struct zt_pvt *p) |
static int | conf_add (struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel) |
static int | conf_del (struct zt_pvt *p, struct zt_subchannel *c, int index) |
static int | destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now) |
static void | destroy_zt_pvt (struct zt_pvt **pvt) |
static int | digit_to_dtmfindex (char digit) |
static void | disable_dtmf_detect (struct zt_pvt *p) |
static void * | do_monitor (void *data) |
static void | enable_dtmf_detect (struct zt_pvt *p) |
static char * | event2str (int event) |
static void | fill_rxgain (struct zt_gains *g, float gain, int law) |
static void | fill_txgain (struct zt_gains *g, float gain, int law) |
static struct zt_pvt * | find_channel (int channel) |
static int | get_alarms (struct zt_pvt *p) |
static int | handle_init_event (struct zt_pvt *i, int event) |
static int | handle_zap_show_cadences (int fd, int argc, char *argv[]) |
static int | has_voicemail (struct zt_pvt *p) |
static int | isourconf (struct zt_pvt *p, struct zt_subchannel *c) |
static int | isslavenative (struct zt_pvt *p, struct zt_pvt **out) |
static int | load_module (void) |
static struct zt_pvt * | mkintf (int channel, 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 | pri_active_dchan_fd (struct zt_pri *pri) |
static int | pri_assign_bearer (struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer) |
static int | pri_find_dchan (struct zt_pri *pri) |
static int | pri_is_up (struct zt_pri *pri) |
static int | process_zap (struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels) |
static char * | redirectingreason2str (int redirectingreason) |
static int | reload (void) |
static int | reset_conf (struct zt_pvt *p) |
static int | restart_monitor (void) |
static int | restore_conference (struct zt_pvt *p) |
static int | restore_gains (struct zt_pvt *p) |
static int | save_conference (struct zt_pvt *p) |
static int | send_callerid (struct zt_pvt *p) |
static int | send_cwcidspill (struct zt_pvt *p) |
static int | set_actual_gain (int fd, int chan, float rxgain, float txgain, int law) |
static int | set_actual_rxgain (int fd, int chan, float gain, int law) |
static int | set_actual_txgain (int fd, int chan, float gain, int law) |
static int | setup_zap (int reload) |
static void * | ss_thread (void *data) |
static void | swap_subs (struct zt_pvt *p, int a, int b) |
static int | unalloc_sub (struct zt_pvt *p, int x) |
static int | unload_module (void) |
static int | update_conf (struct zt_pvt *p) |
static void | wakeup_sub (struct zt_pvt *p, int a, void *pri) |
static int | zap_destroy_channel (int fd, int argc, char **argv) |
static int | zap_destroy_channel_bynum (int channel) |
static int | zap_fake_event (struct zt_pvt *p, int mode) |
static void | zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *pri) |
static int | zap_restart (void) |
static int | zap_restart_cmd (int fd, int argc, char **argv) |
static int | zap_show_channel (int fd, int argc, char **argv) |
static int | zap_show_channels (int fd, int argc, char **argv) |
static int | zap_show_status (int fd, int argc, char *argv[]) |
static char * | zap_sig2str (int sig) |
static int | zt_answer (struct ast_channel *ast) |
static enum ast_bridge_result | zt_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | zt_call (struct ast_channel *ast, char *rdest, int timeout) |
static int | zt_callwait (struct ast_channel *ast) |
static struct zt_chan_conf | zt_chan_conf_default (void) |
static void | zt_close (int fd) |
static int | zt_confmute (struct zt_pvt *p, int muted) |
static int | zt_digit_begin (struct ast_channel *ast, char digit) |
static int | zt_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static void | zt_disable_ec (struct zt_pvt *p) |
static void | zt_enable_ec (struct zt_pvt *p) |
static struct ast_frame * | zt_exception (struct ast_channel *ast) |
static int | zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | zt_func_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
static int | zt_get_event (int fd) |
Avoid the silly zt_getevent which ignores a bunch of events. | |
static int | zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok) |
static void | zt_handle_dtmfup (struct ast_channel *ast, int index, struct ast_frame **dest) |
static struct ast_frame * | zt_handle_event (struct ast_channel *ast) |
static int | zt_hangup (struct ast_channel *ast) |
static int | zt_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen) |
static void | zt_link (struct zt_pvt *slave, struct zt_pvt *master) |
static struct ast_channel * | zt_new (struct zt_pvt *, int, int, int, int, int) |
static int | zt_open (char *fn) |
static struct ast_frame * | zt_read (struct ast_channel *ast) |
static struct ast_channel * | zt_request (const char *type, int format, void *data, int *cause) |
static int | zt_ring_phone (struct zt_pvt *p) |
static int | zt_sendtext (struct ast_channel *c, const char *text) |
static int | zt_set_hook (int fd, int hs) |
static int | zt_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 void | zt_train_ec (struct zt_pvt *p) |
static void | zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock) |
static int | zt_wait_event (int fd) |
Avoid the silly zt_waitevent which ignores a bunch of events. | |
static int | zt_wink (struct zt_pvt *p, int index) |
static int | zt_write (struct ast_channel *ast, struct ast_frame *frame) |
Variables | |
struct { | |
int alarm | |
char * name | |
} | alarms [] |
static struct zt_ring_cadence | cadences [NUM_CADENCE_MAX] |
static int | cidrings [NUM_CADENCE_MAX] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
static const char | config [] = "zapata.conf" |
static struct ast_jb_conf | default_jbconf |
static char | defaultcic [64] = "" |
static char | defaultozz [64] = "" |
static char | destroy_channel_usage [] |
static int | distinctiveringaftercid = 0 |
static struct zt_distRings | drings |
static char * | events [] |
static int | firstdigittimeout = 16000 |
Wait up to 16 seconds for first digit (FXO logic). | |
static int | gendigittimeout = 8000 |
How long to wait for following digits (FXO logic). | |
static struct ast_jb_conf | global_jbconf |
static int | ifcount = 0 |
static struct zt_pvt * | ifend |
static struct zt_pvt * | iflist |
static int | matchdigittimeout = 3000 |
How long to wait for an extra digit, if there is an ambiguous match. | |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static int | num_cadence = 4 |
static int | numbufs = 4 |
static char | progzone [10] = "" |
static int | ringt_base = DEFAULT_RINGT |
zt_pvt * | round_robin [32] |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char * | subnames [] |
static const char | tdesc [] = "Zapata Telephony Driver" |
static int | user_has_defined_cadences = 0 |
static struct ast_cli_entry | zap_cli [] |
static char | zap_restart_usage [] |
static char | zap_show_cadences_help [] |
static char | zap_show_status_usage [] |
static struct ast_channel_tech | zap_tech |
You need to install libraries before you attempt to compile and install the zaptel channel.
Definition in file chan_zap.c.
#define ASCII_BYTES_PER_CHAR 80 |
Referenced by zt_sendtext().
#define AST_LAW | ( | p | ) | (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
Definition at line 155 of file chan_zap.c.
Referenced by send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_sendtext().
#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 283 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 197 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 153 of file chan_zap.c.
#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 407 of file chan_zap.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 408 of file chan_zap.c.
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
Definition at line 203 of file chan_zap.c.
#define DCHAN_NOTINALARM (1 << 1) |
Definition at line 200 of file chan_zap.c.
#define DCHAN_PROVISIONED (1 << 0) |
Definition at line 199 of file chan_zap.c.
#define DCHAN_UP (1 << 2) |
Definition at line 201 of file chan_zap.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 151 of file chan_zap.c.
Referenced by zt_chan_conf_default().
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
8,000 ms
Definition at line 287 of file chan_zap.c.
#define END_SILENCE_LEN 400 |
Referenced by zt_sendtext().
#define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define GET_CHANNEL | ( | p | ) | ((p)->channel) |
Definition at line 736 of file chan_zap.c.
#define HANGUP 1 |
Definition at line 10299 of file chan_zap.c.
Referenced by action_transferhangup(), and zap_fake_event().
#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_information(), build_notify(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_status(), build_status_enquiry(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_timeout(), build_user_information(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_information(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), parse_setup_acknowledge(), parse_status(), and zt_sendtext().
#define HEADER_MS 50 |
Referenced by zt_sendtext().
#define ISTRUNK | ( | p | ) |
Value:
Definition at line 780 of file chan_zap.c.
Referenced by ss_thread(), zap_show_channel(), and zt_indicate().
#define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 280 of file chan_zap.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 281 of file chan_zap.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'zapchan'.
Definition at line 10654 of file chan_zap.c.
Referenced by process_zap().
#define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 195 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 158 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
#define NUM_CADENCE_MAX 25 |
Definition at line 758 of file chan_zap.c.
#define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 194 of file chan_zap.c.
#define NUM_SPANS 32 |
Definition at line 193 of file chan_zap.c.
#define POLARITY_IDLE 0 |
Definition at line 365 of file chan_zap.c.
Referenced by unalloc_sub(), zt_handle_event(), and zt_hangup().
#define POLARITY_REV 1 |
Definition at line 366 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 278 of file chan_zap.c.
Referenced by my_zt_write(), process_zap(), send_cwcidspill(), zt_callwait(), zt_open(), zt_read(), zt_sendtext(), and zt_setoption().
#define sig2str zap_sig2str |
Definition at line 1244 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 173 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM ZT_SIG_EM |
Definition at line 168 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM_E1 ZT_SIG_EM_E1 |
Definition at line 189 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 169 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 172 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 170 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 171 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
Definition at line 174 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMA (0x4000000 | 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_FGC_CAMAMF (0x8000000 | 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_FXOGS ZT_SIG_FXOGS |
Definition at line 181 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 182 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 180 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXSGS ZT_SIG_FXSGS |
Definition at line 178 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 179 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 177 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
Definition at line 190 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 191 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_PRI ZT_SIG_CLEAR |
Definition at line 183 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit_begin(), zt_digit_end(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().
#define SIG_SF ZT_SIG_SF |
Definition at line 184 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
Definition at line 188 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
Definition at line 186 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
Definition at line 187 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 185 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 361 of file chan_zap.c.
#define SUB_REAL 0 |
Active call
Definition at line 360 of file chan_zap.c.
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 362 of file chan_zap.c.
#define tdesc "Zapata Telephony" |
Definition at line 11631 of file chan_zap.c.
#define TRAILER_MS 5 |
Referenced by zt_sendtext().
#define TRANSFER 0 |
#define ZT_EVENT_DTMFDOWN 0 |
#define ZT_EVENT_DTMFUP 0 |
static int __unload_module | ( | void | ) | [static] |
Definition at line 10480 of file chan_zap.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_verbose(), zt_pvt::channel, zt_pvt::cidspill, destroy_zt_pvt(), free, iflist, master, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, zap_cli, zap_tech, and zt_close().
10481 { 10482 int x; 10483 struct zt_pvt *p, *pl; 10484 10485 #ifdef HAVE_PRI 10486 int i; 10487 for (i = 0; i < NUM_SPANS; i++) { 10488 if (pris[i].master != AST_PTHREADT_NULL) 10489 pthread_cancel(pris[i].master); 10490 } 10491 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 10492 ast_unregister_application(zap_send_keypad_facility_app); 10493 #endif 10494 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 10495 ast_manager_unregister( "ZapDialOffhook" ); 10496 ast_manager_unregister( "ZapHangup" ); 10497 ast_manager_unregister( "ZapTransfer" ); 10498 ast_manager_unregister( "ZapDNDoff" ); 10499 ast_manager_unregister( "ZapDNDon" ); 10500 ast_manager_unregister("ZapShowChannels"); 10501 ast_manager_unregister("ZapRestart"); 10502 ast_channel_unregister(&zap_tech); 10503 ast_mutex_lock(&iflock); 10504 /* Hangup all interfaces if they have an owner */ 10505 p = iflist; 10506 while (p) { 10507 if (p->owner) 10508 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 10509 p = p->next; 10510 } 10511 ast_mutex_unlock(&iflock); 10512 ast_mutex_lock(&monlock); 10513 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 10514 pthread_cancel(monitor_thread); 10515 pthread_kill(monitor_thread, SIGURG); 10516 pthread_join(monitor_thread, NULL); 10517 } 10518 monitor_thread = AST_PTHREADT_STOP; 10519 ast_mutex_unlock(&monlock); 10520 10521 ast_mutex_lock(&iflock); 10522 /* Destroy all the interfaces and free their memory */ 10523 p = iflist; 10524 while (p) { 10525 /* Free any callerid */ 10526 if (p->cidspill) 10527 free(p->cidspill); 10528 /* Close the zapata thingy */ 10529 if (p->subs[SUB_REAL].zfd > -1) 10530 zt_close(p->subs[SUB_REAL].zfd); 10531 pl = p; 10532 p = p->next; 10533 x = pl->channel; 10534 /* Free associated memory */ 10535 if (pl) 10536 destroy_zt_pvt(&pl); 10537 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 10538 } 10539 iflist = NULL; 10540 ifcount = 0; 10541 ast_mutex_unlock(&iflock); 10542 #ifdef HAVE_PRI 10543 for (i = 0; i < NUM_SPANS; i++) { 10544 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 10545 pthread_join(pris[i].master, NULL); 10546 zt_close(pris[i].fds[i]); 10547 } 10548 #endif 10549 return 0; 10550 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4530 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_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().
04531 { 04532 struct zt_pvt *p = ast->tech_pvt; 04533 int res; 04534 int usedindex=-1; 04535 int index; 04536 struct ast_frame *f; 04537 04538 04539 index = zt_get_index(ast, p, 1); 04540 04541 p->subs[index].f.frametype = AST_FRAME_NULL; 04542 p->subs[index].f.datalen = 0; 04543 p->subs[index].f.samples = 0; 04544 p->subs[index].f.mallocd = 0; 04545 p->subs[index].f.offset = 0; 04546 p->subs[index].f.subclass = 0; 04547 p->subs[index].f.delivery = ast_tv(0,0); 04548 p->subs[index].f.src = "zt_exception"; 04549 p->subs[index].f.data = NULL; 04550 04551 04552 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04553 /* If nobody owns us, absorb the event appropriately, otherwise 04554 we loop indefinitely. This occurs when, during call waiting, the 04555 other end hangs up our channel so that it no longer exists, but we 04556 have neither FLASH'd nor ONHOOK'd to signify our desire to 04557 change to the other channel. */ 04558 if (p->fake_event) { 04559 res = p->fake_event; 04560 p->fake_event = 0; 04561 } else 04562 res = zt_get_event(p->subs[SUB_REAL].zfd); 04563 /* Switch to real if there is one and this isn't something really silly... */ 04564 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04565 (res != ZT_EVENT_HOOKCOMPLETE)) { 04566 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04567 p->owner = p->subs[SUB_REAL].owner; 04568 if (p->owner && ast_bridged_channel(p->owner)) 04569 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04570 p->subs[SUB_REAL].needunhold = 1; 04571 } 04572 switch (res) { 04573 case ZT_EVENT_ONHOOK: 04574 zt_disable_ec(p); 04575 if (p->owner) { 04576 if (option_verbose > 2) 04577 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04578 zt_ring_phone(p); 04579 p->callwaitingrepeat = 0; 04580 p->cidcwexpire = 0; 04581 } else 04582 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04583 update_conf(p); 04584 break; 04585 case ZT_EVENT_RINGOFFHOOK: 04586 zt_enable_ec(p); 04587 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04588 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04589 p->subs[SUB_REAL].needanswer = 1; 04590 p->dialing = 0; 04591 } 04592 break; 04593 case ZT_EVENT_HOOKCOMPLETE: 04594 case ZT_EVENT_RINGERON: 04595 case ZT_EVENT_RINGEROFF: 04596 /* Do nothing */ 04597 break; 04598 case ZT_EVENT_WINKFLASH: 04599 gettimeofday(&p->flashtime, NULL); 04600 if (p->owner) { 04601 if (option_verbose > 2) 04602 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04603 if (p->owner->_state != AST_STATE_UP) { 04604 /* Answer if necessary */ 04605 usedindex = zt_get_index(p->owner, p, 0); 04606 if (usedindex > -1) { 04607 p->subs[usedindex].needanswer = 1; 04608 } 04609 ast_setstate(p->owner, AST_STATE_UP); 04610 } 04611 p->callwaitingrepeat = 0; 04612 p->cidcwexpire = 0; 04613 if (ast_bridged_channel(p->owner)) 04614 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04615 p->subs[SUB_REAL].needunhold = 1; 04616 } else 04617 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04618 update_conf(p); 04619 break; 04620 default: 04621 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04622 } 04623 f = &p->subs[index].f; 04624 return f; 04625 } 04626 if (!(p->radio || (p->oprmode < 0)) && option_debug) 04627 ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04628 /* If it's not us, return NULL immediately */ 04629 if (ast != p->owner) { 04630 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04631 f = &p->subs[index].f; 04632 return f; 04633 } 04634 f = zt_handle_event(ast); 04635 return f; 04636 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10367 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().
10368 { 10369 struct zt_pvt *p = NULL; 10370 const char *channel = astman_get_header(m, "ZapChannel"); 10371 10372 if (ast_strlen_zero(channel)) { 10373 astman_send_error(s, m, "No channel specified"); 10374 return 0; 10375 } 10376 p = find_channel(atoi(channel)); 10377 if (!p) { 10378 astman_send_error(s, m, "No such channel"); 10379 return 0; 10380 } 10381 zap_fake_event(p,TRANSFER); 10382 astman_send_ack(s, m, "ZapTransfer"); 10383 return 0; 10384 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10386 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().
10387 { 10388 struct zt_pvt *p = NULL; 10389 const char *channel = astman_get_header(m, "ZapChannel"); 10390 10391 if (ast_strlen_zero(channel)) { 10392 astman_send_error(s, m, "No channel specified"); 10393 return 0; 10394 } 10395 p = find_channel(atoi(channel)); 10396 if (!p) { 10397 astman_send_error(s, m, "No such channel"); 10398 return 0; 10399 } 10400 zap_fake_event(p,HANGUP); 10401 astman_send_ack(s, m, "ZapHangup"); 10402 return 0; 10403 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10405 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().
10406 { 10407 struct zt_pvt *p = NULL; 10408 const char *channel = astman_get_header(m, "ZapChannel"); 10409 const char *number = astman_get_header(m, "Number"); 10410 int i; 10411 10412 if (ast_strlen_zero(channel)) { 10413 astman_send_error(s, m, "No channel specified"); 10414 return 0; 10415 } 10416 if (ast_strlen_zero(number)) { 10417 astman_send_error(s, m, "No number specified"); 10418 return 0; 10419 } 10420 p = find_channel(atoi(channel)); 10421 if (!p) { 10422 astman_send_error(s, m, "No such channel"); 10423 return 0; 10424 } 10425 if (!p->owner) { 10426 astman_send_error(s, m, "Channel does not have it's owner"); 10427 return 0; 10428 } 10429 for (i = 0; i < strlen(number); i++) { 10430 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 10431 zap_queue_frame(p, &f, NULL); 10432 } 10433 astman_send_ack(s, m, "ZapDialOffhook"); 10434 return 0; 10435 }
static int action_zapdndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10348 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().
10349 { 10350 struct zt_pvt *p = NULL; 10351 const char *channel = astman_get_header(m, "ZapChannel"); 10352 10353 if (ast_strlen_zero(channel)) { 10354 astman_send_error(s, m, "No channel specified"); 10355 return 0; 10356 } 10357 p = find_channel(atoi(channel)); 10358 if (!p) { 10359 astman_send_error(s, m, "No such channel"); 10360 return 0; 10361 } 10362 p->dnd = 0; 10363 astman_send_ack(s, m, "DND Disabled"); 10364 return 0; 10365 }
static int action_zapdndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10329 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().
10330 { 10331 struct zt_pvt *p = NULL; 10332 const char *channel = astman_get_header(m, "ZapChannel"); 10333 10334 if (ast_strlen_zero(channel)) { 10335 astman_send_error(s, m, "No channel specified"); 10336 return 0; 10337 } 10338 p = find_channel(atoi(channel)); 10339 if (!p) { 10340 astman_send_error(s, m, "No such channel"); 10341 return 0; 10342 } 10343 p->dnd = 1; 10344 astman_send_ack(s, m, "DND Enabled"); 10345 return 0; 10346 }
static int action_zaprestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 9937 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), s, and zap_restart().
Referenced by load_module().
09938 { 09939 if (zap_restart() != 0) { 09940 astman_send_error(s, m, "Failed rereading zaptel configuration"); 09941 return 1; 09942 } 09943 astman_send_ack(s, m, "ZapRestart: Success"); 09944 return 0; 09945 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10437 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().
10438 { 10439 struct zt_pvt *tmp = NULL; 10440 const char *id = astman_get_header(m, "ActionID"); 10441 char idText[256] = ""; 10442 10443 astman_send_ack(s, m, "Zapata channel status will follow"); 10444 if (!ast_strlen_zero(id)) 10445 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 10446 10447 ast_mutex_lock(&iflock); 10448 10449 tmp = iflist; 10450 while (tmp) { 10451 if (tmp->channel > 0) { 10452 int alarm = get_alarms(tmp); 10453 astman_append(s, 10454 "Event: ZapShowChannels\r\n" 10455 "Channel: %d\r\n" 10456 "Signalling: %s\r\n" 10457 "Context: %s\r\n" 10458 "DND: %s\r\n" 10459 "Alarm: %s\r\n" 10460 "%s" 10461 "\r\n", 10462 tmp->channel, sig2str(tmp->sig), tmp->context, 10463 tmp->dnd ? "Enabled" : "Disabled", 10464 alarm2str(alarm), idText); 10465 } 10466 10467 tmp = tmp->next; 10468 } 10469 10470 ast_mutex_unlock(&iflock); 10471 10472 astman_append(s, 10473 "Event: ZapShowChannelsComplete\r\n" 10474 "%s" 10475 "\r\n", 10476 idText); 10477 return 0; 10478 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1155 of file chan_zap.c.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01156 { 01157 int x; 01158 for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) { 01159 if (alarms[x].alarm & alarm) 01160 return alarms[x].name; 01161 } 01162 return alarm ? "Unknown Alarm" : "No Alarm"; 01163 }
static int alloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 953 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().
00954 { 00955 ZT_BUFFERINFO bi; 00956 int res; 00957 if (p->subs[x].zfd < 0) { 00958 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 00959 if (p->subs[x].zfd > -1) { 00960 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 00961 if (!res) { 00962 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 00963 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 00964 bi.numbufs = numbufs; 00965 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 00966 if (res < 0) { 00967 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 00968 } 00969 } else 00970 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 00971 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 00972 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd); 00973 zt_close(p->subs[x].zfd); 00974 p->subs[x].zfd = -1; 00975 return -1; 00976 } 00977 if (option_debug) 00978 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 00979 return 0; 00980 } else 00981 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00982 return -1; 00983 } 00984 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 00985 return -1; 00986 }
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 3513 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.
03514 { 03515 /* In order to transfer, we need at least one of the channels to 03516 actually be in a call bridge. We can't conference two applications 03517 together (but then, why would we want to?) */ 03518 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03519 /* The three-way person we're about to transfer to could still be in MOH, so 03520 stop if now if appropriate */ 03521 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03522 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03523 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03524 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03525 } 03526 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03527 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03528 } 03529 if (p->subs[SUB_REAL].owner->cdr) { 03530 /* Move CDR from second channel to current one */ 03531 p->subs[SUB_THREEWAY].owner->cdr = 03532 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03533 p->subs[SUB_REAL].owner->cdr = NULL; 03534 } 03535 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03536 /* Move CDR from second channel's bridge to current one */ 03537 p->subs[SUB_THREEWAY].owner->cdr = 03538 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03539 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03540 } 03541 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03542 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03543 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03544 return -1; 03545 } 03546 /* Orphan the channel after releasing the lock */ 03547 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03548 unalloc_sub(p, SUB_THREEWAY); 03549 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03550 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03551 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03552 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03553 } 03554 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03555 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03556 } 03557 if (p->subs[SUB_THREEWAY].owner->cdr) { 03558 /* Move CDR from second channel to current one */ 03559 p->subs[SUB_REAL].owner->cdr = 03560 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03561 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03562 } 03563 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03564 /* Move CDR from second channel's bridge to current one */ 03565 p->subs[SUB_REAL].owner->cdr = 03566 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03567 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03568 } 03569 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03570 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03571 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03572 return -1; 03573 } 03574 /* Three-way is now the REAL */ 03575 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03576 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03577 unalloc_sub(p, SUB_THREEWAY); 03578 /* Tell the caller not to hangup */ 03579 return 1; 03580 } else { 03581 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03582 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03583 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03584 return -1; 03585 } 03586 return 0; 03587 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
ast_group_t | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7645 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, LOG_DEBUG, zt_pvt::oprmode, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and zt_pvt::subs.
Referenced by zt_request().
07646 { 07647 int res; 07648 ZT_PARAMS par; 07649 07650 /* First, check group matching */ 07651 if (groupmatch) { 07652 if ((p->group & groupmatch) != groupmatch) 07653 return 0; 07654 *groupmatched = 1; 07655 } 07656 /* Check to see if we have a channel match */ 07657 if (channelmatch != -1) { 07658 if (p->channel != channelmatch) 07659 return 0; 07660 *channelmatched = 1; 07661 } 07662 /* We're at least busy at this point */ 07663 if (busy) { 07664 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07665 *busy = 1; 07666 } 07667 /* If do not disturb, definitely not */ 07668 if (p->dnd) 07669 return 0; 07670 /* If guard time, definitely not */ 07671 if (p->guardtime && (time(NULL) < p->guardtime)) 07672 return 0; 07673 07674 /* If no owner definitely available */ 07675 if (!p->owner) { 07676 #ifdef HAVE_PRI 07677 /* Trust PRI */ 07678 if (p->pri) { 07679 if (p->resetting || p->call) 07680 return 0; 07681 else 07682 return 1; 07683 } 07684 #endif 07685 if (!(p->radio || (p->oprmode < 0))) 07686 { 07687 if (!p->sig || (p->sig == SIG_FXSLS)) 07688 return 1; 07689 /* Check hook state */ 07690 if (p->subs[SUB_REAL].zfd > -1) 07691 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07692 else { 07693 /* Assume not off hook on CVRS */ 07694 res = 0; 07695 par.rxisoffhook = 0; 07696 } 07697 if (res) { 07698 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07699 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07700 /* When "onhook" that means no battery on the line, and thus 07701 it is out of service..., if it's on a TDM card... If it's a channel 07702 bank, there is no telling... */ 07703 if (par.rxbits > -1) 07704 return 1; 07705 if (par.rxisoffhook) 07706 return 1; 07707 else 07708 #ifdef ZAP_CHECK_HOOKSTATE 07709 return 0; 07710 #else 07711 return 1; 07712 #endif 07713 } else if (par.rxisoffhook) { 07714 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07715 /* Not available when the other end is off hook */ 07716 return 0; 07717 } 07718 } 07719 return 1; 07720 } 07721 07722 /* If it's not an FXO, forget about call wait */ 07723 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07724 return 0; 07725 07726 if (!p->callwaiting) { 07727 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07728 return 0; 07729 } 07730 07731 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07732 /* If there is already a call waiting call, then we can't take a second one */ 07733 return 0; 07734 } 07735 07736 if ((p->owner->_state != AST_STATE_UP) && 07737 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07738 /* If the current call is not up, then don't allow the call */ 07739 return 0; 07740 } 07741 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07742 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07743 return 0; 07744 } 07745 /* We're cool */ 07746 return 1; 07747 }
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 10562 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().
10563 { 10564 char *c, *chan; 10565 int x, start, finish; 10566 struct zt_pvt *tmp; 10567 #ifdef HAVE_PRI 10568 struct zt_pri *pri; 10569 int trunkgroup, y; 10570 #endif 10571 10572 if ((reload == 0) && (conf->chan.sig < 0)) { 10573 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 10574 return -1; 10575 } 10576 10577 c = ast_strdupa(value); 10578 10579 #ifdef HAVE_PRI 10580 pri = NULL; 10581 if (iscrv) { 10582 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 10583 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 10584 return -1; 10585 } 10586 if (trunkgroup < 1) { 10587 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 10588 return -1; 10589 } 10590 c += y; 10591 for (y = 0; y < NUM_SPANS; y++) { 10592 if (pris[y].trunkgroup == trunkgroup) { 10593 pri = pris + y; 10594 break; 10595 } 10596 } 10597 if (!pri) { 10598 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 10599 return -1; 10600 } 10601 } 10602 #endif 10603 10604 while ((chan = strsep(&c, ","))) { 10605 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 10606 /* Range */ 10607 } else if (sscanf(chan, "%d", &start)) { 10608 /* Just one */ 10609 finish = start; 10610 } else if (!strcasecmp(chan, "pseudo")) { 10611 finish = start = CHAN_PSEUDO; 10612 if (found_pseudo) 10613 *found_pseudo = 1; 10614 } else { 10615 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 10616 return -1; 10617 } 10618 if (finish < start) { 10619 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 10620 x = finish; 10621 finish = start; 10622 start = x; 10623 } 10624 10625 for (x = start; x <= finish; x++) { 10626 #ifdef HAVE_PRI 10627 tmp = mkintf(x, conf, pri, reload); 10628 #else 10629 tmp = mkintf(x, conf, NULL, reload); 10630 #endif 10631 10632 if (tmp) { 10633 if (option_verbose > 2) { 10634 #ifdef HAVE_PRI 10635 if (pri) 10636 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 10637 else 10638 #endif 10639 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 10640 } 10641 } else { 10642 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 10643 (reload == 1) ? "reconfigure" : "register", value); 10644 return -1; 10645 } 10646 } 10647 } 10648 10649 return 0; 10650 }
static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1606 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, and zt_pvt::txgain.
Referenced by ss_thread().
01607 { 01608 int res; 01609 01610 /* Bump receive gain by 5.0db */ 01611 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01612 if (res) { 01613 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01614 return -1; 01615 } 01616 01617 return 0; 01618 }
Definition at line 7749 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().
07750 { 07751 struct zt_pvt *p; 07752 ZT_BUFFERINFO bi; 07753 int res; 07754 07755 if ((p = ast_malloc(sizeof(*p)))) { 07756 memcpy(p, src, sizeof(struct zt_pvt)); 07757 ast_mutex_init(&p->lock); 07758 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07759 /* Allocate a zapata structure */ 07760 if (p->subs[SUB_REAL].zfd < 0) { 07761 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07762 destroy_zt_pvt(&p); 07763 return NULL; 07764 } 07765 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07766 if (!res) { 07767 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07768 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07769 bi.numbufs = numbufs; 07770 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07771 if (res < 0) { 07772 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 07773 } 07774 } else 07775 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 07776 } 07777 p->destroy = 1; 07778 p->next = iflist; 07779 p->prev = NULL; 07780 iflist = p; 07781 if (iflist->next) 07782 iflist->next->prev = p; 07783 return p; 07784 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3589 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, and VERBOSE_PREFIX_3.
Referenced by zt_handle_event().
03590 { 03591 ZT_CONFINFO ci; 03592 /* Fine if we already have a master, etc */ 03593 if (p->master || (p->confno > -1)) 03594 return 0; 03595 memset(&ci, 0, sizeof(ci)); 03596 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03597 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03598 return 0; 03599 } 03600 /* If we have no master and don't have a confno, then 03601 if we're in a conference, it's probably a MeetMe room or 03602 some such, so don't let us 3-way out! */ 03603 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03604 if (option_verbose > 2) 03605 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03606 return 1; 03607 } 03608 return 0; 03609 }
static int conf_add | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 1246 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().
01247 { 01248 /* If the conference already exists, and we're already in it 01249 don't bother doing anything */ 01250 ZT_CONFINFO zi; 01251 01252 memset(&zi, 0, sizeof(zi)); 01253 zi.chan = 0; 01254 01255 if (slavechannel > 0) { 01256 /* If we have only one slave, do a digital mon */ 01257 zi.confmode = ZT_CONF_DIGITALMON; 01258 zi.confno = slavechannel; 01259 } else { 01260 if (!index) { 01261 /* Real-side and pseudo-side both participate in conference */ 01262 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01263 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01264 } else 01265 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01266 zi.confno = p->confno; 01267 } 01268 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01269 return 0; 01270 if (c->zfd < 0) 01271 return 0; 01272 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01273 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01274 return -1; 01275 } 01276 if (slavechannel < 1) { 01277 p->confno = zi.confno; 01278 } 01279 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01280 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01281 return 0; 01282 }
static int conf_del | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 1295 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().
01296 { 01297 ZT_CONFINFO zi; 01298 if (/* Can't delete if there's no zfd */ 01299 (c->zfd < 0) || 01300 /* Don't delete from the conference if it's not our conference */ 01301 !isourconf(p, c) 01302 /* Don't delete if we don't think it's conferenced at all (implied) */ 01303 ) return 0; 01304 memset(&zi, 0, sizeof(zi)); 01305 zi.chan = 0; 01306 zi.confno = 0; 01307 zi.confmode = 0; 01308 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01309 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01310 return -1; 01311 } 01312 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01313 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01314 return 0; 01315 }
Definition at line 2247 of file chan_zap.c.
References destroy_zt_pvt(), iflist, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::prev, SUB_REAL, zt_pvt::subs, and zt_close().
Referenced by zap_destroy_channel_bynum(), zap_restart(), and zt_hangup().
02248 { 02249 int owned = 0; 02250 int i = 0; 02251 02252 if (!now) { 02253 if (cur->owner) { 02254 owned = 1; 02255 } 02256 02257 for (i = 0; i < 3; i++) { 02258 if (cur->subs[i].owner) { 02259 owned = 1; 02260 } 02261 } 02262 if (!owned) { 02263 if (prev) { 02264 prev->next = cur->next; 02265 if (prev->next) 02266 prev->next->prev = prev; 02267 else 02268 ifend = prev; 02269 } else { 02270 iflist = cur->next; 02271 if (iflist) 02272 iflist->prev = NULL; 02273 else 02274 ifend = NULL; 02275 } 02276 if (cur->subs[SUB_REAL].zfd > -1) { 02277 zt_close(cur->subs[SUB_REAL].zfd); 02278 } 02279 destroy_zt_pvt(&cur); 02280 } 02281 } else { 02282 if (prev) { 02283 prev->next = cur->next; 02284 if (prev->next) 02285 prev->next->prev = prev; 02286 else 02287 ifend = prev; 02288 } else { 02289 iflist = cur->next; 02290 if (iflist) 02291 iflist->prev = NULL; 02292 else 02293 ifend = NULL; 02294 } 02295 if (cur->subs[SUB_REAL].zfd > -1) { 02296 zt_close(cur->subs[SUB_REAL].zfd); 02297 } 02298 destroy_zt_pvt(&cur); 02299 } 02300 return 0; 02301 }
static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2232 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().
02233 { 02234 struct zt_pvt *p = *pvt; 02235 /* Remove channel from the list */ 02236 if (p->prev) 02237 p->prev->next = p->next; 02238 if (p->next) 02239 p->next->prev = p->prev; 02240 if (p->use_smdi) 02241 ast_smdi_interface_unref(p->smdi_iface); 02242 ast_mutex_destroy(&p->lock); 02243 free(p); 02244 *pvt = NULL; 02245 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 1008 of file chan_zap.c.
Referenced by zt_digit_begin().
01009 { 01010 if (isdigit(digit)) 01011 return ZT_TONE_DTMF_BASE + (digit - '0'); 01012 else if (digit >= 'A' && digit <= 'D') 01013 return ZT_TONE_DTMF_A + (digit - 'A'); 01014 else if (digit >= 'a' && digit <= 'd') 01015 return ZT_TONE_DTMF_A + (digit - 'a'); 01016 else if (digit == '*') 01017 return ZT_TONE_DTMF_s; 01018 else if (digit == '#') 01019 return ZT_TONE_DTMF_p; 01020 else 01021 return -1; 01022 }
static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3127 of file chan_zap.c.
References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, and zt_pvt::subs.
Referenced by zt_bridge().
03128 { 03129 #ifdef ZT_TONEDETECT 03130 int val; 03131 #endif 03132 03133 p->ignoredtmf = 1; 03134 03135 #ifdef ZT_TONEDETECT 03136 val = 0; 03137 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03138 #endif 03139 if (!p->hardwaredtmf && p->dsp) { 03140 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03141 ast_dsp_set_features(p->dsp, p->dsp_features); 03142 } 03143 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6837 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_pvt::owner, POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, and zt_pvt::subs.
06838 { 06839 int count, res, res2, spoint, pollres=0; 06840 struct zt_pvt *i; 06841 struct zt_pvt *last = NULL; 06842 time_t thispass = 0, lastpass = 0; 06843 int found; 06844 char buf[1024]; 06845 struct pollfd *pfds=NULL; 06846 int lastalloc = -1; 06847 /* This thread monitors all the frame relay interfaces which are not yet in use 06848 (and thus do not have a separate thread) indefinitely */ 06849 /* From here on out, we die whenever asked */ 06850 #if 0 06851 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 06852 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 06853 return NULL; 06854 } 06855 ast_log(LOG_DEBUG, "Monitor starting...\n"); 06856 #endif 06857 for (;;) { 06858 /* Lock the interface list */ 06859 ast_mutex_lock(&iflock); 06860 if (!pfds || (lastalloc != ifcount)) { 06861 if (pfds) { 06862 free(pfds); 06863 pfds = NULL; 06864 } 06865 if (ifcount) { 06866 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 06867 ast_mutex_unlock(&iflock); 06868 return NULL; 06869 } 06870 } 06871 lastalloc = ifcount; 06872 } 06873 /* Build the stuff we're going to poll on, that is the socket of every 06874 zt_pvt that does not have an associated owner channel */ 06875 count = 0; 06876 i = iflist; 06877 while (i) { 06878 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 06879 if (!i->owner && !i->subs[SUB_REAL].owner) { 06880 /* This needs to be watched, as it lacks an owner */ 06881 pfds[count].fd = i->subs[SUB_REAL].zfd; 06882 pfds[count].events = POLLPRI; 06883 pfds[count].revents = 0; 06884 /* Message waiting or r2 channels also get watched for reading */ 06885 if (i->cidspill) 06886 pfds[count].events |= POLLIN; 06887 count++; 06888 } 06889 } 06890 i = i->next; 06891 } 06892 /* Okay, now that we know what to do, release the interface lock */ 06893 ast_mutex_unlock(&iflock); 06894 06895 pthread_testcancel(); 06896 /* Wait at least a second for something to happen */ 06897 res = poll(pfds, count, 1000); 06898 pthread_testcancel(); 06899 /* Okay, poll has finished. Let's see what happened. */ 06900 if (res < 0) { 06901 if ((errno != EAGAIN) && (errno != EINTR)) 06902 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 06903 continue; 06904 } 06905 /* Alright, lock the interface list again, and let's look and see what has 06906 happened */ 06907 ast_mutex_lock(&iflock); 06908 found = 0; 06909 spoint = 0; 06910 lastpass = thispass; 06911 thispass = time(NULL); 06912 i = iflist; 06913 while (i) { 06914 if (thispass != lastpass) { 06915 if (!found && ((i == last) || ((i == iflist) && !last))) { 06916 last = i; 06917 if (last) { 06918 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 06919 (last->sig & __ZT_SIG_FXO)) { 06920 res = ast_app_has_voicemail(last->mailbox, NULL); 06921 if (last->msgstate != res) { 06922 int x; 06923 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 06924 x = ZT_FLUSH_BOTH; 06925 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 06926 if (res2) 06927 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 06928 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 06929 /* Turn on on hook transfer for 4 seconds */ 06930 x = 4000; 06931 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 06932 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 06933 last->cidpos = 0; 06934 last->msgstate = res; 06935 last->onhooktime = thispass; 06936 } 06937 found ++; 06938 } 06939 } 06940 last = last->next; 06941 } 06942 } 06943 } 06944 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 06945 if (i->radio && !i->owner) 06946 { 06947 res = zt_get_event(i->subs[SUB_REAL].zfd); 06948 if (res) 06949 { 06950 if (option_debug) 06951 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 06952 /* Don't hold iflock while handling init events */ 06953 ast_mutex_unlock(&iflock); 06954 handle_init_event(i, res); 06955 ast_mutex_lock(&iflock); 06956 } 06957 i = i->next; 06958 continue; 06959 } 06960 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 06961 if (pollres & POLLIN) { 06962 if (i->owner || i->subs[SUB_REAL].owner) { 06963 #ifdef HAVE_PRI 06964 if (!i->pri) 06965 #endif 06966 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 06967 i = i->next; 06968 continue; 06969 } 06970 if (!i->cidspill) { 06971 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 06972 i = i->next; 06973 continue; 06974 } 06975 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 06976 if (res > 0) { 06977 /* We read some number of bytes. Write an equal amount of data */ 06978 if (res > i->cidlen - i->cidpos) 06979 res = i->cidlen - i->cidpos; 06980 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 06981 if (res2 > 0) { 06982 i->cidpos += res2; 06983 if (i->cidpos >= i->cidlen) { 06984 free(i->cidspill); 06985 i->cidspill = 0; 06986 i->cidpos = 0; 06987 i->cidlen = 0; 06988 } 06989 } else { 06990 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 06991 i->msgstate = -1; 06992 } 06993 } else { 06994 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 06995 } 06996 } 06997 if (pollres & POLLPRI) { 06998 if (i->owner || i->subs[SUB_REAL].owner) { 06999 #ifdef HAVE_PRI 07000 if (!i->pri) 07001 #endif 07002 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 07003 i = i->next; 07004 continue; 07005 } 07006 res = zt_get_event(i->subs[SUB_REAL].zfd); 07007 if (option_debug) 07008 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 07009 /* Don't hold iflock while handling init events */ 07010 ast_mutex_unlock(&iflock); 07011 handle_init_event(i, res); 07012 ast_mutex_lock(&iflock); 07013 } 07014 } 07015 i=i->next; 07016 } 07017 ast_mutex_unlock(&iflock); 07018 } 07019 /* Never reached */ 07020 return NULL; 07021 07022 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3145 of file chan_zap.c.
References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, and zt_pvt::subs.
Referenced by zt_bridge().
03146 { 03147 #ifdef ZT_TONEDETECT 03148 int val; 03149 #endif 03150 03151 if (p->channel == CHAN_PSEUDO) 03152 return; 03153 03154 p->ignoredtmf = 0; 03155 03156 #ifdef ZT_TONEDETECT 03157 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03158 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03159 #endif 03160 if (!p->hardwaredtmf && p->dsp) { 03161 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03162 ast_dsp_set_features(p->dsp, p->dsp_features); 03163 } 03164 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1165 of file chan_zap.c.
Referenced by __zt_exception(), ss_thread(), and zt_handle_event().
01166 { 01167 static char buf[256]; 01168 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01169 return events[event]; 01170 sprintf(buf, "Event %d", event); /* safe */ 01171 return buf; 01172 }
static void fill_rxgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1530 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01531 { 01532 int j; 01533 int k; 01534 float linear_gain = pow(10.0, gain / 20.0); 01535 01536 switch (law) { 01537 case ZT_LAW_ALAW: 01538 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01539 if (gain) { 01540 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01541 if (k > 32767) k = 32767; 01542 if (k < -32767) k = -32767; 01543 g->rxgain[j] = AST_LIN2A(k); 01544 } else { 01545 g->rxgain[j] = j; 01546 } 01547 } 01548 break; 01549 case ZT_LAW_MULAW: 01550 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01551 if (gain) { 01552 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01553 if (k > 32767) k = 32767; 01554 if (k < -32767) k = -32767; 01555 g->rxgain[j] = AST_LIN2MU(k); 01556 } else { 01557 g->rxgain[j] = j; 01558 } 01559 } 01560 break; 01561 } 01562 }
static void fill_txgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1496 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01497 { 01498 int j; 01499 int k; 01500 float linear_gain = pow(10.0, gain / 20.0); 01501 01502 switch (law) { 01503 case ZT_LAW_ALAW: 01504 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01505 if (gain) { 01506 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01507 if (k > 32767) k = 32767; 01508 if (k < -32767) k = -32767; 01509 g->txgain[j] = AST_LIN2A(k); 01510 } else { 01511 g->txgain[j] = j; 01512 } 01513 } 01514 break; 01515 case ZT_LAW_MULAW: 01516 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01517 if (gain) { 01518 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01519 if (k > 32767) k = 32767; 01520 if (k < -32767) k = -32767; 01521 g->txgain[j] = AST_LIN2MU(k); 01522 } else { 01523 g->txgain[j] = j; 01524 } 01525 } 01526 break; 01527 } 01528 }
static struct zt_pvt* find_channel | ( | int | channel | ) | [static] |
Definition at line 10317 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().
10318 { 10319 struct zt_pvt *p = iflist; 10320 while (p) { 10321 if (p->channel == channel) { 10322 break; 10323 } 10324 p = p->next; 10325 } 10326 return p; 10327 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3611 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::span, SUB_REAL, and zt_pvt::subs.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03612 { 03613 int res; 03614 ZT_SPANINFO zi; 03615 memset(&zi, 0, sizeof(zi)); 03616 zi.spanno = p->span; 03617 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03618 if (res < 0) { 03619 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03620 return 0; 03621 } 03622 return zi.alarms; 03623 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6612 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_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
06613 { 06614 int res; 06615 pthread_t threadid; 06616 pthread_attr_t attr; 06617 struct ast_channel *chan; 06618 pthread_attr_init(&attr); 06619 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06620 /* Handle an event on a given channel for the monitor thread. */ 06621 switch (event) { 06622 case ZT_EVENT_NONE: 06623 case ZT_EVENT_BITSCHANGED: 06624 break; 06625 case ZT_EVENT_WINKFLASH: 06626 case ZT_EVENT_RINGOFFHOOK: 06627 if (i->inalarm) break; 06628 if (i->radio) break; 06629 /* Got a ring/answer. What kind of channel are we? */ 06630 switch (i->sig) { 06631 case SIG_FXOLS: 06632 case SIG_FXOGS: 06633 case SIG_FXOKS: 06634 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06635 if (res && (errno == EBUSY)) 06636 break; 06637 if (i->cidspill) { 06638 /* Cancel VMWI spill */ 06639 free(i->cidspill); 06640 i->cidspill = NULL; 06641 } 06642 if (i->immediate) { 06643 zt_enable_ec(i); 06644 /* The channel is immediately up. Start right away */ 06645 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06646 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06647 if (!chan) { 06648 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06649 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06650 if (res < 0) 06651 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06652 } 06653 } else { 06654 /* Check for callerid, digits, etc */ 06655 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06656 if (chan) { 06657 if (has_voicemail(i)) 06658 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06659 else 06660 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06661 if (res < 0) 06662 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 06663 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06664 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06665 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06666 if (res < 0) 06667 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06668 ast_hangup(chan); 06669 } 06670 } else 06671 ast_log(LOG_WARNING, "Unable to create channel\n"); 06672 } 06673 break; 06674 case SIG_FXSLS: 06675 case SIG_FXSGS: 06676 case SIG_FXSKS: 06677 i->ringt = i->ringt_base; 06678 /* Fall through */ 06679 case SIG_EMWINK: 06680 case SIG_FEATD: 06681 case SIG_FEATDMF: 06682 case SIG_FEATDMF_TA: 06683 case SIG_E911: 06684 case SIG_FGC_CAMA: 06685 case SIG_FGC_CAMAMF: 06686 case SIG_FEATB: 06687 case SIG_EM: 06688 case SIG_EM_E1: 06689 case SIG_SFWINK: 06690 case SIG_SF_FEATD: 06691 case SIG_SF_FEATDMF: 06692 case SIG_SF_FEATB: 06693 case SIG_SF: 06694 /* Check for callerid, digits, etc */ 06695 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06696 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06697 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06698 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06699 if (res < 0) 06700 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06701 ast_hangup(chan); 06702 } else if (!chan) { 06703 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06704 } 06705 break; 06706 default: 06707 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06708 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06709 if (res < 0) 06710 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06711 return -1; 06712 } 06713 break; 06714 case ZT_EVENT_NOALARM: 06715 i->inalarm = 0; 06716 if (!i->unknown_alarm) { 06717 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06718 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06719 "Channel: %d\r\n", i->channel); 06720 } else { 06721 i->unknown_alarm = 0; 06722 } 06723 break; 06724 case ZT_EVENT_ALARM: 06725 i->inalarm = 1; 06726 res = get_alarms(i); 06727 do { 06728 const char *alarm_str = alarm2str(res); 06729 06730 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 06731 * doesn't know what to do with it. Don't confuse users with log messages. */ 06732 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 06733 i->unknown_alarm = 1; 06734 break; 06735 } else { 06736 i->unknown_alarm = 0; 06737 } 06738 06739 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str); 06740 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06741 "Alarm: %s\r\n" 06742 "Channel: %d\r\n", 06743 alarm_str, i->channel); 06744 } while (0); 06745 /* fall thru intentionally */ 06746 case ZT_EVENT_ONHOOK: 06747 if (i->radio) 06748 break; 06749 /* Back on hook. Hang up. */ 06750 switch (i->sig) { 06751 case SIG_FXOLS: 06752 case SIG_FXOGS: 06753 case SIG_FEATD: 06754 case SIG_FEATDMF: 06755 case SIG_FEATDMF_TA: 06756 case SIG_E911: 06757 case SIG_FGC_CAMA: 06758 case SIG_FGC_CAMAMF: 06759 case SIG_FEATB: 06760 case SIG_EM: 06761 case SIG_EM_E1: 06762 case SIG_EMWINK: 06763 case SIG_SF_FEATD: 06764 case SIG_SF_FEATDMF: 06765 case SIG_SF_FEATB: 06766 case SIG_SF: 06767 case SIG_SFWINK: 06768 case SIG_FXSLS: 06769 case SIG_FXSGS: 06770 case SIG_FXSKS: 06771 case SIG_GR303FXSKS: 06772 zt_disable_ec(i); 06773 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06774 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06775 break; 06776 case SIG_GR303FXOKS: 06777 case SIG_FXOKS: 06778 zt_disable_ec(i); 06779 /* Diddle the battery for the zhone */ 06780 #ifdef ZHONE_HACK 06781 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06782 usleep(1); 06783 #endif 06784 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06785 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06786 break; 06787 case SIG_PRI: 06788 zt_disable_ec(i); 06789 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06790 break; 06791 default: 06792 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06793 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06794 return -1; 06795 } 06796 break; 06797 case ZT_EVENT_POLARITY: 06798 switch (i->sig) { 06799 case SIG_FXSLS: 06800 case SIG_FXSKS: 06801 case SIG_FXSGS: 06802 /* We have already got a PR before the channel was 06803 created, but it wasn't handled. We need polarity 06804 to be REV for remote hangup detection to work. 06805 At least in Spain */ 06806 if (i->hanguponpolarityswitch) 06807 i->polarity = POLARITY_REV; 06808 06809 if (i->cid_start == CID_START_POLARITY) { 06810 i->polarity = POLARITY_REV; 06811 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06812 "CID detection on channel %d\n", 06813 i->channel); 06814 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06815 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06816 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06817 } 06818 } 06819 break; 06820 default: 06821 ast_log(LOG_WARNING, "handle_init_event detected " 06822 "polarity reversal on non-FXO (SIG_FXS) " 06823 "interface %d\n", i->channel); 06824 } 06825 break; 06826 case ZT_EVENT_REMOVED: /* destroy channel */ 06827 ast_log(LOG_NOTICE, 06828 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 06829 i->channel); 06830 zap_destroy_channel_bynum(i->channel); 06831 break; 06832 } 06833 pthread_attr_destroy(&attr); 06834 return 0; 06835 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10161 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
10162 { 10163 int i, j; 10164 for (i = 0; i < num_cadence; i++) { 10165 char output[1024]; 10166 char tmp[16], tmp2[64]; 10167 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 10168 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 10169 10170 for (j = 0; j < 16; j++) { 10171 if (cadences[i].ringcadence[j] == 0) 10172 break; 10173 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 10174 if (cidrings[i] * 2 - 1 == j) 10175 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 10176 else 10177 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 10178 if (j != 0) 10179 strncat(output, ",", sizeof(output) - strlen(output) - 1); 10180 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 10181 } 10182 ast_cli(fd,"%s\n",output); 10183 } 10184 return 0; 10185 }
static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1725 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01726 { 01727 01728 return ast_app_has_voicemail(p->mailbox, NULL); 01729 }
static int isourconf | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c | |||
) | [static] |
Definition at line 1284 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01285 { 01286 /* If they're listening to our channel, they're ours */ 01287 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01288 return 1; 01289 /* If they're a talker on our (allocated) conference, they're ours */ 01290 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01291 return 1; 01292 return 0; 01293 }
Definition at line 1317 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().
01318 { 01319 int x; 01320 int useslavenative; 01321 struct zt_pvt *slave = NULL; 01322 /* Start out optimistic */ 01323 useslavenative = 1; 01324 /* Update conference state in a stateless fashion */ 01325 for (x = 0; x < 3; x++) { 01326 /* Any three-way calling makes slave native mode *definitely* out 01327 of the question */ 01328 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01329 useslavenative = 0; 01330 } 01331 /* If we don't have any 3-way calls, check to see if we have 01332 precisely one slave */ 01333 if (useslavenative) { 01334 for (x = 0; x < MAX_SLAVES; x++) { 01335 if (p->slaves[x]) { 01336 if (slave) { 01337 /* Whoops already have a slave! No 01338 slave native and stop right away */ 01339 slave = NULL; 01340 useslavenative = 0; 01341 break; 01342 } else { 01343 /* We have one slave so far */ 01344 slave = p->slaves[x]; 01345 } 01346 } 01347 } 01348 } 01349 /* If no slave, slave native definitely out */ 01350 if (!slave) 01351 useslavenative = 0; 01352 else if (slave->law != p->law) { 01353 useslavenative = 0; 01354 slave = NULL; 01355 } 01356 if (out) 01357 *out = slave; 01358 return useslavenative; 01359 }
static int load_module | ( | void | ) | [static] |
Definition at line 11464 of file chan_zap.c.
References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, ast_mutex_init(), AST_PTHREADT_NULL, ast_register_application(), ast_string_field_init, ast_string_field_set, inuse, lock, LOG_ERROR, name, round_robin, setup_zap(), zap_cli, and zap_tech.
11465 { 11466 int res; 11467 11468 #ifdef HAVE_PRI 11469 int y,i; 11470 memset(pris, 0, sizeof(pris)); 11471 for (y = 0; y < NUM_SPANS; y++) { 11472 ast_mutex_init(&pris[y].lock); 11473 pris[y].offset = -1; 11474 pris[y].master = AST_PTHREADT_NULL; 11475 for (i = 0; i < NUM_DCHANS; i++) 11476 pris[y].fds[i] = -1; 11477 } 11478 pri_set_error(zt_pri_error); 11479 pri_set_message(zt_pri_message); 11480 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 11481 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 11482 #endif 11483 res = setup_zap(0); 11484 /* Make sure we can register our Zap channel type */ 11485 if (res) 11486 return AST_MODULE_LOAD_DECLINE; 11487 if (ast_channel_register(&zap_tech)) { 11488 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 11489 __unload_module(); 11490 return -1; 11491 } 11492 #ifdef HAVE_PRI 11493 ast_string_field_init(&inuse, 16); 11494 ast_string_field_set(&inuse, name, "GR-303InUse"); 11495 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 11496 #endif 11497 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 11498 11499 memset(round_robin, 0, sizeof(round_robin)); 11500 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 11501 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 11502 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 11503 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 11504 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 11505 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 11506 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 11507 11508 return res; 11509 }
static struct zt_pvt* mkintf | ( | int | channel, | |
const struct zt_chan_conf * | conf, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static] |
Definition at line 7169 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_init(), ast_strlen_zero(), zt_chan_conf::chan, CHAN_PSEUDO, destroy_zt_pvt(), errno, iflist, LOG_ERROR, MAX_CHANNELS, zt_pvt::next, zt_pvt::prev, zt_pvt::sig, sig2str, SIG_FXOKS, SIG_FXSKS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SUB_REAL, and zt_open().
Referenced by build_channels().
07170 { 07171 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07172 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07173 char fn[80]; 07174 #if 1 07175 struct zt_bufferinfo bi; 07176 #endif 07177 struct zt_spaninfo si; 07178 int res; 07179 int span=0; 07180 int here = 0; 07181 int x; 07182 struct zt_pvt **wlist; 07183 struct zt_pvt **wend; 07184 ZT_PARAMS p; 07185 07186 wlist = &iflist; 07187 wend = &ifend; 07188 07189 #ifdef HAVE_PRI 07190 if (pri) { 07191 wlist = &pri->crvs; 07192 wend = &pri->crvend; 07193 } 07194 #endif 07195 07196 tmp2 = *wlist; 07197 prev = NULL; 07198 07199 while (tmp2) { 07200 if (!tmp2->destroy) { 07201 if (tmp2->channel == channel) { 07202 tmp = tmp2; 07203 here = 1; 07204 break; 07205 } 07206 if (tmp2->channel > channel) { 07207 break; 07208 } 07209 } 07210 prev = tmp2; 07211 tmp2 = tmp2->next; 07212 } 07213 07214 if (!here && !reloading) { 07215 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07216 destroy_zt_pvt(&tmp); 07217 return NULL; 07218 } 07219 ast_mutex_init(&tmp->lock); 07220 ifcount++; 07221 for (x = 0; x < 3; x++) 07222 tmp->subs[x].zfd = -1; 07223 tmp->channel = channel; 07224 } 07225 07226 if (tmp) { 07227 int chan_sig = conf->chan.sig; 07228 if (!here) { 07229 if ((channel != CHAN_PSEUDO) && !pri) { 07230 snprintf(fn, sizeof(fn), "%d", channel); 07231 /* Open non-blocking */ 07232 if (!here) 07233 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07234 /* Allocate a zapata structure */ 07235 if (tmp->subs[SUB_REAL].zfd < 0) { 07236 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); 07237 destroy_zt_pvt(&tmp); 07238 return NULL; 07239 } 07240 memset(&p, 0, sizeof(p)); 07241 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07242 if (res < 0) { 07243 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07244 destroy_zt_pvt(&tmp); 07245 return NULL; 07246 } 07247 if (p.sigtype != (conf->chan.sig & 0x3ffff)) { 07248 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)); 07249 destroy_zt_pvt(&tmp); 07250 return NULL; 07251 } 07252 tmp->law = p.curlaw; 07253 tmp->span = p.spanno; 07254 span = p.spanno - 1; 07255 } else { 07256 if (channel == CHAN_PSEUDO) 07257 chan_sig = 0; 07258 else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) { 07259 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07260 return NULL; 07261 } 07262 } 07263 #ifdef HAVE_PRI 07264 if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) { 07265 int offset; 07266 int myswitchtype; 07267 int matchesdchan; 07268 int x,y; 07269 offset = 0; 07270 if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07271 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07272 destroy_zt_pvt(&tmp); 07273 return NULL; 07274 } 07275 if (span >= NUM_SPANS) { 07276 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07277 destroy_zt_pvt(&tmp); 07278 return NULL; 07279 } else { 07280 si.spanno = 0; 07281 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07282 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07283 destroy_zt_pvt(&tmp); 07284 return NULL; 07285 } 07286 /* Store the logical span first based upon the real span */ 07287 tmp->logicalspan = pris[span].prilogicalspan; 07288 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07289 if (span < 0) { 07290 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07291 destroy_zt_pvt(&tmp); 07292 return NULL; 07293 } 07294 if (chan_sig == SIG_PRI) 07295 myswitchtype = conf->pri.switchtype; 07296 else 07297 myswitchtype = PRI_SWITCH_GR303_TMC; 07298 /* Make sure this isn't a d-channel */ 07299 matchesdchan=0; 07300 for (x = 0; x < NUM_SPANS; x++) { 07301 for (y = 0; y < NUM_DCHANS; y++) { 07302 if (pris[x].dchannels[y] == tmp->channel) { 07303 matchesdchan = 1; 07304 break; 07305 } 07306 } 07307 } 07308 offset = p.chanpos; 07309 if (!matchesdchan) { 07310 if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) { 07311 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07312 destroy_zt_pvt(&tmp); 07313 return NULL; 07314 } 07315 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07316 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07317 destroy_zt_pvt(&tmp); 07318 return NULL; 07319 } 07320 if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) { 07321 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07322 destroy_zt_pvt(&tmp); 07323 return NULL; 07324 } 07325 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) { 07326 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial); 07327 destroy_zt_pvt(&tmp); 07328 return NULL; 07329 } 07330 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) { 07331 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext); 07332 destroy_zt_pvt(&tmp); 07333 return NULL; 07334 } 07335 if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) { 07336 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused); 07337 destroy_zt_pvt(&tmp); 07338 return NULL; 07339 } 07340 if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) { 07341 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle); 07342 destroy_zt_pvt(&tmp); 07343 return NULL; 07344 } 07345 if (pris[span].numchans >= MAX_CHANNELS) { 07346 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07347 pris[span].trunkgroup); 07348 destroy_zt_pvt(&tmp); 07349 return NULL; 07350 } 07351 pris[span].nodetype = conf->pri.nodetype; 07352 pris[span].switchtype = myswitchtype; 07353 pris[span].nsf = conf->pri.nsf; 07354 pris[span].dialplan = conf->pri.dialplan; 07355 pris[span].localdialplan = conf->pri.localdialplan; 07356 pris[span].pvts[pris[span].numchans++] = tmp; 07357 pris[span].minunused = conf->pri.minunused; 07358 pris[span].minidle = conf->pri.minidle; 07359 pris[span].overlapdial = conf->pri.overlapdial; 07360 pris[span].facilityenable = conf->pri.facilityenable; 07361 ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial)); 07362 ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext)); 07363 ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07364 ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07365 ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix)); 07366 ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix)); 07367 ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07368 pris[span].resetinterval = conf->pri.resetinterval; 07369 07370 tmp->pri = &pris[span]; 07371 tmp->prioffset = offset; 07372 tmp->call = NULL; 07373 } else { 07374 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07375 destroy_zt_pvt(&tmp); 07376 return NULL; 07377 } 07378 } 07379 } else { 07380 tmp->prioffset = 0; 07381 } 07382 #endif 07383 } else { 07384 chan_sig = tmp->sig; 07385 memset(&p, 0, sizeof(p)); 07386 if (tmp->subs[SUB_REAL].zfd > -1) 07387 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07388 } 07389 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07390 switch (chan_sig) { 07391 case SIG_FXSKS: 07392 case SIG_FXSLS: 07393 case SIG_EM: 07394 case SIG_EM_E1: 07395 case SIG_EMWINK: 07396 case SIG_FEATD: 07397 case SIG_FEATDMF: 07398 case SIG_FEATDMF_TA: 07399 case SIG_FEATB: 07400 case SIG_E911: 07401 case SIG_SF: 07402 case SIG_SFWINK: 07403 case SIG_FGC_CAMA: 07404 case SIG_FGC_CAMAMF: 07405 case SIG_SF_FEATD: 07406 case SIG_SF_FEATDMF: 07407 case SIG_SF_FEATB: 07408 p.starttime = 250; 07409 break; 07410 } 07411 07412 if (tmp->radio) { 07413 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07414 p.channo = channel; 07415 p.rxwinktime = 1; 07416 p.rxflashtime = 1; 07417 p.starttime = 1; 07418 p.debouncetime = 5; 07419 } 07420 if (!tmp->radio) { 07421 p.channo = channel; 07422 /* Override timing settings based on config file */ 07423 if (conf->timing.prewinktime >= 0) 07424 p.prewinktime = conf->timing.prewinktime; 07425 if (conf->timing.preflashtime >= 0) 07426 p.preflashtime = conf->timing.preflashtime; 07427 if (conf->timing.winktime >= 0) 07428 p.winktime = conf->timing.winktime; 07429 if (conf->timing.flashtime >= 0) 07430 p.flashtime = conf->timing.flashtime; 07431 if (conf->timing.starttime >= 0) 07432 p.starttime = conf->timing.starttime; 07433 if (conf->timing.rxwinktime >= 0) 07434 p.rxwinktime = conf->timing.rxwinktime; 07435 if (conf->timing.rxflashtime >= 0) 07436 p.rxflashtime = conf->timing.rxflashtime; 07437 if (conf->timing.debouncetime >= 0) 07438 p.debouncetime = conf->timing.debouncetime; 07439 } 07440 07441 /* dont set parms on a pseudo-channel (or CRV) */ 07442 if (tmp->subs[SUB_REAL].zfd >= 0) 07443 { 07444 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07445 if (res < 0) { 07446 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07447 destroy_zt_pvt(&tmp); 07448 return NULL; 07449 } 07450 } 07451 #if 1 07452 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07453 memset(&bi, 0, sizeof(bi)); 07454 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07455 if (!res) { 07456 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07457 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07458 bi.numbufs = numbufs; 07459 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07460 if (res < 0) { 07461 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07462 } 07463 } else 07464 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07465 } 07466 #endif 07467 tmp->immediate = conf->chan.immediate; 07468 tmp->transfertobusy = conf->chan.transfertobusy; 07469 tmp->sig = chan_sig; 07470 tmp->outsigmod = conf->chan.outsigmod; 07471 tmp->ringt_base = ringt_base; 07472 tmp->firstradio = 0; 07473 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 07474 tmp->permcallwaiting = conf->chan.callwaiting; 07475 else 07476 tmp->permcallwaiting = 0; 07477 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07478 tmp->destroy = 0; 07479 tmp->drings = drings; 07480 tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection; 07481 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 07482 tmp->threewaycalling = conf->chan.threewaycalling; 07483 tmp->adsi = conf->chan.adsi; 07484 tmp->use_smdi = conf->chan.use_smdi; 07485 tmp->permhidecallerid = conf->chan.hidecallerid; 07486 tmp->callreturn = conf->chan.callreturn; 07487 tmp->echocancel = conf->chan.echocancel; 07488 tmp->echotraining = conf->chan.echotraining; 07489 tmp->pulse = conf->chan.pulse; 07490 if (tmp->echocancel) 07491 tmp->echocanbridged = conf->chan.echocanbridged; 07492 else { 07493 if (conf->chan.echocanbridged) 07494 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 07495 tmp->echocanbridged = 0; 07496 } 07497 tmp->busydetect = conf->chan.busydetect; 07498 tmp->busycount = conf->chan.busycount; 07499 tmp->busycompare = conf->chan.busycompare; 07500 tmp->busytonelength = conf->chan.busytonelength; 07501 tmp->busyquietlength = conf->chan.busyquietlength; 07502 tmp->busyfuzziness = conf->chan.busyfuzziness; 07503 tmp->silencethreshold = conf->chan.silencethreshold; 07504 tmp->callprogress = conf->chan.callprogress; 07505 tmp->cancallforward = conf->chan.cancallforward; 07506 tmp->dtmfrelax = conf->chan.dtmfrelax; 07507 tmp->callwaiting = tmp->permcallwaiting; 07508 tmp->hidecallerid = tmp->permhidecallerid; 07509 tmp->channel = channel; 07510 tmp->stripmsd = conf->chan.stripmsd; 07511 tmp->use_callerid = conf->chan.use_callerid; 07512 tmp->cid_signalling = conf->chan.cid_signalling; 07513 tmp->cid_start = conf->chan.cid_start; 07514 tmp->zaptrcallerid = conf->chan.zaptrcallerid; 07515 tmp->restrictcid = conf->chan.restrictcid; 07516 tmp->use_callingpres = conf->chan.use_callingpres; 07517 tmp->priindication_oob = conf->chan.priindication_oob; 07518 tmp->priexclusive = conf->chan.priexclusive; 07519 if (tmp->usedistinctiveringdetection) { 07520 if (!tmp->use_callerid) { 07521 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07522 tmp->use_callerid = 1; 07523 } 07524 } 07525 07526 if (tmp->cid_signalling == CID_SIG_SMDI) { 07527 if (!tmp->use_smdi) { 07528 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07529 tmp->use_smdi = 1; 07530 } 07531 } 07532 if (tmp->use_smdi) { 07533 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 07534 if (!(tmp->smdi_iface)) { 07535 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07536 tmp->use_smdi = 0; 07537 } 07538 } 07539 07540 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 07541 tmp->amaflags = conf->chan.amaflags; 07542 if (!here) { 07543 tmp->confno = -1; 07544 tmp->propconfno = -1; 07545 } 07546 tmp->canpark = conf->chan.canpark; 07547 tmp->transfer = conf->chan.transfer; 07548 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 07549 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 07550 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 07551 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 07552 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 07553 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 07554 tmp->cid_ton = 0; 07555 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 07556 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 07557 tmp->msgstate = -1; 07558 tmp->group = conf->chan.group; 07559 tmp->callgroup = conf->chan.callgroup; 07560 tmp->pickupgroup= conf->chan.pickupgroup; 07561 tmp->rxgain = conf->chan.rxgain; 07562 tmp->txgain = conf->chan.txgain; 07563 tmp->tonezone = conf->chan.tonezone; 07564 tmp->onhooktime = time(NULL); 07565 if (tmp->subs[SUB_REAL].zfd > -1) { 07566 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07567 if (tmp->dsp) 07568 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07569 update_conf(tmp); 07570 if (!here) { 07571 if (chan_sig != SIG_PRI) 07572 /* Hang it up to be sure it's good */ 07573 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07574 } 07575 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07576 #ifdef HAVE_PRI 07577 /* the dchannel is down so put the channel in alarm */ 07578 if (tmp->pri && !pri_is_up(tmp->pri)) 07579 tmp->inalarm = 1; 07580 else 07581 tmp->inalarm = 0; 07582 #endif 07583 memset(&si, 0, sizeof(si)); 07584 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07585 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07586 destroy_zt_pvt(&tmp); 07587 return NULL; 07588 } 07589 if (si.alarms) tmp->inalarm = 1; 07590 } 07591 07592 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 07593 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 07594 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 07595 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 07596 07597 } 07598 if (tmp && !here) { 07599 /* nothing on the iflist */ 07600 if (!*wlist) { 07601 *wlist = tmp; 07602 tmp->prev = NULL; 07603 tmp->next = NULL; 07604 *wend = tmp; 07605 } else { 07606 /* at least one member on the iflist */ 07607 struct zt_pvt *working = *wlist; 07608 07609 /* check if we maybe have to put it on the begining */ 07610 if (working->channel > tmp->channel) { 07611 tmp->next = *wlist; 07612 tmp->prev = NULL; 07613 (*wlist)->prev = tmp; 07614 *wlist = tmp; 07615 } else { 07616 /* go through all the members and put the member in the right place */ 07617 while (working) { 07618 /* in the middle */ 07619 if (working->next) { 07620 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07621 tmp->next = working->next; 07622 tmp->prev = working; 07623 working->next->prev = tmp; 07624 working->next = tmp; 07625 break; 07626 } 07627 } else { 07628 /* the last */ 07629 if (working->channel < tmp->channel) { 07630 working->next = tmp; 07631 tmp->next = NULL; 07632 tmp->prev = working; 07633 *wend = tmp; 07634 break; 07635 } 07636 } 07637 working = working->next; 07638 } 07639 } 07640 } 07641 } 07642 return tmp; 07643 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5409 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05410 { 05411 char c; 05412 05413 *str = 0; /* start with empty output buffer */ 05414 for (;;) 05415 { 05416 /* Wait for the first digit (up to specified ms). */ 05417 c = ast_waitfordigit(chan, ms); 05418 /* if timeout, hangup or error, return as such */ 05419 if (c < 1) 05420 return c; 05421 *str++ = c; 05422 *str = 0; 05423 if (strchr(term, c)) 05424 return 1; 05425 } 05426 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 4937 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().
04938 { 04939 int sent=0; 04940 int size; 04941 int res; 04942 int fd; 04943 fd = p->subs[index].zfd; 04944 while (len) { 04945 size = len; 04946 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 04947 size = (linear ? READ_SIZE * 2 : READ_SIZE); 04948 res = write(fd, buf, size); 04949 if (res != size) { 04950 if (option_debug) 04951 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 04952 return sent; 04953 } 04954 len -= size; 04955 buf += size; 04956 } 04957 return sent; 04958 }
static int pri_active_dchan_fd | ( | struct zt_pri * | pri | ) | [inline, static] |
static int pri_assign_bearer | ( | struct zt_pvt * | crv, | |
struct zt_pri * | pri, | |||
struct zt_pvt * | bearer | |||
) | [inline, static] |
Referenced by zt_request().
static int pri_find_dchan | ( | struct zt_pri * | pri | ) | [static] |
static int pri_is_up | ( | struct zt_pri * | pri | ) | [inline, static] |
static int process_zap | ( | struct zt_chan_conf * | confp, | |
struct ast_variable * | v, | |||
int | reload, | |||
int | skipchannels | |||
) | [static] |
Definition at line 10655 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::busycompare, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::busyfuzziness, zt_pvt::busyquietlength, zt_pvt::busytonelength, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, global_jbconf, zt_pvt::group, zt_pvt::hanguponpolarityswitch, HAVE_PRI, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, zt_pvt::immediate, zt_pvt::language, ast_variable::lineno, LOG_ERROR, zt_pvt::mailbox, MAX_CHANLIST_LEN, zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pulse, zt_pvt::radio, READ_SIZE, zt_pvt::restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::rxgain, zt_pvt::sendcalleridafter, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, zt_pvt::silencethreshold, 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().
10656 { 10657 struct zt_pvt *tmp; 10658 char *ringc; /* temporary string for parsing the dring number. */ 10659 int y; 10660 int found_pseudo = 0; 10661 char zapchan[MAX_CHANLIST_LEN] = {}; 10662 10663 for (; v; v = v->next) { 10664 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 10665 continue; 10666 10667 /* Create the interface list */ 10668 if (!strcasecmp(v->name, "channel") 10669 #ifdef HAVE_PRI 10670 || !strcasecmp(v->name, "crv") 10671 #endif 10672 ) { 10673 int iscrv; 10674 if (skipchannels) 10675 continue; 10676 iscrv = !strcasecmp(v->name, "crv"); 10677 if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 10678 return -1; 10679 } else if (!strcasecmp(v->name, "zapchan")) { 10680 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 10681 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 10682 if (ast_true(v->value)) 10683 confp->chan.usedistinctiveringdetection = 1; 10684 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 10685 if (ast_true(v->value)) 10686 distinctiveringaftercid = 1; 10687 } else if (!strcasecmp(v->name, "dring1context")) { 10688 ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData)); 10689 } else if (!strcasecmp(v->name, "dring2context")) { 10690 ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData)); 10691 } else if (!strcasecmp(v->name, "dring3context")) { 10692 ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData)); 10693 } else if (!strcasecmp(v->name, "dring1")) { 10694 ringc = v->value; 10695 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 10696 } else if (!strcasecmp(v->name, "dring2")) { 10697 ringc = v->value; 10698 sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 10699 } else if (!strcasecmp(v->name, "dring3")) { 10700 ringc = v->value; 10701 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 10702 } else if (!strcasecmp(v->name, "usecallerid")) { 10703 confp->chan.use_callerid = ast_true(v->value); 10704 } else if (!strcasecmp(v->name, "cidsignalling")) { 10705 if (!strcasecmp(v->value, "bell")) 10706 confp->chan.cid_signalling = CID_SIG_BELL; 10707 else if (!strcasecmp(v->value, "v23")) 10708 confp->chan.cid_signalling = CID_SIG_V23; 10709 else if (!strcasecmp(v->value, "dtmf")) 10710 confp->chan.cid_signalling = CID_SIG_DTMF; 10711 else if (!strcasecmp(v->value, "smdi")) 10712 confp->chan.cid_signalling = CID_SIG_SMDI; 10713 else if (!strcasecmp(v->value, "v23_jp")) 10714 confp->chan.cid_signalling = CID_SIG_V23_JP; 10715 else if (ast_true(v->value)) 10716 confp->chan.cid_signalling = CID_SIG_BELL; 10717 } else if (!strcasecmp(v->name, "cidstart")) { 10718 if (!strcasecmp(v->value, "ring")) 10719 confp->chan.cid_start = CID_START_RING; 10720 else if (!strcasecmp(v->value, "polarity")) 10721 confp->chan.cid_start = CID_START_POLARITY; 10722 else if (ast_true(v->value)) 10723 confp->chan.cid_start = CID_START_RING; 10724 } else if (!strcasecmp(v->name, "threewaycalling")) { 10725 confp->chan.threewaycalling = ast_true(v->value); 10726 } else if (!strcasecmp(v->name, "cancallforward")) { 10727 confp->chan.cancallforward = ast_true(v->value); 10728 } else if (!strcasecmp(v->name, "relaxdtmf")) { 10729 if (ast_true(v->value)) 10730 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 10731 else 10732 confp->chan.dtmfrelax = 0; 10733 } else if (!strcasecmp(v->name, "mailbox")) { 10734 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 10735 } else if (!strcasecmp(v->name, "adsi")) { 10736 confp->chan.adsi = ast_true(v->value); 10737 } else if (!strcasecmp(v->name, "usesmdi")) { 10738 confp->chan.use_smdi = ast_true(v->value); 10739 } else if (!strcasecmp(v->name, "smdiport")) { 10740 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 10741 } else if (!strcasecmp(v->name, "transfer")) { 10742 confp->chan.transfer = ast_true(v->value); 10743 } else if (!strcasecmp(v->name, "canpark")) { 10744 confp->chan.canpark = ast_true(v->value); 10745 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 10746 confp->chan.echocanbridged = ast_true(v->value); 10747 } else if (!strcasecmp(v->name, "busydetect")) { 10748 confp->chan.busydetect = ast_true(v->value); 10749 } else if (!strcasecmp(v->name, "busycount")) { 10750 confp->chan.busycount = atoi(v->value); 10751 } else if (!strcasecmp(v->name, "silencethreshold")) { 10752 confp->chan.silencethreshold = atoi(v->value); 10753 } else if (!strcasecmp(v->name, "busycompare")) { 10754 confp->chan.busycompare = ast_true(v->value); 10755 } else if (!strcasecmp(v->name, "busypattern")) { 10756 int count = sscanf(v->value, "%d,%d", &confp->chan.busytonelength, &confp->chan.busyquietlength); 10757 if (count == 1) 10758 confp->chan.busyquietlength = 0; 10759 else if (count < 1) 10760 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength[,quietlength]\n"); 10761 } else if (!strcasecmp(v->name, "busyfuzziness")) { 10762 confp->chan.busyfuzziness = atoi(v->value); 10763 } else if (!strcasecmp(v->name, "callprogress")) { 10764 if (ast_true(v->value)) 10765 confp->chan.callprogress |= 1; 10766 else 10767 confp->chan.callprogress &= ~1; 10768 } else if (!strcasecmp(v->name, "faxdetect")) { 10769 if (!strcasecmp(v->value, "incoming")) { 10770 confp->chan.callprogress |= 4; 10771 confp->chan.callprogress &= ~2; 10772 } else if (!strcasecmp(v->value, "outgoing")) { 10773 confp->chan.callprogress &= ~4; 10774 confp->chan.callprogress |= 2; 10775 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 10776 confp->chan.callprogress |= 6; 10777 else 10778 confp->chan.callprogress &= ~6; 10779 } else if (!strcasecmp(v->name, "echocancel")) { 10780 if (!ast_strlen_zero(v->value)) { 10781 y = atoi(v->value); 10782 } else 10783 y = 0; 10784 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 10785 confp->chan.echocancel = y; 10786 else { 10787 confp->chan.echocancel = ast_true(v->value); 10788 if (confp->chan.echocancel) 10789 confp->chan.echocancel=128; 10790 } 10791 } else if (!strcasecmp(v->name, "echotraining")) { 10792 if (sscanf(v->value, "%d", &y) == 1) { 10793 if ((y < 10) || (y > 4000)) { 10794 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 10795 } else { 10796 confp->chan.echotraining = y; 10797 } 10798 } else if (ast_true(v->value)) { 10799 confp->chan.echotraining = 400; 10800 } else 10801 confp->chan.echotraining = 0; 10802 } else if (!strcasecmp(v->name, "hidecallerid")) { 10803 confp->chan.hidecallerid = ast_true(v->value); 10804 } else if (!strcasecmp(v->name, "hidecalleridname")) { 10805 confp->chan.hidecalleridname = ast_true(v->value); 10806 } else if (!strcasecmp(v->name, "pulsedial")) { 10807 confp->chan.pulse = ast_true(v->value); 10808 } else if (!strcasecmp(v->name, "callreturn")) { 10809 confp->chan.callreturn = ast_true(v->value); 10810 } else if (!strcasecmp(v->name, "callwaiting")) { 10811 confp->chan.callwaiting = ast_true(v->value); 10812 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 10813 confp->chan.callwaitingcallerid = ast_true(v->value); 10814 } else if (!strcasecmp(v->name, "context")) { 10815 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 10816 } else if (!strcasecmp(v->name, "language")) { 10817 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 10818 } else if (!strcasecmp(v->name, "progzone")) { 10819 ast_copy_string(progzone, v->value, sizeof(progzone)); 10820 } else if (!strcasecmp(v->name, "mohinterpret") 10821 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 10822 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 10823 } else if (!strcasecmp(v->name, "mohsuggest")) { 10824 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 10825 } else if (!strcasecmp(v->name, "stripmsd")) { 10826 confp->chan.stripmsd = atoi(v->value); 10827 } else if (!strcasecmp(v->name, "jitterbuffers")) { 10828 numbufs = atoi(v->value); 10829 } else if (!strcasecmp(v->name, "group")) { 10830 confp->chan.group = ast_get_group(v->value); 10831 } else if (!strcasecmp(v->name, "callgroup")) { 10832 confp->chan.callgroup = ast_get_group(v->value); 10833 } else if (!strcasecmp(v->name, "pickupgroup")) { 10834 confp->chan.pickupgroup = ast_get_group(v->value); 10835 } else if (!strcasecmp(v->name, "immediate")) { 10836 confp->chan.immediate = ast_true(v->value); 10837 } else if (!strcasecmp(v->name, "transfertobusy")) { 10838 confp->chan.transfertobusy = ast_true(v->value); 10839 } else if (!strcasecmp(v->name, "rxgain")) { 10840 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 10841 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 10842 } 10843 } else if (!strcasecmp(v->name, "txgain")) { 10844 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 10845 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 10846 } 10847 } else if (!strcasecmp(v->name, "tonezone")) { 10848 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 10849 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 10850 } 10851 } else if (!strcasecmp(v->name, "callerid")) { 10852 if (!strcasecmp(v->value, "asreceived")) { 10853 confp->chan.cid_num[0] = '\0'; 10854 confp->chan.cid_name[0] = '\0'; 10855 } else { 10856 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 10857 } 10858 } else if (!strcasecmp(v->name, "fullname")) { 10859 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 10860 } else if (!strcasecmp(v->name, "cid_number")) { 10861 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 10862 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 10863 confp->chan.zaptrcallerid = ast_true(v->value); 10864 } else if (!strcasecmp(v->name, "restrictcid")) { 10865 confp->chan.restrictcid = ast_true(v->value); 10866 } else if (!strcasecmp(v->name, "usecallingpres")) { 10867 confp->chan.use_callingpres = ast_true(v->value); 10868 } else if (!strcasecmp(v->name, "accountcode")) { 10869 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 10870 } else if (!strcasecmp(v->name, "amaflags")) { 10871 y = ast_cdr_amaflags2int(v->value); 10872 if (y < 0) 10873 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 10874 else 10875 confp->chan.amaflags = y; 10876 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 10877 confp->chan.polarityonanswerdelay = atoi(v->value); 10878 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 10879 confp->chan.answeronpolarityswitch = ast_true(v->value); 10880 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 10881 confp->chan.hanguponpolarityswitch = ast_true(v->value); 10882 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 10883 confp->chan.sendcalleridafter = atoi(v->value); 10884 } else if (!reload){ 10885 if (!strcasecmp(v->name, "signalling")) { 10886 confp->chan.outsigmod = -1; 10887 if (!strcasecmp(v->value, "em")) { 10888 confp->chan.sig = SIG_EM; 10889 } else if (!strcasecmp(v->value, "em_e1")) { 10890 confp->chan.sig = SIG_EM_E1; 10891 } else if (!strcasecmp(v->value, "em_w")) { 10892 confp->chan.sig = SIG_EMWINK; 10893 confp->chan.radio = 0; 10894 } else if (!strcasecmp(v->value, "fxs_ls")) { 10895 confp->chan.sig = SIG_FXSLS; 10896 confp->chan.radio = 0; 10897 } else if (!strcasecmp(v->value, "fxs_gs")) { 10898 confp->chan.sig = SIG_FXSGS; 10899 confp->chan.radio = 0; 10900 } else if (!strcasecmp(v->value, "fxs_ks")) { 10901 confp->chan.sig = SIG_FXSKS; 10902 confp->chan.radio = 0; 10903 } else if (!strcasecmp(v->value, "fxo_ls")) { 10904 confp->chan.sig = SIG_FXOLS; 10905 confp->chan.radio = 0; 10906 } else if (!strcasecmp(v->value, "fxo_gs")) { 10907 confp->chan.sig = SIG_FXOGS; 10908 confp->chan.radio = 0; 10909 } else if (!strcasecmp(v->value, "fxo_ks")) { 10910 confp->chan.sig = SIG_FXOKS; 10911 confp->chan.radio = 0; 10912 } else if (!strcasecmp(v->value, "fxs_rx")) { 10913 confp->chan.sig = SIG_FXSKS; 10914 confp->chan.radio = 1; 10915 } else if (!strcasecmp(v->value, "fxo_rx")) { 10916 confp->chan.sig = SIG_FXOLS; 10917 confp->chan.radio = 1; 10918 } else if (!strcasecmp(v->value, "fxs_tx")) { 10919 confp->chan.sig = SIG_FXSLS; 10920 confp->chan.radio = 1; 10921 } else if (!strcasecmp(v->value, "fxo_tx")) { 10922 confp->chan.sig = SIG_FXOGS; 10923 confp->chan.radio = 1; 10924 } else if (!strcasecmp(v->value, "em_rx")) { 10925 confp->chan.sig = SIG_EM; 10926 confp->chan.radio = 1; 10927 } else if (!strcasecmp(v->value, "em_tx")) { 10928 confp->chan.sig = SIG_EM; 10929 confp->chan.radio = 1; 10930 } else if (!strcasecmp(v->value, "em_rxtx")) { 10931 confp->chan.sig = SIG_EM; 10932 confp->chan.radio = 2; 10933 } else if (!strcasecmp(v->value, "em_txrx")) { 10934 confp->chan.sig = SIG_EM; 10935 confp->chan.radio = 2; 10936 } else if (!strcasecmp(v->value, "sf")) { 10937 confp->chan.sig = SIG_SF; 10938 confp->chan.radio = 0; 10939 } else if (!strcasecmp(v->value, "sf_w")) { 10940 confp->chan.sig = SIG_SFWINK; 10941 confp->chan.radio = 0; 10942 } else if (!strcasecmp(v->value, "sf_featd")) { 10943 confp->chan.sig = SIG_FEATD; 10944 confp->chan.radio = 0; 10945 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10946 confp->chan.sig = SIG_FEATDMF; 10947 confp->chan.radio = 0; 10948 } else if (!strcasecmp(v->value, "sf_featb")) { 10949 confp->chan.sig = SIG_SF_FEATB; 10950 confp->chan.radio = 0; 10951 } else if (!strcasecmp(v->value, "sf")) { 10952 confp->chan.sig = SIG_SF; 10953 confp->chan.radio = 0; 10954 } else if (!strcasecmp(v->value, "sf_rx")) { 10955 confp->chan.sig = SIG_SF; 10956 confp->chan.radio = 1; 10957 } else if (!strcasecmp(v->value, "sf_tx")) { 10958 confp->chan.sig = SIG_SF; 10959 confp->chan.radio = 1; 10960 } else if (!strcasecmp(v->value, "sf_rxtx")) { 10961 confp->chan.sig = SIG_SF; 10962 confp->chan.radio = 2; 10963 } else if (!strcasecmp(v->value, "sf_txrx")) { 10964 confp->chan.sig = SIG_SF; 10965 confp->chan.radio = 2; 10966 } else if (!strcasecmp(v->value, "featd")) { 10967 confp->chan.sig = SIG_FEATD; 10968 confp->chan.radio = 0; 10969 } else if (!strcasecmp(v->value, "featdmf")) { 10970 confp->chan.sig = SIG_FEATDMF; 10971 confp->chan.radio = 0; 10972 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10973 confp->chan.sig = SIG_FEATDMF_TA; 10974 confp->chan.radio = 0; 10975 } else if (!strcasecmp(v->value, "e911")) { 10976 confp->chan.sig = SIG_E911; 10977 confp->chan.radio = 0; 10978 } else if (!strcasecmp(v->value, "fgccama")) { 10979 confp->chan.sig = SIG_FGC_CAMA; 10980 confp->chan.radio = 0; 10981 } else if (!strcasecmp(v->value, "fgccamamf")) { 10982 confp->chan.sig = SIG_FGC_CAMAMF; 10983 confp->chan.radio = 0; 10984 } else if (!strcasecmp(v->value, "featb")) { 10985 confp->chan.sig = SIG_FEATB; 10986 confp->chan.radio = 0; 10987 #ifdef HAVE_PRI 10988 } else if (!strcasecmp(v->value, "pri_net")) { 10989 confp->chan.radio = 0; 10990 confp->chan.sig = SIG_PRI; 10991 confp->pri.nodetype = PRI_NETWORK; 10992 } else if (!strcasecmp(v->value, "pri_cpe")) { 10993 confp->chan.sig = SIG_PRI; 10994 confp->chan.radio = 0; 10995 confp->pri.nodetype = PRI_CPE; 10996 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 10997 confp->chan.sig = SIG_GR303FXOKS; 10998 confp->chan.radio = 0; 10999 confp->pri.nodetype = PRI_NETWORK; 11000 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 11001 confp->chan.sig = SIG_GR303FXSKS; 11002 confp->chan.radio = 0; 11003 confp->pri.nodetype = PRI_CPE; 11004 #endif 11005 } else { 11006 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 11007 } 11008 } else if (!strcasecmp(v->name, "outsignalling")) { 11009 if (!strcasecmp(v->value, "em")) { 11010 confp->chan.outsigmod = SIG_EM; 11011 } else if (!strcasecmp(v->value, "em_e1")) { 11012 confp->chan.outsigmod = SIG_EM_E1; 11013 } else if (!strcasecmp(v->value, "em_w")) { 11014 confp->chan.outsigmod = SIG_EMWINK; 11015 } else if (!strcasecmp(v->value, "sf")) { 11016 confp->chan.outsigmod = SIG_SF; 11017 } else if (!strcasecmp(v->value, "sf_w")) { 11018 confp->chan.outsigmod = SIG_SFWINK; 11019 } else if (!strcasecmp(v->value, "sf_featd")) { 11020 confp->chan.outsigmod = SIG_FEATD; 11021 } else if (!strcasecmp(v->value, "sf_featdmf")) { 11022 confp->chan.outsigmod = SIG_FEATDMF; 11023 } else if (!strcasecmp(v->value, "sf_featb")) { 11024 confp->chan.outsigmod = SIG_SF_FEATB; 11025 } else if (!strcasecmp(v->value, "sf")) { 11026 confp->chan.outsigmod = SIG_SF; 11027 } else if (!strcasecmp(v->value, "featd")) { 11028 confp->chan.outsigmod = SIG_FEATD; 11029 } else if (!strcasecmp(v->value, "featdmf")) { 11030 confp->chan.outsigmod = SIG_FEATDMF; 11031 } else if (!strcasecmp(v->value, "featdmf_ta")) { 11032 confp->chan.outsigmod = SIG_FEATDMF_TA; 11033 } else if (!strcasecmp(v->value, "e911")) { 11034 confp->chan.outsigmod = SIG_E911; 11035 } else if (!strcasecmp(v->value, "fgccama")) { 11036 confp->chan.outsigmod = SIG_FGC_CAMA; 11037 } else if (!strcasecmp(v->value, "fgccamamf")) { 11038 confp->chan.outsigmod = SIG_FGC_CAMAMF; 11039 } else if (!strcasecmp(v->value, "featb")) { 11040 confp->chan.outsigmod = SIG_FEATB; 11041 } else { 11042 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 11043 } 11044 #ifdef HAVE_PRI 11045 } else if (!strcasecmp(v->name, "pridialplan")) { 11046 if (!strcasecmp(v->value, "national")) { 11047 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 11048 } else if (!strcasecmp(v->value, "unknown")) { 11049 confp->pri.dialplan = PRI_UNKNOWN + 1; 11050 } else if (!strcasecmp(v->value, "private")) { 11051 confp->pri.dialplan = PRI_PRIVATE + 1; 11052 } else if (!strcasecmp(v->value, "international")) { 11053 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 11054 } else if (!strcasecmp(v->value, "local")) { 11055 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 11056 } else if (!strcasecmp(v->value, "dynamic")) { 11057 confp->pri.dialplan = -1; 11058 } else { 11059 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 11060 } 11061 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 11062 if (!strcasecmp(v->value, "national")) { 11063 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 11064 } else if (!strcasecmp(v->value, "unknown")) { 11065 confp->pri.localdialplan = PRI_UNKNOWN + 1; 11066 } else if (!strcasecmp(v->value, "private")) { 11067 confp->pri.localdialplan = PRI_PRIVATE + 1; 11068 } else if (!strcasecmp(v->value, "international")) { 11069 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 11070 } else if (!strcasecmp(v->value, "local")) { 11071 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 11072 } else if (!strcasecmp(v->value, "dynamic")) { 11073 confp->pri.localdialplan = -1; 11074 } else { 11075 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 11076 } 11077 } else if (!strcasecmp(v->name, "switchtype")) { 11078 if (!strcasecmp(v->value, "national")) 11079 confp->pri.switchtype = PRI_SWITCH_NI2; 11080 else if (!strcasecmp(v->value, "ni1")) 11081 confp->pri.switchtype = PRI_SWITCH_NI1; 11082 else if (!strcasecmp(v->value, "dms100")) 11083 confp->pri.switchtype = PRI_SWITCH_DMS100; 11084 else if (!strcasecmp(v->value, "4ess")) 11085 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 11086 else if (!strcasecmp(v->value, "5ess")) 11087 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 11088 else if (!strcasecmp(v->value, "euroisdn")) 11089 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 11090 else if (!strcasecmp(v->value, "qsig")) 11091 confp->pri.switchtype = PRI_SWITCH_QSIG; 11092 else { 11093 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 11094 return -1; 11095 } 11096 } else if (!strcasecmp(v->name, "nsf")) { 11097 if (!strcasecmp(v->value, "sdn")) 11098 confp->pri.nsf = PRI_NSF_SDN; 11099 else if (!strcasecmp(v->value, "megacom")) 11100 confp->pri.nsf = PRI_NSF_MEGACOM; 11101 else if (!strcasecmp(v->value, "tollfreemegacom")) 11102 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 11103 else if (!strcasecmp(v->value, "accunet")) 11104 confp->pri.nsf = PRI_NSF_ACCUNET; 11105 else if (!strcasecmp(v->value, "none")) 11106 confp->pri.nsf = PRI_NSF_NONE; 11107 else { 11108 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 11109 confp->pri.nsf = PRI_NSF_NONE; 11110 } 11111 } else if (!strcasecmp(v->name, "priindication")) { 11112 if (!strcasecmp(v->value, "outofband")) 11113 confp->chan.priindication_oob = 1; 11114 else if (!strcasecmp(v->value, "inband")) 11115 confp->chan.priindication_oob = 0; 11116 else 11117 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n", 11118 v->value, v->lineno); 11119 } else if (!strcasecmp(v->name, "priexclusive")) { 11120 confp->chan.priexclusive = ast_true(v->value); 11121 } else if (!strcasecmp(v->name, "internationalprefix")) { 11122 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 11123 } else if (!strcasecmp(v->name, "nationalprefix")) { 11124 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 11125 } else if (!strcasecmp(v->name, "localprefix")) { 11126 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 11127 } else if (!strcasecmp(v->name, "privateprefix")) { 11128 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 11129 } else if (!strcasecmp(v->name, "unknownprefix")) { 11130 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 11131 } else if (!strcasecmp(v->name, "resetinterval")) { 11132 if (!strcasecmp(v->value, "never")) 11133 confp->pri.resetinterval = -1; 11134 else if (atoi(v->value) >= 60) 11135 confp->pri.resetinterval = atoi(v->value); 11136 else 11137 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 11138 v->value, v->lineno); 11139 } else if (!strcasecmp(v->name, "minunused")) { 11140 confp->pri.minunused = atoi(v->value); 11141 } else if (!strcasecmp(v->name, "minidle")) { 11142 confp->pri.minidle = atoi(v->value); 11143 } else if (!strcasecmp(v->name, "idleext")) { 11144 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 11145 } else if (!strcasecmp(v->name, "idledial")) { 11146 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 11147 } else if (!strcasecmp(v->name, "overlapdial")) { 11148 confp->pri.overlapdial = ast_true(v->value); 11149 } else if (!strcasecmp(v->name, "pritimer")) { 11150 #ifdef PRI_GETSET_TIMERS 11151 char *timerc, *c; 11152 int timer, timeridx; 11153 c = v->value; 11154 timerc = strsep(&c, ","); 11155 if (timerc) { 11156 timer = atoi(c); 11157 if (!timer) 11158 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 11159 else { 11160 if ((timeridx = pri_timer2idx(timerc)) >= 0) 11161 pritimers[timeridx] = timer; 11162 else 11163 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 11164 } 11165 } else 11166 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 11167 11168 } else if (!strcasecmp(v->name, "facilityenable")) { 11169 confp->pri.facilityenable = ast_true(v->value); 11170 #endif /* PRI_GETSET_TIMERS */ 11171 #endif /* HAVE_PRI */ 11172 } else if (!strcasecmp(v->name, "cadence")) { 11173 /* setup to scan our argument */ 11174 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 11175 int i; 11176 struct zt_ring_cadence new_cadence; 11177 int cid_location = -1; 11178 int firstcadencepos = 0; 11179 char original_args[80]; 11180 int cadence_is_ok = 1; 11181 11182 ast_copy_string(original_args, v->value, sizeof(original_args)); 11183 /* 16 cadences allowed (8 pairs) */ 11184 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]); 11185 11186 /* Cadence must be even (on/off) */ 11187 if (element_count % 2 == 1) { 11188 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 11189 cadence_is_ok = 0; 11190 } 11191 11192 /* Ring cadences cannot be negative */ 11193 for (i = 0; i < element_count; i++) { 11194 if (c[i] == 0) { 11195 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 11196 cadence_is_ok = 0; 11197 break; 11198 } else if (c[i] < 0) { 11199 if (i % 2 == 1) { 11200 /* Silence duration, negative possibly okay */ 11201 if (cid_location == -1) { 11202 cid_location = i; 11203 c[i] *= -1; 11204 } else { 11205 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 11206 cadence_is_ok = 0; 11207 break; 11208 } 11209 } else { 11210 if (firstcadencepos == 0) { 11211 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 11212 /* duration will be passed negative to the zaptel driver */ 11213 } else { 11214 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 11215 cadence_is_ok = 0; 11216 break; 11217 } 11218 } 11219 } 11220 } 11221 11222 /* Substitute our scanned cadence */ 11223 for (i = 0; i < 16; i++) { 11224 new_cadence.ringcadence[i] = c[i]; 11225 } 11226 11227 if (cadence_is_ok) { 11228 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 11229 if (element_count < 2) { 11230 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 11231 } else { 11232 if (cid_location == -1) { 11233 /* user didn't say; default to first pause */ 11234 cid_location = 1; 11235 } else { 11236 /* convert element_index to cidrings value */ 11237 cid_location = (cid_location + 1) / 2; 11238 } 11239 /* ---we like their cadence; try to install it--- */ 11240 if (!user_has_defined_cadences++) 11241 /* this is the first user-defined cadence; clear the default user cadences */ 11242 num_cadence = 0; 11243 if ((num_cadence+1) >= NUM_CADENCE_MAX) 11244 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 11245 else { 11246 cadences[num_cadence] = new_cadence; 11247 cidrings[num_cadence++] = cid_location; 11248 if (option_verbose > 2) 11249 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 11250 } 11251 } 11252 } 11253 } else if (!strcasecmp(v->name, "ringtimeout")) { 11254 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 11255 } else if (!strcasecmp(v->name, "prewink")) { 11256 confp->timing.prewinktime = atoi(v->value); 11257 } else if (!strcasecmp(v->name, "preflash")) { 11258 confp->timing.preflashtime = atoi(v->value); 11259 } else if (!strcasecmp(v->name, "wink")) { 11260 confp->timing.winktime = atoi(v->value); 11261 } else if (!strcasecmp(v->name, "flash")) { 11262 confp->timing.flashtime = atoi(v->value); 11263 } else if (!strcasecmp(v->name, "start")) { 11264 confp->timing.starttime = atoi(v->value); 11265 } else if (!strcasecmp(v->name, "rxwink")) { 11266 confp->timing.rxwinktime = atoi(v->value); 11267 } else if (!strcasecmp(v->name, "rxflash")) { 11268 confp->timing.rxflashtime = atoi(v->value); 11269 } else if (!strcasecmp(v->name, "debounce")) { 11270 confp->timing.debouncetime = atoi(v->value); 11271 } else if (!strcasecmp(v->name, "toneduration")) { 11272 int toneduration; 11273 int ctlfd; 11274 int res; 11275 struct zt_dialparams dps; 11276 11277 ctlfd = open("/dev/zap/ctl", O_RDWR); 11278 if (ctlfd == -1) { 11279 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 11280 return -1; 11281 } 11282 11283 toneduration = atoi(v->value); 11284 if (toneduration > -1) { 11285 memset(&dps, 0, sizeof(dps)); 11286 11287 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 11288 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 11289 if (res < 0) { 11290 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 11291 return -1; 11292 } 11293 } 11294 close(ctlfd); 11295 } else if (!strcasecmp(v->name, "defaultcic")) { 11296 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 11297 } else if (!strcasecmp(v->name, "defaultozz")) { 11298 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 11299 } 11300 } else if (!skipchannels) 11301 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11302 } 11303 if (zapchan[0]) { 11304 /* The user has set 'zapchan' */ 11305 /*< \todo pass proper line number instead of 0 */ 11306 if (build_channels(confp, 0, zapchan, reload, 0, &found_pseudo)) { 11307 return -1; 11308 } 11309 } 11310 /*< \todo why check for the pseudo in the per-channel section. 11311 * Any actual use for manual setup of the pseudo channel? */ 11312 if (!found_pseudo && reload == 0) { 11313 /* Make sure pseudo isn't a member of any groups if 11314 we're automatically making it. */ 11315 11316 confp->chan.group = 0; 11317 confp->chan.callgroup = 0; 11318 confp->chan.pickupgroup = 0; 11319 11320 tmp = mkintf(CHAN_PSEUDO, confp, NULL, reload); 11321 11322 if (tmp) { 11323 if (option_verbose > 2) 11324 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 11325 } else { 11326 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 11327 } 11328 } 11329 return 0; 11330 }
static char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
static int reload | ( | void | ) | [static] |
Definition at line 11612 of file chan_zap.c.
References ast_log(), and setup_zap().
11613 { 11614 int res = 0; 11615 11616 res = setup_zap(1); 11617 if (res) { 11618 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 11619 return -1; 11620 } 11621 return 0; 11622 }
static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1361 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::confno, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_hangup().
01362 { 01363 ZT_CONFINFO zi; 01364 memset(&zi, 0, sizeof(zi)); 01365 p->confno = -1; 01366 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01367 if (p->subs[SUB_REAL].zfd > -1) { 01368 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01369 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01370 } 01371 return 0; 01372 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 7024 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.
07025 { 07026 pthread_attr_t attr; 07027 pthread_attr_init(&attr); 07028 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07029 /* If we're supposed to be stopped -- stay stopped */ 07030 if (monitor_thread == AST_PTHREADT_STOP) 07031 return 0; 07032 ast_mutex_lock(&monlock); 07033 if (monitor_thread == pthread_self()) { 07034 ast_mutex_unlock(&monlock); 07035 ast_log(LOG_WARNING, "Cannot kill myself\n"); 07036 return -1; 07037 } 07038 if (monitor_thread != AST_PTHREADT_NULL) { 07039 /* Wake up the thread */ 07040 pthread_kill(monitor_thread, SIGURG); 07041 } else { 07042 /* Start a new monitor */ 07043 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 07044 ast_mutex_unlock(&monlock); 07045 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 07046 pthread_attr_destroy(&attr); 07047 return -1; 07048 } 07049 } 07050 ast_mutex_unlock(&monlock); 07051 pthread_attr_destroy(&attr); 07052 return 0; 07053 }
static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1693 of file chan_zap.c.
References ast_log(), errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, and zt_pvt::subs.
Referenced by send_callerid(), zt_handle_event(), and zt_read().
01694 { 01695 int res; 01696 if (p->saveconf.confmode) { 01697 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01698 p->saveconf.confmode = 0; 01699 if (res) { 01700 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01701 return -1; 01702 } 01703 } 01704 if (option_debug) 01705 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01706 return 0; 01707 }
static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1620 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, and zt_pvt::txgain.
Referenced by ss_thread(), and zt_hangup().
01621 { 01622 int res; 01623 01624 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01625 if (res) { 01626 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01627 return -1; 01628 } 01629 01630 return 0; 01631 }
static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1665 of file chan_zap.c.
References ast_log(), errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, and zt_pvt::subs.
Referenced by zt_callwait(), and zt_handle_event().
01666 { 01667 struct zt_confinfo c; 01668 int res; 01669 if (p->saveconf.confmode) { 01670 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01671 return -1; 01672 } 01673 p->saveconf.chan = 0; 01674 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01675 if (res) { 01676 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01677 p->saveconf.confmode = 0; 01678 return -1; 01679 } 01680 c.chan = 0; 01681 c.confno = 0; 01682 c.confmode = ZT_CONF_NORMAL; 01683 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01684 if (res) { 01685 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01686 return -1; 01687 } 01688 if (option_debug) 01689 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01690 return 0; 01691 }
static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1731 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, and zt_setlinear().
Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().
01732 { 01733 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01734 int res; 01735 /* Take out of linear mode if necessary */ 01736 if (p->subs[SUB_REAL].linear) { 01737 p->subs[SUB_REAL].linear = 0; 01738 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01739 } 01740 while (p->cidpos < p->cidlen) { 01741 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01742 if (res < 0) { 01743 if (errno == EAGAIN) 01744 return 0; 01745 else { 01746 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01747 return -1; 01748 } 01749 } 01750 if (!res) 01751 return 0; 01752 p->cidpos += res; 01753 } 01754 free(p->cidspill); 01755 p->cidspill = NULL; 01756 if (p->callwaitcas) { 01757 /* Wait for CID/CW to expire */ 01758 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01759 } else 01760 restore_conference(p); 01761 return 0; 01762 }
static int send_cwcidspill | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1709 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().
01710 { 01711 p->callwaitcas = 0; 01712 p->cidcwexpire = 0; 01713 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 01714 return -1; 01715 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01716 /* Make sure we account for the end */ 01717 p->cidlen += READ_SIZE * 4; 01718 p->cidpos = 0; 01719 send_callerid(p); 01720 if (option_verbose > 2) 01721 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01722 return 0; 01723 }
static int set_actual_gain | ( | int | fd, | |
int | chan, | |||
float | rxgain, | |||
float | txgain, | |||
int | law | |||
) | [inline, static] |
Definition at line 1601 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), restore_gains(), and zt_call().
01602 { 01603 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01604 }
static int set_actual_rxgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1583 of file chan_zap.c.
References ast_log(), errno, fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01584 { 01585 struct zt_gains g; 01586 int res; 01587 01588 memset(&g, 0, sizeof(g)); 01589 g.chan = chan; 01590 res = ioctl(fd, ZT_GETGAINS, &g); 01591 if (res) { 01592 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01593 return res; 01594 } 01595 01596 fill_rxgain(&g, gain, law); 01597 01598 return ioctl(fd, ZT_SETGAINS, &g); 01599 }
static int set_actual_txgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1564 of file chan_zap.c.
References ast_log(), errno, fill_txgain(), LOG_DEBUG, and option_debug.
Referenced by set_actual_gain(), and zt_setoption().
01565 { 01566 struct zt_gains g; 01567 int res; 01568 01569 memset(&g, 0, sizeof(g)); 01570 g.chan = chan; 01571 res = ioctl(fd, ZT_GETGAINS, &g); 01572 if (res) { 01573 if (option_debug) 01574 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01575 return res; 01576 } 01577 01578 fill_txgain(&g, gain, law); 01579 01580 return ioctl(fd, ZT_SETGAINS, &g); 01581 }
static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 11332 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().
11333 { 11334 struct ast_config *cfg; 11335 struct ast_variable *v; 11336 struct zt_chan_conf conf = zt_chan_conf_default(); 11337 int res; 11338 11339 #ifdef HAVE_PRI 11340 char *c; 11341 int spanno; 11342 int i, x; 11343 int logicalspan; 11344 int trunkgroup; 11345 int dchannels[NUM_DCHANS]; 11346 #endif 11347 11348 cfg = ast_config_load(config); 11349 11350 /* Error if we have no config file */ 11351 if (!cfg) { 11352 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 11353 return 0; 11354 } 11355 11356 /* It's a little silly to lock it, but we mind as well just to be sure */ 11357 ast_mutex_lock(&iflock); 11358 #ifdef HAVE_PRI 11359 if (!reload) { 11360 /* Process trunkgroups first */ 11361 v = ast_variable_browse(cfg, "trunkgroups"); 11362 while (v) { 11363 if (!strcasecmp(v->name, "trunkgroup")) { 11364 trunkgroup = atoi(v->value); 11365 if (trunkgroup > 0) { 11366 if ((c = strchr(v->value, ','))) { 11367 i = 0; 11368 memset(dchannels, 0, sizeof(dchannels)); 11369 while (c && (i < NUM_DCHANS)) { 11370 dchannels[i] = atoi(c + 1); 11371 if (dchannels[i] < 0) { 11372 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); 11373 } else 11374 i++; 11375 c = strchr(c + 1, ','); 11376 } 11377 if (i) { 11378 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 11379 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); 11380 } else if (option_verbose > 1) 11381 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"); 11382 } else 11383 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 11384 } else 11385 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 11386 } else 11387 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 11388 } else if (!strcasecmp(v->name, "spanmap")) { 11389 spanno = atoi(v->value); 11390 if (spanno > 0) { 11391 if ((c = strchr(v->value, ','))) { 11392 trunkgroup = atoi(c + 1); 11393 if (trunkgroup > 0) { 11394 if ((c = strchr(c + 1, ','))) 11395 logicalspan = atoi(c + 1); 11396 else 11397 logicalspan = 0; 11398 if (logicalspan >= 0) { 11399 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 11400 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11401 } else if (option_verbose > 1) 11402 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11403 } else 11404 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 11405 } else 11406 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 11407 } else 11408 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 11409 } else 11410 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 11411 } else { 11412 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 11413 } 11414 v = v->next; 11415 } 11416 } 11417 #endif 11418 11419 /* Copy the default jb config over global_jbconf */ 11420 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 11421 11422 v = ast_variable_browse(cfg, "channels"); 11423 res = process_zap(&conf, v, reload, 0); 11424 ast_mutex_unlock(&iflock); 11425 ast_config_destroy(cfg); 11426 if (res) 11427 return res; 11428 cfg = ast_config_load("users.conf"); 11429 if (cfg) { 11430 char *cat; 11431 const char *chans; 11432 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 11433 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 11434 if (!strcasecmp(cat, "general")) 11435 continue; 11436 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 11437 if (!ast_strlen_zero(chans)) { 11438 struct zt_chan_conf sect_conf; 11439 memcpy(§_conf, &conf, sizeof(sect_conf)); 11440 11441 process_zap(§_conf, ast_variable_browse(cfg, cat), reload, 0); 11442 } 11443 } 11444 ast_config_destroy(cfg); 11445 } 11446 #ifdef HAVE_PRI 11447 if (!reload) { 11448 for (x = 0; x < NUM_SPANS; x++) { 11449 if (pris[x].pvts[0]) { 11450 if (start_pri(pris + x)) { 11451 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 11452 return -1; 11453 } else if (option_verbose > 1) 11454 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 11455 } 11456 } 11457 } 11458 #endif 11459 /* And start the monitor for the first time */ 11460 restart_monitor(); 11461 return 0; 11462 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5446 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().
05447 { 05448 struct ast_channel *chan = data; 05449 struct zt_pvt *p = chan->tech_pvt; 05450 char exten[AST_MAX_EXTENSION] = ""; 05451 char exten2[AST_MAX_EXTENSION] = ""; 05452 unsigned char buf[256]; 05453 char dtmfcid[300]; 05454 char dtmfbuf[300]; 05455 struct callerid_state *cs = NULL; 05456 char *name = NULL, *number = NULL; 05457 int distMatches; 05458 int curRingData[3]; 05459 int receivedRingT; 05460 int counter1; 05461 int counter; 05462 int samples = 0; 05463 struct ast_smdi_md_message *smdi_msg = NULL; 05464 int flags; 05465 int i; 05466 int timeout; 05467 int getforward = 0; 05468 char *s1, *s2; 05469 int len = 0; 05470 int res; 05471 int index; 05472 05473 /* in the bizarre case where the channel has become a zombie before we 05474 even get started here, abort safely 05475 */ 05476 if (!p) { 05477 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05478 ast_hangup(chan); 05479 return NULL; 05480 } 05481 05482 if (option_verbose > 2) 05483 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05484 index = zt_get_index(chan, p, 1); 05485 if (index < 0) { 05486 ast_log(LOG_WARNING, "Huh?\n"); 05487 ast_hangup(chan); 05488 return NULL; 05489 } 05490 if (p->dsp) 05491 ast_dsp_digitreset(p->dsp); 05492 switch (p->sig) { 05493 #ifdef HAVE_PRI 05494 case SIG_PRI: 05495 /* Now loop looking for an extension */ 05496 ast_copy_string(exten, p->exten, sizeof(exten)); 05497 len = strlen(exten); 05498 res = 0; 05499 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05500 if (len && !ast_ignore_pattern(chan->context, exten)) 05501 tone_zone_play_tone(p->subs[index].zfd, -1); 05502 else 05503 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05504 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05505 timeout = matchdigittimeout; 05506 else 05507 timeout = gendigittimeout; 05508 res = ast_waitfordigit(chan, timeout); 05509 if (res < 0) { 05510 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05511 ast_hangup(chan); 05512 return NULL; 05513 } else if (res) { 05514 exten[len++] = res; 05515 exten[len] = '\0'; 05516 } else 05517 break; 05518 } 05519 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05520 if (ast_strlen_zero(exten)) { 05521 if (option_verbose > 2) 05522 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05523 exten[0] = 's'; 05524 exten[1] = '\0'; 05525 } 05526 tone_zone_play_tone(p->subs[index].zfd, -1); 05527 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05528 /* Start the real PBX */ 05529 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05530 if (p->dsp) ast_dsp_digitreset(p->dsp); 05531 zt_enable_ec(p); 05532 ast_setstate(chan, AST_STATE_RING); 05533 res = ast_pbx_run(chan); 05534 if (res) { 05535 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05536 } 05537 } else { 05538 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05539 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05540 ast_hangup(chan); 05541 p->exten[0] = '\0'; 05542 /* Since we send release complete here, we won't get one */ 05543 p->call = NULL; 05544 } 05545 return NULL; 05546 break; 05547 #endif 05548 case SIG_FEATD: 05549 case SIG_FEATDMF: 05550 case SIG_FEATDMF_TA: 05551 case SIG_E911: 05552 case SIG_FGC_CAMAMF: 05553 case SIG_FEATB: 05554 case SIG_EMWINK: 05555 case SIG_SF_FEATD: 05556 case SIG_SF_FEATDMF: 05557 case SIG_SF_FEATB: 05558 case SIG_SFWINK: 05559 if (zt_wink(p, index)) 05560 return NULL; 05561 /* Fall through */ 05562 case SIG_EM: 05563 case SIG_EM_E1: 05564 case SIG_SF: 05565 case SIG_FGC_CAMA: 05566 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05567 if (p->dsp) 05568 ast_dsp_digitreset(p->dsp); 05569 /* set digit mode appropriately */ 05570 if (p->dsp) { 05571 if (NEED_MFDETECT(p)) 05572 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05573 else 05574 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05575 } 05576 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05577 /* Wait for the first digit only if immediate=no */ 05578 if (!p->immediate) 05579 /* Wait for the first digit (up to 5 seconds). */ 05580 res = ast_waitfordigit(chan, 5000); 05581 else 05582 res = 0; 05583 if (res > 0) { 05584 /* save first char */ 05585 dtmfbuf[0] = res; 05586 switch (p->sig) { 05587 case SIG_FEATD: 05588 case SIG_SF_FEATD: 05589 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05590 if (res > 0) 05591 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05592 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05593 break; 05594 case SIG_FEATDMF_TA: 05595 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05596 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05597 if (zt_wink(p, index)) return NULL; 05598 dtmfbuf[0] = 0; 05599 /* Wait for the first digit (up to 5 seconds). */ 05600 res = ast_waitfordigit(chan, 5000); 05601 if (res <= 0) break; 05602 dtmfbuf[0] = res; 05603 /* fall through intentionally */ 05604 case SIG_FEATDMF: 05605 case SIG_E911: 05606 case SIG_FGC_CAMAMF: 05607 case SIG_SF_FEATDMF: 05608 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05609 /* if international caca, do it again to get real ANO */ 05610 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05611 { 05612 if (zt_wink(p, index)) return NULL; 05613 dtmfbuf[0] = 0; 05614 /* Wait for the first digit (up to 5 seconds). */ 05615 res = ast_waitfordigit(chan, 5000); 05616 if (res <= 0) break; 05617 dtmfbuf[0] = res; 05618 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05619 } 05620 if (res > 0) { 05621 /* if E911, take off hook */ 05622 if (p->sig == SIG_E911) 05623 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05624 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05625 } 05626 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05627 break; 05628 case SIG_FEATB: 05629 case SIG_SF_FEATB: 05630 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05631 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05632 break; 05633 case SIG_EMWINK: 05634 /* if we received a '*', we are actually receiving Feature Group D 05635 dial syntax, so use that mode; otherwise, fall through to normal 05636 mode 05637 */ 05638 if (res == '*') { 05639 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05640 if (res > 0) 05641 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05642 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05643 break; 05644 } 05645 default: 05646 /* If we got the first digit, get the rest */ 05647 len = 1; 05648 dtmfbuf[len] = '\0'; 05649 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05650 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05651 timeout = matchdigittimeout; 05652 } else { 05653 timeout = gendigittimeout; 05654 } 05655 res = ast_waitfordigit(chan, timeout); 05656 if (res < 0) { 05657 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05658 ast_hangup(chan); 05659 return NULL; 05660 } else if (res) { 05661 dtmfbuf[len++] = res; 05662 dtmfbuf[len] = '\0'; 05663 } else { 05664 break; 05665 } 05666 } 05667 break; 05668 } 05669 } 05670 if (res == -1) { 05671 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05672 ast_hangup(chan); 05673 return NULL; 05674 } else if (res < 0) { 05675 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05676 ast_hangup(chan); 05677 return NULL; 05678 } 05679 05680 if (p->sig == SIG_FGC_CAMA) { 05681 char anibuf[100]; 05682 05683 if (ast_safe_sleep(chan,1000) == -1) { 05684 ast_hangup(chan); 05685 return NULL; 05686 } 05687 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05688 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05689 res = my_getsigstr(chan, anibuf, "#", 10000); 05690 if ((res > 0) && (strlen(anibuf) > 2)) { 05691 if (anibuf[strlen(anibuf) - 1] == '#') 05692 anibuf[strlen(anibuf) - 1] = 0; 05693 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05694 } 05695 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05696 } 05697 05698 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05699 if (ast_strlen_zero(exten)) 05700 ast_copy_string(exten, "s", sizeof(exten)); 05701 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05702 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05703 if (exten[0] == '*') { 05704 char *stringp=NULL; 05705 ast_copy_string(exten2, exten, sizeof(exten2)); 05706 /* Parse out extension and callerid */ 05707 stringp=exten2 +1; 05708 s1 = strsep(&stringp, "*"); 05709 s2 = strsep(&stringp, "*"); 05710 if (s2) { 05711 if (!ast_strlen_zero(p->cid_num)) 05712 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05713 else 05714 ast_set_callerid(chan, s1, NULL, s1); 05715 ast_copy_string(exten, s2, sizeof(exten)); 05716 } else 05717 ast_copy_string(exten, s1, sizeof(exten)); 05718 } else if (p->sig == SIG_FEATD) 05719 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05720 } 05721 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05722 if (exten[0] == '*') { 05723 char *stringp=NULL; 05724 ast_copy_string(exten2, exten, sizeof(exten2)); 05725 /* Parse out extension and callerid */ 05726 stringp=exten2 +1; 05727 s1 = strsep(&stringp, "#"); 05728 s2 = strsep(&stringp, "#"); 05729 if (s2) { 05730 if (!ast_strlen_zero(p->cid_num)) 05731 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05732 else 05733 if (*(s1 + 2)) 05734 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05735 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05736 } else 05737 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05738 } else 05739 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05740 } 05741 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05742 if (exten[0] == '*') { 05743 char *stringp=NULL; 05744 ast_copy_string(exten2, exten, sizeof(exten2)); 05745 /* Parse out extension and callerid */ 05746 stringp=exten2 +1; 05747 s1 = strsep(&stringp, "#"); 05748 s2 = strsep(&stringp, "#"); 05749 if (s2 && (*(s2 + 1) == '0')) { 05750 if (*(s2 + 2)) 05751 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05752 } 05753 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05754 else ast_copy_string(exten, "911", sizeof(exten)); 05755 } else 05756 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 05757 } 05758 if (p->sig == SIG_FEATB) { 05759 if (exten[0] == '*') { 05760 char *stringp=NULL; 05761 ast_copy_string(exten2, exten, sizeof(exten2)); 05762 /* Parse out extension and callerid */ 05763 stringp=exten2 +1; 05764 s1 = strsep(&stringp, "#"); 05765 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05766 } else 05767 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05768 } 05769 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05770 zt_wink(p, index); 05771 /* some switches require a minimum guard time between 05772 the last FGD wink and something that answers 05773 immediately. This ensures it */ 05774 if (ast_safe_sleep(chan,100)) return NULL; 05775 } 05776 zt_enable_ec(p); 05777 if (NEED_MFDETECT(p)) { 05778 if (p->dsp) { 05779 if (!p->hardwaredtmf) 05780 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05781 else { 05782 ast_dsp_free(p->dsp); 05783 p->dsp = NULL; 05784 } 05785 } 05786 } 05787 05788 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05789 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05790 if (p->dsp) ast_dsp_digitreset(p->dsp); 05791 res = ast_pbx_run(chan); 05792 if (res) { 05793 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05794 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05795 } 05796 return NULL; 05797 } else { 05798 if (option_verbose > 2) 05799 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05800 sleep(2); 05801 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05802 if (res < 0) 05803 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05804 else 05805 sleep(1); 05806 res = ast_streamfile(chan, "ss-noservice", chan->language); 05807 if (res >= 0) 05808 ast_waitstream(chan, ""); 05809 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05810 ast_hangup(chan); 05811 return NULL; 05812 } 05813 break; 05814 case SIG_FXOLS: 05815 case SIG_FXOGS: 05816 case SIG_FXOKS: 05817 /* Read the first digit */ 05818 timeout = firstdigittimeout; 05819 /* If starting a threeway call, never timeout on the first digit so someone 05820 can use flash-hook as a "hold" feature */ 05821 if (p->subs[SUB_THREEWAY].owner) 05822 timeout = 999999; 05823 while (len < AST_MAX_EXTENSION-1) { 05824 /* Read digit unless it's supposed to be immediate, in which case the 05825 only answer is 's' */ 05826 if (p->immediate) 05827 res = 's'; 05828 else 05829 res = ast_waitfordigit(chan, timeout); 05830 timeout = 0; 05831 if (res < 0) { 05832 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05833 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05834 ast_hangup(chan); 05835 return NULL; 05836 } else if (res) { 05837 exten[len++]=res; 05838 exten[len] = '\0'; 05839 } 05840 if (!ast_ignore_pattern(chan->context, exten)) 05841 tone_zone_play_tone(p->subs[index].zfd, -1); 05842 else 05843 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05844 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05845 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05846 if (getforward) { 05847 /* Record this as the forwarding extension */ 05848 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05849 if (option_verbose > 2) 05850 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 05851 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05852 if (res) 05853 break; 05854 usleep(500000); 05855 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05856 sleep(1); 05857 memset(exten, 0, sizeof(exten)); 05858 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05859 len = 0; 05860 getforward = 0; 05861 } else { 05862 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05863 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05864 if (!ast_strlen_zero(p->cid_num)) { 05865 if (!p->hidecallerid) 05866 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05867 else 05868 ast_set_callerid(chan, NULL, NULL, p->cid_num); 05869 } 05870 if (!ast_strlen_zero(p->cid_name)) { 05871 if (!p->hidecallerid) 05872 ast_set_callerid(chan, NULL, p->cid_name, NULL); 05873 } 05874 ast_setstate(chan, AST_STATE_RING); 05875 zt_enable_ec(p); 05876 res = ast_pbx_run(chan); 05877 if (res) { 05878 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05879 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05880 } 05881 return NULL; 05882 } 05883 } else { 05884 /* It's a match, but they just typed a digit, and there is an ambiguous match, 05885 so just set the timeout to matchdigittimeout and wait some more */ 05886 timeout = matchdigittimeout; 05887 } 05888 } else if (res == 0) { 05889 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 05890 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05891 zt_wait_event(p->subs[index].zfd); 05892 ast_hangup(chan); 05893 return NULL; 05894 } else if (p->callwaiting && !strcmp(exten, "*70")) { 05895 if (option_verbose > 2) 05896 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 05897 /* Disable call waiting if enabled */ 05898 p->callwaiting = 0; 05899 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05900 if (res) { 05901 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05902 chan->name, strerror(errno)); 05903 } 05904 len = 0; 05905 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 05906 memset(exten, 0, sizeof(exten)); 05907 timeout = firstdigittimeout; 05908 05909 } else if (!strcmp(exten,ast_pickup_ext())) { 05910 /* Scan all channels and see if there are any 05911 * ringing channels that have call groups 05912 * that equal this channels pickup group 05913 */ 05914 if (index == SUB_REAL) { 05915 /* Switch us from Third call to Call Wait */ 05916 if (p->subs[SUB_THREEWAY].owner) { 05917 /* If you make a threeway call and the *8# a call, it should actually 05918 look like a callwait */ 05919 alloc_sub(p, SUB_CALLWAIT); 05920 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 05921 unalloc_sub(p, SUB_THREEWAY); 05922 } 05923 zt_enable_ec(p); 05924 if (ast_pickup_call(chan)) { 05925 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 05926 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05927 zt_wait_event(p->subs[index].zfd); 05928 } 05929 ast_hangup(chan); 05930 return NULL; 05931 } else { 05932 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 05933 ast_hangup(chan); 05934 return NULL; 05935 } 05936 05937 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 05938 if (option_verbose > 2) 05939 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 05940 /* Disable Caller*ID if enabled */ 05941 p->hidecallerid = 1; 05942 if (chan->cid.cid_num) 05943 free(chan->cid.cid_num); 05944 chan->cid.cid_num = NULL; 05945 if (chan->cid.cid_name) 05946 free(chan->cid.cid_name); 05947 chan->cid.cid_name = NULL; 05948 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05949 if (res) { 05950 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05951 chan->name, strerror(errno)); 05952 } 05953 len = 0; 05954 memset(exten, 0, sizeof(exten)); 05955 timeout = firstdigittimeout; 05956 } else if (p->callreturn && !strcmp(exten, "*69")) { 05957 res = 0; 05958 if (!ast_strlen_zero(p->lastcid_num)) { 05959 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 05960 } 05961 if (!res) 05962 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05963 break; 05964 } else if (!strcmp(exten, "*78")) { 05965 /* Do not disturb */ 05966 if (option_verbose > 2) 05967 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 05968 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05969 "Channel: Zap/%d\r\n" 05970 "Status: enabled\r\n", p->channel); 05971 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05972 p->dnd = 1; 05973 getforward = 0; 05974 memset(exten, 0, sizeof(exten)); 05975 len = 0; 05976 } else if (!strcmp(exten, "*79")) { 05977 /* Do not disturb */ 05978 if (option_verbose > 2) 05979 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 05980 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05981 "Channel: Zap/%d\r\n" 05982 "Status: disabled\r\n", p->channel); 05983 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05984 p->dnd = 0; 05985 getforward = 0; 05986 memset(exten, 0, sizeof(exten)); 05987 len = 0; 05988 } else if (p->cancallforward && !strcmp(exten, "*72")) { 05989 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05990 getforward = 1; 05991 memset(exten, 0, sizeof(exten)); 05992 len = 0; 05993 } else if (p->cancallforward && !strcmp(exten, "*73")) { 05994 if (option_verbose > 2) 05995 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 05996 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05997 memset(p->call_forward, 0, sizeof(p->call_forward)); 05998 getforward = 0; 05999 memset(exten, 0, sizeof(exten)); 06000 len = 0; 06001 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 06002 p->subs[SUB_THREEWAY].owner && 06003 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06004 /* This is a three way call, the main call being a real channel, 06005 and we're parking the first call. */ 06006 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 06007 if (option_verbose > 2) 06008 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 06009 break; 06010 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 06011 if (option_verbose > 2) 06012 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 06013 res = ast_db_put("blacklist", p->lastcid_num, "1"); 06014 if (!res) { 06015 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06016 memset(exten, 0, sizeof(exten)); 06017 len = 0; 06018 } 06019 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 06020 if (option_verbose > 2) 06021 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 06022 /* Enable Caller*ID if enabled */ 06023 p->hidecallerid = 0; 06024 if (chan->cid.cid_num) 06025 free(chan->cid.cid_num); 06026 chan->cid.cid_num = NULL; 06027 if (chan->cid.cid_name) 06028 free(chan->cid.cid_name); 06029 chan->cid.cid_name = NULL; 06030 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 06031 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06032 if (res) { 06033 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06034 chan->name, strerror(errno)); 06035 } 06036 len = 0; 06037 memset(exten, 0, sizeof(exten)); 06038 timeout = firstdigittimeout; 06039 } else if (!strcmp(exten, "*0")) { 06040 struct ast_channel *nbridge = 06041 p->subs[SUB_THREEWAY].owner; 06042 struct zt_pvt *pbridge = NULL; 06043 /* set up the private struct of the bridged one, if any */ 06044 if (nbridge && ast_bridged_channel(nbridge)) 06045 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 06046 if (nbridge && pbridge && 06047 (nbridge->tech == &zap_tech) && 06048 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 06049 ISTRUNK(pbridge)) { 06050 int func = ZT_FLASH; 06051 /* Clear out the dial buffer */ 06052 p->dop.dialstr[0] = '\0'; 06053 /* flash hookswitch */ 06054 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 06055 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 06056 nbridge->name, strerror(errno)); 06057 } 06058 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06059 unalloc_sub(p, SUB_THREEWAY); 06060 p->owner = p->subs[SUB_REAL].owner; 06061 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06062 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06063 ast_hangup(chan); 06064 return NULL; 06065 } else { 06066 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06067 zt_wait_event(p->subs[index].zfd); 06068 tone_zone_play_tone(p->subs[index].zfd, -1); 06069 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06070 unalloc_sub(p, SUB_THREEWAY); 06071 p->owner = p->subs[SUB_REAL].owner; 06072 ast_hangup(chan); 06073 return NULL; 06074 } 06075 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06076 ((exten[0] != '*') || (strlen(exten) > 2))) { 06077 if (option_debug) 06078 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); 06079 break; 06080 } 06081 if (!timeout) 06082 timeout = gendigittimeout; 06083 if (len && !ast_ignore_pattern(chan->context, exten)) 06084 tone_zone_play_tone(p->subs[index].zfd, -1); 06085 } 06086 break; 06087 case SIG_FXSLS: 06088 case SIG_FXSGS: 06089 case SIG_FXSKS: 06090 #ifdef HAVE_PRI 06091 if (p->pri) { 06092 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06093 struct ast_frame *f; 06094 int res; 06095 time_t start; 06096 06097 time(&start); 06098 ast_setstate(chan, AST_STATE_RING); 06099 while (time(NULL) < start + 3) { 06100 res = ast_waitfor(chan, 1000); 06101 if (res) { 06102 f = ast_read(chan); 06103 if (!f) { 06104 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06105 ast_hangup(chan); 06106 return NULL; 06107 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06108 res = 1; 06109 } else 06110 res = 0; 06111 ast_frfree(f); 06112 if (res) { 06113 ast_log(LOG_DEBUG, "Got ring!\n"); 06114 res = 0; 06115 break; 06116 } 06117 } 06118 } 06119 } 06120 #endif 06121 /* check for SMDI messages */ 06122 if (p->use_smdi && p->smdi_iface) { 06123 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06124 06125 if (smdi_msg != NULL) { 06126 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06127 06128 if (smdi_msg->type == 'B') 06129 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06130 else if (smdi_msg->type == 'N') 06131 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06132 06133 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06134 } else { 06135 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06136 } 06137 } 06138 06139 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06140 number = smdi_msg->calling_st; 06141 06142 /* If we want caller id, we're in a prering state due to a polarity reversal 06143 * and we're set to use a polarity reversal to trigger the start of caller id, 06144 * grab the caller id and wait for ringing to start... */ 06145 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06146 /* If set to use DTMF CID signalling, listen for DTMF */ 06147 if (p->cid_signalling == CID_SIG_DTMF) { 06148 int i = 0; 06149 cs = NULL; 06150 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06151 "channel %s\n", chan->name); 06152 zt_setlinear(p->subs[index].zfd, 0); 06153 res = 2000; 06154 for (;;) { 06155 struct ast_frame *f; 06156 res = ast_waitfor(chan, res); 06157 if (res <= 0) { 06158 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06159 "Exiting simple switch\n"); 06160 ast_hangup(chan); 06161 return NULL; 06162 } 06163 f = ast_read(chan); 06164 if (!f) 06165 break; 06166 if (f->frametype == AST_FRAME_DTMF) { 06167 dtmfbuf[i++] = f->subclass; 06168 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06169 res = 2000; 06170 } 06171 ast_frfree(f); 06172 if (chan->_state == AST_STATE_RING || 06173 chan->_state == AST_STATE_RINGING) 06174 break; /* Got ring */ 06175 } 06176 dtmfbuf[i] = '\0'; 06177 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06178 /* Got cid and ring. */ 06179 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06180 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06181 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06182 dtmfcid, flags); 06183 /* If first byte is NULL, we have no cid */ 06184 if (!ast_strlen_zero(dtmfcid)) 06185 number = dtmfcid; 06186 else 06187 number = NULL; 06188 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06189 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06190 cs = callerid_new(p->cid_signalling); 06191 if (cs) { 06192 samples = 0; 06193 #if 1 06194 bump_gains(p); 06195 #endif 06196 /* Take out of linear mode for Caller*ID processing */ 06197 zt_setlinear(p->subs[index].zfd, 0); 06198 06199 /* First we wait and listen for the Caller*ID */ 06200 for (;;) { 06201 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06202 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06203 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06204 callerid_free(cs); 06205 ast_hangup(chan); 06206 return NULL; 06207 } 06208 if (i & ZT_IOMUX_SIGEVENT) { 06209 res = zt_get_event(p->subs[index].zfd); 06210 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06211 06212 if (p->cid_signalling == CID_SIG_V23_JP) { 06213 #ifdef ZT_EVENT_RINGBEGIN 06214 if (res == ZT_EVENT_RINGBEGIN) { 06215 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06216 usleep(1); 06217 } 06218 #endif 06219 } else { 06220 res = 0; 06221 break; 06222 } 06223 } else if (i & ZT_IOMUX_READ) { 06224 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06225 if (res < 0) { 06226 if (errno != ELAST) { 06227 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06228 callerid_free(cs); 06229 ast_hangup(chan); 06230 return NULL; 06231 } 06232 break; 06233 } 06234 samples += res; 06235 06236 if (p->cid_signalling == CID_SIG_V23_JP) { 06237 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06238 } else { 06239 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06240 } 06241 06242 if (res < 0) { 06243 ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name); 06244 break; 06245 } else if (res) 06246 break; 06247 else if (samples > (8000 * 10)) 06248 break; 06249 } 06250 } 06251 if (res == 1) { 06252 callerid_get(cs, &name, &number, &flags); 06253 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06254 } 06255 06256 if (p->cid_signalling == CID_SIG_V23_JP) { 06257 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06258 usleep(1); 06259 res = 4000; 06260 } else { 06261 06262 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06263 res = 2000; 06264 } 06265 06266 for (;;) { 06267 struct ast_frame *f; 06268 res = ast_waitfor(chan, res); 06269 if (res <= 0) { 06270 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06271 "Exiting simple switch\n"); 06272 ast_hangup(chan); 06273 return NULL; 06274 } 06275 f = ast_read(chan); 06276 ast_frfree(f); 06277 if (chan->_state == AST_STATE_RING || 06278 chan->_state == AST_STATE_RINGING) 06279 break; /* Got ring */ 06280 } 06281 06282 /* We must have a ring by now, so, if configured, lets try to listen for 06283 * distinctive ringing */ 06284 if (p->usedistinctiveringdetection == 1) { 06285 len = 0; 06286 distMatches = 0; 06287 /* Clear the current ring data array so we dont have old data in it. */ 06288 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06289 curRingData[receivedRingT] = 0; 06290 receivedRingT = 0; 06291 counter = 0; 06292 counter1 = 0; 06293 /* Check to see if context is what it should be, if not set to be. */ 06294 if (strcmp(p->context,p->defcontext) != 0) { 06295 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06296 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06297 } 06298 06299 for (;;) { 06300 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06301 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06302 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06303 callerid_free(cs); 06304 ast_hangup(chan); 06305 return NULL; 06306 } 06307 if (i & ZT_IOMUX_SIGEVENT) { 06308 res = zt_get_event(p->subs[index].zfd); 06309 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06310 res = 0; 06311 /* Let us detect distinctive ring */ 06312 06313 curRingData[receivedRingT] = p->ringt; 06314 06315 if (p->ringt < p->ringt_base/2) 06316 break; 06317 /* Increment the ringT counter so we can match it against 06318 values in zapata.conf for distinctive ring */ 06319 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06320 break; 06321 } else if (i & ZT_IOMUX_READ) { 06322 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06323 if (res < 0) { 06324 if (errno != ELAST) { 06325 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06326 callerid_free(cs); 06327 ast_hangup(chan); 06328 return NULL; 06329 } 06330 break; 06331 } 06332 if (p->ringt) 06333 p->ringt--; 06334 if (p->ringt == 1) { 06335 res = -1; 06336 break; 06337 } 06338 } 06339 } 06340 if (option_verbose > 2) 06341 /* this only shows up if you have n of the dring patterns filled in */ 06342 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06343 06344 for (counter = 0; counter < 3; counter++) { 06345 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06346 channel */ 06347 distMatches = 0; 06348 for (counter1 = 0; counter1 < 3; counter1++) { 06349 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06350 (p->drings.ringnum[counter].ring[counter1]-10)) { 06351 distMatches++; 06352 } 06353 } 06354 if (distMatches == 3) { 06355 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06356 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06357 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06358 if (option_verbose > 2) 06359 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06360 break; 06361 } 06362 } 06363 } 06364 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06365 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06366 #if 1 06367 restore_gains(p); 06368 #endif 06369 } else 06370 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06371 } else { 06372 ast_log(LOG_WARNING, "Channel %s in prering " 06373 "state, but I have nothing to do. " 06374 "Terminating simple switch, should be " 06375 "restarted by the actual ring.\n", 06376 chan->name); 06377 ast_hangup(chan); 06378 return NULL; 06379 } 06380 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06381 /* FSK Bell202 callerID */ 06382 cs = callerid_new(p->cid_signalling); 06383 if (cs) { 06384 #if 1 06385 bump_gains(p); 06386 #endif 06387 samples = 0; 06388 len = 0; 06389 distMatches = 0; 06390 /* Clear the current ring data array so we dont have old data in it. */ 06391 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06392 curRingData[receivedRingT] = 0; 06393 receivedRingT = 0; 06394 counter = 0; 06395 counter1 = 0; 06396 /* Check to see if context is what it should be, if not set to be. */ 06397 if (strcmp(p->context,p->defcontext) != 0) { 06398 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06399 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06400 } 06401 06402 /* Take out of linear mode for Caller*ID processing */ 06403 zt_setlinear(p->subs[index].zfd, 0); 06404 for (;;) { 06405 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06406 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06407 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06408 callerid_free(cs); 06409 ast_hangup(chan); 06410 return NULL; 06411 } 06412 if (i & ZT_IOMUX_SIGEVENT) { 06413 res = zt_get_event(p->subs[index].zfd); 06414 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06415 /* If we get a PR event, they hung up while processing calerid */ 06416 if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 06417 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 06418 p->polarity = POLARITY_IDLE; 06419 callerid_free(cs); 06420 ast_hangup(chan); 06421 return NULL; 06422 } 06423 res = 0; 06424 /* Let us detect callerid when the telco uses distinctive ring */ 06425 06426 curRingData[receivedRingT] = p->ringt; 06427 06428 if (p->ringt < p->ringt_base/2) 06429 break; 06430 /* Increment the ringT counter so we can match it against 06431 values in zapata.conf for distinctive ring */ 06432 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06433 break; 06434 } else if (i & ZT_IOMUX_READ) { 06435 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06436 if (res < 0) { 06437 if (errno != ELAST) { 06438 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06439 callerid_free(cs); 06440 ast_hangup(chan); 06441 return NULL; 06442 } 06443 break; 06444 } 06445 if (p->ringt) 06446 p->ringt--; 06447 if (p->ringt == 1) { 06448 res = -1; 06449 break; 06450 } 06451 samples += res; 06452 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06453 if (res < 0) { 06454 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06455 break; 06456 } else if (res) 06457 break; 06458 else if (samples > (8000 * 10)) 06459 break; 06460 } 06461 } 06462 if (res == 1) { 06463 callerid_get(cs, &name, &number, &flags); 06464 if (option_debug) 06465 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06466 } 06467 if (distinctiveringaftercid == 1) { 06468 /* Clear the current ring data array so we dont have old data in it. */ 06469 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06470 curRingData[receivedRingT] = 0; 06471 } 06472 receivedRingT = 0; 06473 if (option_verbose > 2) 06474 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06475 for (;;) { 06476 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06477 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06478 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06479 callerid_free(cs); 06480 ast_hangup(chan); 06481 return NULL; 06482 } 06483 if (i & ZT_IOMUX_SIGEVENT) { 06484 res = zt_get_event(p->subs[index].zfd); 06485 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06486 res = 0; 06487 /* Let us detect callerid when the telco uses distinctive ring */ 06488 06489 curRingData[receivedRingT] = p->ringt; 06490 06491 if (p->ringt < p->ringt_base/2) 06492 break; 06493 /* Increment the ringT counter so we can match it against 06494 values in zapata.conf for distinctive ring */ 06495 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06496 break; 06497 } else if (i & ZT_IOMUX_READ) { 06498 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06499 if (res < 0) { 06500 if (errno != ELAST) { 06501 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06502 callerid_free(cs); 06503 ast_hangup(chan); 06504 return NULL; 06505 } 06506 break; 06507 } 06508 if (p->ringt) 06509 p->ringt--; 06510 if (p->ringt == 1) { 06511 res = -1; 06512 break; 06513 } 06514 } 06515 } 06516 } 06517 if (p->usedistinctiveringdetection == 1) { 06518 if (option_verbose > 2) 06519 /* this only shows up if you have n of the dring patterns filled in */ 06520 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06521 06522 for (counter = 0; counter < 3; counter++) { 06523 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06524 channel */ 06525 if (option_verbose > 2) 06526 /* this only shows up if you have n of the dring patterns filled in */ 06527 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06528 p->drings.ringnum[counter].ring[0], 06529 p->drings.ringnum[counter].ring[1], 06530 p->drings.ringnum[counter].ring[2]); 06531 distMatches = 0; 06532 for (counter1 = 0; counter1 < 3; counter1++) { 06533 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06534 (p->drings.ringnum[counter].ring[counter1]-10)) { 06535 distMatches++; 06536 } 06537 } 06538 if (distMatches == 3) { 06539 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06540 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06541 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06542 if (option_verbose > 2) 06543 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06544 break; 06545 } 06546 } 06547 } 06548 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06549 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06550 #if 1 06551 restore_gains(p); 06552 #endif 06553 if (res < 0) { 06554 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06555 } 06556 } else 06557 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06558 } 06559 else 06560 cs = NULL; 06561 06562 if (number) 06563 ast_shrink_phone_number(number); 06564 ast_set_callerid(chan, number, name, number); 06565 06566 if (smdi_msg) 06567 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06568 06569 if (cs) 06570 callerid_free(cs); 06571 06572 ast_setstate(chan, AST_STATE_RING); 06573 chan->rings = 1; 06574 p->ringt = p->ringt_base; 06575 res = ast_pbx_run(chan); 06576 if (res) { 06577 ast_hangup(chan); 06578 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06579 } 06580 return NULL; 06581 default: 06582 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06583 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06584 if (res < 0) 06585 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06586 } 06587 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06588 if (res < 0) 06589 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06590 ast_hangup(chan); 06591 return NULL; 06592 }
static void swap_subs | ( | struct zt_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 862 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().
00863 { 00864 int tchan; 00865 int tinthreeway; 00866 struct ast_channel *towner; 00867 00868 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 00869 00870 tchan = p->subs[a].chan; 00871 towner = p->subs[a].owner; 00872 tinthreeway = p->subs[a].inthreeway; 00873 00874 p->subs[a].chan = p->subs[b].chan; 00875 p->subs[a].owner = p->subs[b].owner; 00876 p->subs[a].inthreeway = p->subs[b].inthreeway; 00877 00878 p->subs[b].chan = tchan; 00879 p->subs[b].owner = towner; 00880 p->subs[b].inthreeway = tinthreeway; 00881 00882 if (p->subs[a].owner) 00883 p->subs[a].owner->fds[0] = p->subs[a].zfd; 00884 if (p->subs[b].owner) 00885 p->subs[b].owner->fds[0] = p->subs[b].zfd; 00886 wakeup_sub(p, a, NULL); 00887 wakeup_sub(p, b, NULL); 00888 }
static int unalloc_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, 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().
00989 { 00990 if (!x) { 00991 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 00992 return -1; 00993 } 00994 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 00995 if (p->subs[x].zfd > -1) { 00996 zt_close(p->subs[x].zfd); 00997 } 00998 p->subs[x].zfd = -1; 00999 p->subs[x].linear = 0; 01000 p->subs[x].chan = 0; 01001 p->subs[x].owner = NULL; 01002 p->subs[x].inthreeway = 0; 01003 p->polarity = POLARITY_IDLE; 01004 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 01005 return 0; 01006 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10552 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
10553 { 10554 #ifdef HAVE_PRI 10555 int y; 10556 for (y = 0; y < NUM_SPANS; y++) 10557 ast_mutex_destroy(&pris[y].lock); 10558 #endif 10559 return __unload_module(); 10560 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1374 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().
01375 { 01376 int needconf = 0; 01377 int x; 01378 int useslavenative; 01379 struct zt_pvt *slave = NULL; 01380 01381 useslavenative = isslavenative(p, &slave); 01382 /* Start with the obvious, general stuff */ 01383 for (x = 0; x < 3; x++) { 01384 /* Look for three way calls */ 01385 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01386 conf_add(p, &p->subs[x], x, 0); 01387 needconf++; 01388 } else { 01389 conf_del(p, &p->subs[x], x); 01390 } 01391 } 01392 /* If we have a slave, add him to our conference now. or DAX 01393 if this is slave native */ 01394 for (x = 0; x < MAX_SLAVES; x++) { 01395 if (p->slaves[x]) { 01396 if (useslavenative) 01397 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01398 else { 01399 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01400 needconf++; 01401 } 01402 } 01403 } 01404 /* If we're supposed to be in there, do so now */ 01405 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01406 if (useslavenative) 01407 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01408 else { 01409 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01410 needconf++; 01411 } 01412 } 01413 /* If we have a master, add ourselves to his conference */ 01414 if (p->master) { 01415 if (isslavenative(p->master, NULL)) { 01416 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01417 } else { 01418 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01419 } 01420 } 01421 if (!needconf) { 01422 /* Nobody is left (or should be left) in our conference. 01423 Kill it. */ 01424 p->confno = -1; 01425 } 01426 if (option_debug) 01427 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01428 return 0; 01429 }
static void wakeup_sub | ( | struct zt_pvt * | p, | |
int | a, | |||
void * | pri | |||
) | [static] |
Definition at line 806 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().
00808 { 00809 #ifdef HAVE_PRI 00810 if (pri) 00811 ast_mutex_unlock(&pri->lock); 00812 #endif 00813 for (;;) { 00814 if (p->subs[a].owner) { 00815 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00816 DEADLOCK_AVOIDANCE(&p->lock); 00817 } else { 00818 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 00819 ast_mutex_unlock(&p->subs[a].owner->lock); 00820 break; 00821 } 00822 } else 00823 break; 00824 } 00825 #ifdef HAVE_PRI 00826 if (pri) 00827 ast_mutex_lock(&pri->lock); 00828 #endif 00829 }
static int zap_destroy_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9894 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
09895 { 09896 int channel; 09897 09898 if (argc != 4) 09899 return RESULT_SHOWUSAGE; 09900 09901 channel = atoi(argv[3]); 09902 09903 return zap_destroy_channel_bynum(channel); 09904 }
static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6595 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().
06596 { 06597 struct zt_pvt *tmp = NULL; 06598 struct zt_pvt *prev = NULL; 06599 06600 tmp = iflist; 06601 while (tmp) { 06602 if (tmp->channel == channel) { 06603 destroy_channel(prev, tmp, 1); 06604 return RESULT_SUCCESS; 06605 } 06606 prev = tmp; 06607 tmp = tmp->next; 06608 } 06609 return RESULT_FAILURE; 06610 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 10301 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().
10302 { 10303 if (p) { 10304 switch (mode) { 10305 case TRANSFER: 10306 p->fake_event = ZT_EVENT_WINKFLASH; 10307 break; 10308 case HANGUP: 10309 p->fake_event = ZT_EVENT_ONHOOK; 10310 break; 10311 default: 10312 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 10313 } 10314 } 10315 return 0; 10316 }
Definition at line 834 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().
00836 { 00837 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00838 #ifdef HAVE_PRI 00839 if (pri) 00840 ast_mutex_unlock(&pri->lock); 00841 #endif 00842 for (;;) { 00843 if (p->owner) { 00844 if (ast_mutex_trylock(&p->owner->lock)) { 00845 DEADLOCK_AVOIDANCE(&p->lock); 00846 } else { 00847 ast_queue_frame(p->owner, f); 00848 ast_mutex_unlock(&p->owner->lock); 00849 break; 00850 } 00851 } else 00852 break; 00853 } 00854 #ifdef HAVE_PRI 00855 if (pri) 00856 ast_mutex_lock(&pri->lock); 00857 #endif 00858 }
static int zap_restart | ( | void | ) | [static] |
Definition at line 9907 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().
09908 { 09909 if (option_verbose > 0) 09910 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 09911 while (iflist) { 09912 if (option_debug) 09913 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 09914 /* Also updates iflist: */ 09915 destroy_channel(NULL, iflist, 1); 09916 } 09917 if (option_debug) 09918 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 09919 if (setup_zap(0) != 0) { 09920 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 09921 return 1; 09922 } 09923 return 0; 09924 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9926 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
09927 { 09928 if (argc != 2) { 09929 return RESULT_SHOWUSAGE; 09930 } 09931 09932 if (zap_restart() != 0) 09933 return RESULT_FAILURE; 09934 return RESULT_SUCCESS; 09935 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 10008 of file chan_zap.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::busyfuzziness, zt_pvt::busyquietlength, zt_pvt::busytonelength, zt_pvt::callprogress, 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, ISTRUNK, zt_pvt::law, zt_subchannel::linear, lock, zt_pvt::master, zt_pvt::next, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and zt_pvt::subs.
10009 { 10010 int channel; 10011 struct zt_pvt *tmp = NULL; 10012 ZT_CONFINFO ci; 10013 ZT_PARAMS ps; 10014 int x; 10015 ast_mutex_t *lock; 10016 struct zt_pvt *start; 10017 #ifdef HAVE_PRI 10018 char *c; 10019 int trunkgroup; 10020 struct zt_pri *pri=NULL; 10021 #endif 10022 10023 lock = &iflock; 10024 start = iflist; 10025 10026 if (argc != 4) 10027 return RESULT_SHOWUSAGE; 10028 #ifdef HAVE_PRI 10029 if ((c = strchr(argv[3], ':'))) { 10030 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 10031 return RESULT_SHOWUSAGE; 10032 if ((trunkgroup < 1) || (channel < 1)) 10033 return RESULT_SHOWUSAGE; 10034 for (x = 0; x < NUM_SPANS; x++) { 10035 if (pris[x].trunkgroup == trunkgroup) { 10036 pri = pris + x; 10037 break; 10038 } 10039 } 10040 if (pri) { 10041 start = pri->crvs; 10042 lock = &pri->lock; 10043 } else { 10044 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 10045 return RESULT_FAILURE; 10046 } 10047 } else 10048 #endif 10049 channel = atoi(argv[3]); 10050 10051 ast_mutex_lock(lock); 10052 tmp = start; 10053 while (tmp) { 10054 if (tmp->channel == channel) { 10055 #ifdef HAVE_PRI 10056 if (pri) 10057 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 10058 else 10059 #endif 10060 ast_cli(fd, "Channel: %d\n", tmp->channel); 10061 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 10062 ast_cli(fd, "Span: %d\n", tmp->span); 10063 ast_cli(fd, "Extension: %s\n", tmp->exten); 10064 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 10065 ast_cli(fd, "Context: %s\n", tmp->context); 10066 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 10067 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 10068 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 10069 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 10070 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 10071 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 10072 ast_cli(fd, "Radio: %d\n", tmp->radio); 10073 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 10074 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)" : ""); 10075 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)" : ""); 10076 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)" : ""); 10077 ast_cli(fd, "Confno: %d\n", tmp->confno); 10078 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 10079 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 10080 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 10081 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 10082 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 10083 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 10084 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 10085 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 10086 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 10087 if (tmp->master) 10088 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 10089 for (x = 0; x < MAX_SLAVES; x++) { 10090 if (tmp->slaves[x]) 10091 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 10092 } 10093 #ifdef HAVE_PRI 10094 if (tmp->pri) { 10095 ast_cli(fd, "PRI Flags: "); 10096 if (tmp->resetting) 10097 ast_cli(fd, "Resetting "); 10098 if (tmp->call) 10099 ast_cli(fd, "Call "); 10100 if (tmp->bearer) 10101 ast_cli(fd, "Bearer "); 10102 ast_cli(fd, "\n"); 10103 if (tmp->logicalspan) 10104 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 10105 else 10106 ast_cli(fd, "PRI Logical Span: Implicit\n"); 10107 } 10108 10109 #endif 10110 memset(&ci, 0, sizeof(ci)); 10111 ps.channo = tmp->channel; 10112 if (tmp->subs[SUB_REAL].zfd > -1) { 10113 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 10114 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 10115 } 10116 #ifdef ZT_GETCONFMUTE 10117 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 10118 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 10119 } 10120 #endif 10121 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 10122 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 10123 } else { 10124 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 10125 } 10126 } 10127 if (ISTRUNK(tmp)) { 10128 ast_cli(fd, "Call Progress: %s\n", tmp->callprogress ? "yes" : "no"); 10129 if (!ast_strlen_zero(progzone)) 10130 ast_cli(fd, "Progress Zone: %s\n", progzone); 10131 ast_cli(fd, "Busy Detect: %s\n", tmp->busydetect ? "yes" : "no"); 10132 if(tmp->busydetect) { 10133 ast_cli(fd, "Busy Count: %d\n", tmp->busycount); 10134 if(tmp->busytonelength > 0) { 10135 ast_cli(fd, "Busy Pattern:\n"); 10136 ast_cli(fd, " -- Tone Length: %6d ms\n", tmp->busytonelength); 10137 if (tmp->busyquietlength > 0) 10138 ast_cli(fd, " -- Quiet Length: %6d ms\n", tmp->busyquietlength); 10139 else 10140 ast_cli(fd, " -- Detect Tone Only\n"); 10141 if(tmp->busyfuzziness > 0) 10142 ast_cli(fd, "Busy Pattern Fuziness: %d\n", tmp->busyfuzziness); 10143 } 10144 } 10145 } 10146 ast_mutex_unlock(lock); 10147 return RESULT_SUCCESS; 10148 } 10149 tmp = tmp->next; 10150 } 10151 10152 ast_cli(fd, "Unable to find given channel %d\n", channel); 10153 ast_mutex_unlock(lock); 10154 return RESULT_FAILURE; 10155 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9947 of file chan_zap.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::context, zt_pvt::exten, FORMAT, FORMAT2, iflist, zt_pvt::language, lock, zt_pvt::mohinterpret, zt_pvt::next, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
09948 { 09949 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09950 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09951 struct zt_pvt *tmp = NULL; 09952 char tmps[20] = ""; 09953 ast_mutex_t *lock; 09954 struct zt_pvt *start; 09955 #ifdef HAVE_PRI 09956 int trunkgroup; 09957 struct zt_pri *pri = NULL; 09958 int x; 09959 #endif 09960 09961 lock = &iflock; 09962 start = iflist; 09963 09964 #ifdef HAVE_PRI 09965 if (argc == 4) { 09966 if ((trunkgroup = atoi(argv[3])) < 1) 09967 return RESULT_SHOWUSAGE; 09968 for (x = 0; x < NUM_SPANS; x++) { 09969 if (pris[x].trunkgroup == trunkgroup) { 09970 pri = pris + x; 09971 break; 09972 } 09973 } 09974 if (pri) { 09975 start = pri->crvs; 09976 lock = &pri->lock; 09977 } else { 09978 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09979 return RESULT_FAILURE; 09980 } 09981 } else 09982 #endif 09983 if (argc != 3) 09984 return RESULT_SHOWUSAGE; 09985 09986 ast_mutex_lock(lock); 09987 #ifdef HAVE_PRI 09988 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09989 #else 09990 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09991 #endif 09992 09993 tmp = start; 09994 while (tmp) { 09995 if (tmp->channel > 0) { 09996 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 09997 } else 09998 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 09999 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 10000 tmp = tmp->next; 10001 } 10002 ast_mutex_unlock(lock); 10003 return RESULT_SUCCESS; 10004 #undef FORMAT 10005 #undef FORMAT2 10006 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10188 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), errno, FORMAT, FORMAT2, and RESULT_FAILURE.
10188 { 10189 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 10190 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 10191 10192 int span; 10193 int res; 10194 char alarms[50]; 10195 10196 int ctl; 10197 ZT_SPANINFO s; 10198 10199 ctl = open("/dev/zap/ctl", O_RDWR); 10200 if (ctl < 0) { 10201 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 10202 ast_cli(fd, "No Zaptel interface found.\n"); 10203 return RESULT_FAILURE; 10204 } 10205 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 10206 10207 for (span = 1; span < ZT_MAX_SPANS; ++span) { 10208 s.spanno = span; 10209 res = ioctl(ctl, ZT_SPANSTAT, &s); 10210 if (res) { 10211 continue; 10212 } 10213 alarms[0] = '\0'; 10214 if (s.alarms > 0) { 10215 if (s.alarms & ZT_ALARM_BLUE) 10216 strcat(alarms, "BLU/"); 10217 if (s.alarms & ZT_ALARM_YELLOW) 10218 strcat(alarms, "YEL/"); 10219 if (s.alarms & ZT_ALARM_RED) 10220 strcat(alarms, "RED/"); 10221 if (s.alarms & ZT_ALARM_LOOPBACK) 10222 strcat(alarms, "LB/"); 10223 if (s.alarms & ZT_ALARM_RECOVER) 10224 strcat(alarms, "REC/"); 10225 if (s.alarms & ZT_ALARM_NOTOPEN) 10226 strcat(alarms, "NOP/"); 10227 if (!strlen(alarms)) 10228 strcat(alarms, "UUU/"); 10229 if (strlen(alarms)) { 10230 /* Strip trailing / */ 10231 alarms[strlen(alarms) - 1] = '\0'; 10232 } 10233 } else { 10234 if (s.numchans) 10235 strcpy(alarms, "OK"); 10236 else 10237 strcpy(alarms, "UNCONFIGURED"); 10238 } 10239 10240 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 10241 } 10242 close(ctl); 10243 10244 return RESULT_SUCCESS; 10245 #undef FORMAT 10246 #undef FORMAT2 10247 }
static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1184 of file chan_zap.c.
References SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01185 { 01186 static char buf[256]; 01187 switch (sig) { 01188 case SIG_EM: 01189 return "E & M Immediate"; 01190 case SIG_EMWINK: 01191 return "E & M Wink"; 01192 case SIG_EM_E1: 01193 return "E & M E1"; 01194 case SIG_FEATD: 01195 return "Feature Group D (DTMF)"; 01196 case SIG_FEATDMF: 01197 return "Feature Group D (MF)"; 01198 case SIG_FEATDMF_TA: 01199 return "Feature Groud D (MF) Tandem Access"; 01200 case SIG_FEATB: 01201 return "Feature Group B (MF)"; 01202 case SIG_E911: 01203 return "E911 (MF)"; 01204 case SIG_FGC_CAMA: 01205 return "FGC/CAMA (Dialpulse)"; 01206 case SIG_FGC_CAMAMF: 01207 return "FGC/CAMA (MF)"; 01208 case SIG_FXSLS: 01209 return "FXS Loopstart"; 01210 case SIG_FXSGS: 01211 return "FXS Groundstart"; 01212 case SIG_FXSKS: 01213 return "FXS Kewlstart"; 01214 case SIG_FXOLS: 01215 return "FXO Loopstart"; 01216 case SIG_FXOGS: 01217 return "FXO Groundstart"; 01218 case SIG_FXOKS: 01219 return "FXO Kewlstart"; 01220 case SIG_PRI: 01221 return "ISDN PRI"; 01222 case SIG_SF: 01223 return "SF (Tone) Immediate"; 01224 case SIG_SFWINK: 01225 return "SF (Tone) Wink"; 01226 case SIG_SF_FEATD: 01227 return "SF (Tone) with Feature Group D (DTMF)"; 01228 case SIG_SF_FEATDMF: 01229 return "SF (Tone) with Feature Group D (MF)"; 01230 case SIG_SF_FEATB: 01231 return "SF (Tone) with Feature Group B (MF)"; 01232 case SIG_GR303FXOKS: 01233 return "GR-303 with FXOKS"; 01234 case SIG_GR303FXSKS: 01235 return "GR-303 with FXSKS"; 01236 case 0: 01237 return "Pseudo"; 01238 default: 01239 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01240 return buf; 01241 } 01242 }
static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2759 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().
02760 { 02761 struct zt_pvt *p = ast->tech_pvt; 02762 int res = 0; 02763 int index; 02764 int oldstate = ast->_state; 02765 ast_setstate(ast, AST_STATE_UP); 02766 ast_mutex_lock(&p->lock); 02767 index = zt_get_index(ast, p, 0); 02768 if (index < 0) 02769 index = SUB_REAL; 02770 /* nothing to do if a radio channel */ 02771 if ((p->radio || (p->oprmode < 0))) { 02772 ast_mutex_unlock(&p->lock); 02773 return 0; 02774 } 02775 switch (p->sig) { 02776 case SIG_FXSLS: 02777 case SIG_FXSGS: 02778 case SIG_FXSKS: 02779 p->ringt = 0; 02780 /* Fall through */ 02781 case SIG_EM: 02782 case SIG_EM_E1: 02783 case SIG_EMWINK: 02784 case SIG_FEATD: 02785 case SIG_FEATDMF: 02786 case SIG_FEATDMF_TA: 02787 case SIG_E911: 02788 case SIG_FGC_CAMA: 02789 case SIG_FGC_CAMAMF: 02790 case SIG_FEATB: 02791 case SIG_SF: 02792 case SIG_SFWINK: 02793 case SIG_SF_FEATD: 02794 case SIG_SF_FEATDMF: 02795 case SIG_SF_FEATB: 02796 case SIG_FXOLS: 02797 case SIG_FXOGS: 02798 case SIG_FXOKS: 02799 /* Pick up the line */ 02800 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02801 if (p->hanguponpolarityswitch) { 02802 gettimeofday(&p->polaritydelaytv, NULL); 02803 } 02804 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02805 tone_zone_play_tone(p->subs[index].zfd, -1); 02806 p->dialing = 0; 02807 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02808 if (oldstate == AST_STATE_RINGING) { 02809 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02810 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02811 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02812 p->owner = p->subs[SUB_REAL].owner; 02813 } 02814 } 02815 if (p->sig & __ZT_SIG_FXS) { 02816 zt_enable_ec(p); 02817 zt_train_ec(p); 02818 } 02819 break; 02820 #ifdef HAVE_PRI 02821 case SIG_PRI: 02822 /* Send a pri acknowledge */ 02823 if (!pri_grab(p, p->pri)) { 02824 p->proceeding = 1; 02825 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02826 pri_rel(p->pri); 02827 } else { 02828 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02829 res = -1; 02830 } 02831 break; 02832 #endif 02833 case 0: 02834 ast_mutex_unlock(&p->lock); 02835 return 0; 02836 default: 02837 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02838 res = -1; 02839 } 02840 ast_mutex_unlock(&p->lock); 02841 return res; 02842 }
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 3166 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().
03167 { 03168 struct ast_channel *who; 03169 struct zt_pvt *p0, *p1, *op0, *op1; 03170 struct zt_pvt *master = NULL, *slave = NULL; 03171 struct ast_frame *f; 03172 int inconf = 0; 03173 int nothingok = 1; 03174 int ofd0, ofd1; 03175 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03176 int os0 = -1, os1 = -1; 03177 int priority = 0; 03178 struct ast_channel *oc0, *oc1; 03179 enum ast_bridge_result res; 03180 03181 #ifdef PRI_2BCT 03182 int triedtopribridge = 0; 03183 q931_call *q931c0 = NULL, *q931c1 = NULL; 03184 #endif 03185 03186 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03187 There is code below to handle it properly until DTMF is actually seen, 03188 but due to currently unresolved issues it's ignored... 03189 */ 03190 03191 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03192 return AST_BRIDGE_FAILED_NOWARN; 03193 03194 ast_mutex_lock(&c0->lock); 03195 while (ast_mutex_trylock(&c1->lock)) { 03196 DEADLOCK_AVOIDANCE(&c0->lock); 03197 } 03198 03199 p0 = c0->tech_pvt; 03200 p1 = c1->tech_pvt; 03201 /* cant do pseudo-channels here */ 03202 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03203 ast_mutex_unlock(&c0->lock); 03204 ast_mutex_unlock(&c1->lock); 03205 return AST_BRIDGE_FAILED_NOWARN; 03206 } 03207 03208 oi0 = zt_get_index(c0, p0, 0); 03209 oi1 = zt_get_index(c1, p1, 0); 03210 if ((oi0 < 0) || (oi1 < 0)) { 03211 ast_mutex_unlock(&c0->lock); 03212 ast_mutex_unlock(&c1->lock); 03213 return AST_BRIDGE_FAILED; 03214 } 03215 03216 op0 = p0 = c0->tech_pvt; 03217 op1 = p1 = c1->tech_pvt; 03218 ofd0 = c0->fds[0]; 03219 ofd1 = c1->fds[0]; 03220 oc0 = p0->owner; 03221 oc1 = p1->owner; 03222 03223 if (ast_mutex_trylock(&p0->lock)) { 03224 /* Don't block, due to potential for deadlock */ 03225 ast_mutex_unlock(&c0->lock); 03226 ast_mutex_unlock(&c1->lock); 03227 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03228 return AST_BRIDGE_RETRY; 03229 } 03230 if (ast_mutex_trylock(&p1->lock)) { 03231 /* Don't block, due to potential for deadlock */ 03232 ast_mutex_unlock(&p0->lock); 03233 ast_mutex_unlock(&c0->lock); 03234 ast_mutex_unlock(&c1->lock); 03235 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03236 return AST_BRIDGE_RETRY; 03237 } 03238 03239 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03240 if (p0->owner && p1->owner) { 03241 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03242 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03243 master = p0; 03244 slave = p1; 03245 inconf = 1; 03246 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03247 master = p1; 03248 slave = p0; 03249 inconf = 1; 03250 } else { 03251 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03252 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03253 p0->channel, 03254 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03255 p0->subs[SUB_REAL].inthreeway, p0->channel, 03256 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03257 p1->subs[SUB_REAL].inthreeway); 03258 } 03259 nothingok = 0; 03260 } 03261 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03262 if (p1->subs[SUB_THREEWAY].inthreeway) { 03263 master = p1; 03264 slave = p0; 03265 nothingok = 0; 03266 } 03267 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03268 if (p0->subs[SUB_THREEWAY].inthreeway) { 03269 master = p0; 03270 slave = p1; 03271 nothingok = 0; 03272 } 03273 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03274 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03275 don't put us in anything */ 03276 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03277 master = p1; 03278 slave = p0; 03279 nothingok = 0; 03280 } 03281 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03282 /* Same as previous */ 03283 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03284 master = p0; 03285 slave = p1; 03286 nothingok = 0; 03287 } 03288 } 03289 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03290 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03291 if (master && slave) { 03292 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03293 in an active threeway call with a channel that is ringing, we should 03294 indicate ringing. */ 03295 if ((oi1 == SUB_THREEWAY) && 03296 p1->subs[SUB_THREEWAY].inthreeway && 03297 p1->subs[SUB_REAL].owner && 03298 p1->subs[SUB_REAL].inthreeway && 03299 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03300 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03301 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03302 os1 = p1->subs[SUB_REAL].owner->_state; 03303 } else { 03304 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03305 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03306 } 03307 if ((oi0 == SUB_THREEWAY) && 03308 p0->subs[SUB_THREEWAY].inthreeway && 03309 p0->subs[SUB_REAL].owner && 03310 p0->subs[SUB_REAL].inthreeway && 03311 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03312 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03313 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03314 os0 = p0->subs[SUB_REAL].owner->_state; 03315 } else { 03316 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03317 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03318 } 03319 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03320 if (!p0->echocanbridged || !p1->echocanbridged) { 03321 /* Disable echo cancellation if appropriate */ 03322 zt_disable_ec(p0); 03323 zt_disable_ec(p1); 03324 } 03325 } 03326 zt_link(slave, master); 03327 master->inconference = inconf; 03328 } else if (!nothingok) 03329 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03330 03331 update_conf(p0); 03332 update_conf(p1); 03333 t0 = p0->subs[SUB_REAL].inthreeway; 03334 t1 = p1->subs[SUB_REAL].inthreeway; 03335 03336 ast_mutex_unlock(&p0->lock); 03337 ast_mutex_unlock(&p1->lock); 03338 03339 ast_mutex_unlock(&c0->lock); 03340 ast_mutex_unlock(&c1->lock); 03341 03342 /* Native bridge failed */ 03343 if ((!master || !slave) && !nothingok) { 03344 zt_enable_ec(p0); 03345 zt_enable_ec(p1); 03346 return AST_BRIDGE_FAILED; 03347 } 03348 03349 if (option_verbose > 2) 03350 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03351 03352 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03353 disable_dtmf_detect(op0); 03354 03355 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03356 disable_dtmf_detect(op1); 03357 03358 for (;;) { 03359 struct ast_channel *c0_priority[2] = {c0, c1}; 03360 struct ast_channel *c1_priority[2] = {c1, c0}; 03361 03362 /* Here's our main loop... Start by locking things, looking for private parts, 03363 and then balking if anything is wrong */ 03364 ast_mutex_lock(&c0->lock); 03365 while (ast_mutex_trylock(&c1->lock)) { 03366 DEADLOCK_AVOIDANCE(&c0->lock); 03367 } 03368 03369 p0 = c0->tech_pvt; 03370 p1 = c1->tech_pvt; 03371 03372 if (op0 == p0) 03373 i0 = zt_get_index(c0, p0, 1); 03374 if (op1 == p1) 03375 i1 = zt_get_index(c1, p1, 1); 03376 ast_mutex_unlock(&c0->lock); 03377 ast_mutex_unlock(&c1->lock); 03378 03379 if (!timeoutms || 03380 (op0 != p0) || 03381 (op1 != p1) || 03382 (ofd0 != c0->fds[0]) || 03383 (ofd1 != c1->fds[0]) || 03384 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03385 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03386 (oc0 != p0->owner) || 03387 (oc1 != p1->owner) || 03388 (t0 != p0->subs[SUB_REAL].inthreeway) || 03389 (t1 != p1->subs[SUB_REAL].inthreeway) || 03390 (oi0 != i0) || 03391 (oi1 != i1)) { 03392 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03393 op0->channel, oi0, op1->channel, oi1); 03394 res = AST_BRIDGE_RETRY; 03395 goto return_from_bridge; 03396 } 03397 03398 #ifdef PRI_2BCT 03399 q931c0 = p0->call; 03400 q931c1 = p1->call; 03401 if (p0->transfer && p1->transfer 03402 && q931c0 && q931c1 03403 && !triedtopribridge) { 03404 pri_channel_bridge(q931c0, q931c1); 03405 triedtopribridge = 1; 03406 } 03407 #endif 03408 03409 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03410 if (!who) { 03411 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03412 continue; 03413 } 03414 f = ast_read(who); 03415 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03416 *fo = f; 03417 *rc = who; 03418 res = AST_BRIDGE_COMPLETE; 03419 goto return_from_bridge; 03420 } 03421 if (f->frametype == AST_FRAME_DTMF) { 03422 if ((who == c0) && p0->pulsedial) { 03423 ast_write(c1, f); 03424 } else if ((who == c1) && p1->pulsedial) { 03425 ast_write(c0, f); 03426 } else { 03427 *fo = f; 03428 *rc = who; 03429 res = AST_BRIDGE_COMPLETE; 03430 goto return_from_bridge; 03431 } 03432 } 03433 ast_frfree(f); 03434 03435 /* Swap who gets priority */ 03436 priority = !priority; 03437 } 03438 03439 return_from_bridge: 03440 if (op0 == p0) 03441 zt_enable_ec(p0); 03442 03443 if (op1 == p1) 03444 zt_enable_ec(p1); 03445 03446 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03447 enable_dtmf_detect(op0); 03448 03449 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03450 enable_dtmf_detect(op1); 03451 03452 zt_unlink(slave, master, 1); 03453 03454 return res; 03455 }
static int zt_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 1792 of file chan_zap.c.
References ast_channel::_state, ast_callerid_generate(), AST_LAW, ast_log(), ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::callwaitrings, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, errno, zt_pvt::finaldial, free, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, IS_DIGITAL, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_pvt::law, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_CALLERID_SIZE, zt_subchannel::needbusy, zt_subchannel::needringing, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::owner, pbx_builtin_getvar_helper(), PRI_TRANS_CAP_DIGITAL, zt_pvt::priexclusive, zt_pvt::pulse, zt_pvt::radio, zt_pvt::rxgain, s, send_callerid(), zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::stripmsd, SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, ast_channel::transfercapability, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_subchannel::zfd, zt_callwait(), and zt_get_index().
01793 { 01794 struct zt_pvt *p = ast->tech_pvt; 01795 int x, res, index,mysig; 01796 char *c, *n, *l; 01797 #ifdef HAVE_PRI 01798 char *s = NULL; 01799 #endif 01800 char dest[256]; /* must be same length as p->dialdest */ 01801 ast_mutex_lock(&p->lock); 01802 ast_copy_string(dest, rdest, sizeof(dest)); 01803 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01804 if ((ast->_state == AST_STATE_BUSY)) { 01805 p->subs[SUB_REAL].needbusy = 1; 01806 ast_mutex_unlock(&p->lock); 01807 return 0; 01808 } 01809 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01810 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01811 ast_mutex_unlock(&p->lock); 01812 return -1; 01813 } 01814 p->dialednone = 0; 01815 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 01816 { 01817 /* Special pseudo -- automatically up */ 01818 ast_setstate(ast, AST_STATE_UP); 01819 ast_mutex_unlock(&p->lock); 01820 return 0; 01821 } 01822 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01823 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01824 if (res) 01825 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01826 p->outgoing = 1; 01827 01828 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01829 01830 mysig = p->sig; 01831 if (p->outsigmod > -1) 01832 mysig = p->outsigmod; 01833 01834 switch (mysig) { 01835 case SIG_FXOLS: 01836 case SIG_FXOGS: 01837 case SIG_FXOKS: 01838 if (p->owner == ast) { 01839 /* Normal ring, on hook */ 01840 01841 /* Don't send audio while on hook, until the call is answered */ 01842 p->dialing = 1; 01843 if (p->use_callerid) { 01844 /* Generate the Caller-ID spill if desired */ 01845 if (p->cidspill) { 01846 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01847 free(p->cidspill); 01848 } 01849 p->callwaitcas = 0; 01850 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01851 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 01852 p->cidpos = 0; 01853 send_callerid(p); 01854 } 01855 } 01856 /* Choose proper cadence */ 01857 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 01858 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1])) 01859 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 01860 p->cidrings = cidrings[p->distinctivering - 1]; 01861 } else { 01862 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 01863 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 01864 p->cidrings = p->sendcalleridafter; 01865 } 01866 01867 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 01868 c = strchr(dest, '/'); 01869 if (c) 01870 c++; 01871 if (c && (strlen(c) < p->stripmsd)) { 01872 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01873 c = NULL; 01874 } 01875 if (c) { 01876 p->dop.op = ZT_DIAL_OP_REPLACE; 01877 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 01878 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 01879 } else { 01880 p->dop.dialstr[0] = '\0'; 01881 } 01882 x = ZT_RING; 01883 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 01884 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 01885 ast_mutex_unlock(&p->lock); 01886 return -1; 01887 } 01888 p->dialing = 1; 01889 } else { 01890 /* Call waiting call */ 01891 p->callwaitrings = 0; 01892 if (ast->cid.cid_num) 01893 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 01894 else 01895 p->callwait_num[0] = '\0'; 01896 if (ast->cid.cid_name) 01897 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 01898 else 01899 p->callwait_name[0] = '\0'; 01900 /* Call waiting tone instead */ 01901 if (zt_callwait(ast)) { 01902 ast_mutex_unlock(&p->lock); 01903 return -1; 01904 } 01905 /* Make ring-back */ 01906 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 01907 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 01908 01909 } 01910 n = ast->cid.cid_name; 01911 l = ast->cid.cid_num; 01912 if (l) 01913 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 01914 else 01915 p->lastcid_num[0] = '\0'; 01916 if (n) 01917 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 01918 else 01919 p->lastcid_name[0] = '\0'; 01920 ast_setstate(ast, AST_STATE_RINGING); 01921 index = zt_get_index(ast, p, 0); 01922 if (index > -1) { 01923 p->subs[index].needringing = 1; 01924 } 01925 break; 01926 case SIG_FXSLS: 01927 case SIG_FXSGS: 01928 case SIG_FXSKS: 01929 case SIG_EMWINK: 01930 case SIG_EM: 01931 case SIG_EM_E1: 01932 case SIG_FEATD: 01933 case SIG_FEATDMF: 01934 case SIG_E911: 01935 case SIG_FGC_CAMA: 01936 case SIG_FGC_CAMAMF: 01937 case SIG_FEATB: 01938 case SIG_SFWINK: 01939 case SIG_SF: 01940 case SIG_SF_FEATD: 01941 case SIG_SF_FEATDMF: 01942 case SIG_FEATDMF_TA: 01943 case SIG_SF_FEATB: 01944 c = strchr(dest, '/'); 01945 if (c) 01946 c++; 01947 else 01948 c = ""; 01949 if (strlen(c) < p->stripmsd) { 01950 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01951 ast_mutex_unlock(&p->lock); 01952 return -1; 01953 } 01954 #ifdef HAVE_PRI 01955 /* Start the trunk, if not GR-303 */ 01956 if (!p->pri) { 01957 #endif 01958 x = ZT_START; 01959 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 01960 if (res < 0) { 01961 if (errno != EINPROGRESS) { 01962 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 01963 ast_mutex_unlock(&p->lock); 01964 return -1; 01965 } 01966 } 01967 #ifdef HAVE_PRI 01968 } 01969 #endif 01970 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 01971 p->dop.op = ZT_DIAL_OP_REPLACE; 01972 01973 c += p->stripmsd; 01974 01975 switch (mysig) { 01976 case SIG_FEATD: 01977 l = ast->cid.cid_num; 01978 if (l) 01979 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 01980 else 01981 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 01982 break; 01983 case SIG_FEATDMF: 01984 l = ast->cid.cid_num; 01985 if (l) 01986 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 01987 else 01988 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 01989 break; 01990 case SIG_FEATDMF_TA: 01991 { 01992 const char *cic, *ozz; 01993 01994 /* If you have to go through a Tandem Access point you need to use this */ 01995 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 01996 if (!ozz) 01997 ozz = defaultozz; 01998 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 01999 if (!cic) 02000 cic = defaultcic; 02001 if (!ozz || !cic) { 02002 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 02003 ast_mutex_unlock(&p->lock); 02004 return -1; 02005 } 02006 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 02007 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 02008 p->whichwink = 0; 02009 } 02010 break; 02011 case SIG_E911: 02012 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 02013 break; 02014 case SIG_FGC_CAMA: 02015 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 02016 break; 02017 case SIG_FGC_CAMAMF: 02018 case SIG_FEATB: 02019 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 02020 break; 02021 default: 02022 if (p->pulse) 02023 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 02024 else 02025 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 02026 break; 02027 } 02028 02029 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 02030 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02031 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02032 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02033 p->echobreak = 1; 02034 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02035 } else 02036 p->echobreak = 0; 02037 if (!res) { 02038 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 02039 x = ZT_ONHOOK; 02040 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02041 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 02042 ast_mutex_unlock(&p->lock); 02043 return -1; 02044 } 02045 } else 02046 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 02047 p->dialing = 1; 02048 if (ast_strlen_zero(c)) 02049 p->dialednone = 1; 02050 ast_setstate(ast, AST_STATE_DIALING); 02051 break; 02052 case 0: 02053 /* Special pseudo -- automatically up*/ 02054 ast_setstate(ast, AST_STATE_UP); 02055 break; 02056 case SIG_PRI: 02057 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02058 p->dialdest[0] = '\0'; 02059 break; 02060 default: 02061 ast_log(LOG_DEBUG, "not yet implemented\n"); 02062 ast_mutex_unlock(&p->lock); 02063 return -1; 02064 } 02065 #ifdef HAVE_PRI 02066 if (p->pri) { 02067 struct pri_sr *sr; 02068 #ifdef SUPPORT_USERUSER 02069 const char *useruser; 02070 #endif 02071 int pridialplan; 02072 int dp_strip; 02073 int prilocaldialplan; 02074 int ldp_strip; 02075 int exclusive; 02076 const char *rr_str; 02077 int redirect_reason; 02078 02079 c = strchr(dest, '/'); 02080 if (c) 02081 c++; 02082 else 02083 c = dest; 02084 02085 l = NULL; 02086 n = NULL; 02087 02088 if (!p->hidecallerid) { 02089 l = ast->cid.cid_num; 02090 if (!p->hidecalleridname) { 02091 n = ast->cid.cid_name; 02092 } 02093 } 02094 02095 02096 if (strlen(c) < p->stripmsd) { 02097 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02098 ast_mutex_unlock(&p->lock); 02099 return -1; 02100 } 02101 if (mysig != SIG_FXSKS) { 02102 p->dop.op = ZT_DIAL_OP_REPLACE; 02103 s = strchr(c + p->stripmsd, 'w'); 02104 if (s) { 02105 if (strlen(s) > 1) 02106 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02107 else 02108 p->dop.dialstr[0] = '\0'; 02109 *s = '\0'; 02110 } else { 02111 p->dop.dialstr[0] = '\0'; 02112 } 02113 } 02114 if (pri_grab(p, p->pri)) { 02115 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02116 ast_mutex_unlock(&p->lock); 02117 return -1; 02118 } 02119 if (!(p->call = pri_new_call(p->pri->pri))) { 02120 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02121 pri_rel(p->pri); 02122 ast_mutex_unlock(&p->lock); 02123 return -1; 02124 } 02125 if (!(sr = pri_sr_new())) { 02126 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02127 pri_destroycall(p->pri->pri, p->call); 02128 p->call = NULL; 02129 pri_rel(p->pri); 02130 ast_mutex_unlock(&p->lock); 02131 return -1; 02132 } 02133 if (p->bearer || (mysig == SIG_FXSKS)) { 02134 if (p->bearer) { 02135 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); 02136 p->bearer->call = p->call; 02137 } else 02138 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02139 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02140 } 02141 p->digital = IS_DIGITAL(ast->transfercapability); 02142 /* Add support for exclusive override */ 02143 if (p->priexclusive) 02144 exclusive = 1; 02145 else { 02146 /* otherwise, traditional behavior */ 02147 if (p->pri->nodetype == PRI_NETWORK) 02148 exclusive = 0; 02149 else 02150 exclusive = 1; 02151 } 02152 02153 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02154 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02155 (p->digital ? -1 : 02156 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); 02157 if (p->pri->facilityenable) 02158 pri_facility_enable(p->pri->pri); 02159 02160 if (option_verbose > 2) 02161 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02162 dp_strip = 0; 02163 pridialplan = p->pri->dialplan - 1; 02164 if (pridialplan == -2) { /* compute dynamically */ 02165 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02166 dp_strip = strlen(p->pri->internationalprefix); 02167 pridialplan = PRI_INTERNATIONAL_ISDN; 02168 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02169 dp_strip = strlen(p->pri->nationalprefix); 02170 pridialplan = PRI_NATIONAL_ISDN; 02171 } else { 02172 pridialplan = PRI_LOCAL_ISDN; 02173 } 02174 } 02175 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02176 02177 ldp_strip = 0; 02178 prilocaldialplan = p->pri->localdialplan - 1; 02179 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02180 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02181 ldp_strip = strlen(p->pri->internationalprefix); 02182 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02183 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02184 ldp_strip = strlen(p->pri->nationalprefix); 02185 prilocaldialplan = PRI_NATIONAL_ISDN; 02186 } else { 02187 prilocaldialplan = PRI_LOCAL_ISDN; 02188 } 02189 } 02190 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02191 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02192 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { 02193 if (!strcasecmp(rr_str, "UNKNOWN")) 02194 redirect_reason = 0; 02195 else if (!strcasecmp(rr_str, "BUSY")) 02196 redirect_reason = 1; 02197 else if (!strcasecmp(rr_str, "NO_REPLY")) 02198 redirect_reason = 2; 02199 else if (!strcasecmp(rr_str, "UNCONDITIONAL")) 02200 redirect_reason = 15; 02201 else 02202 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02203 } else 02204 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02205 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); 02206 02207 #ifdef SUPPORT_USERUSER 02208 /* User-user info */ 02209 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02210 02211 if (useruser) 02212 pri_sr_set_useruser(sr, useruser); 02213 #endif 02214 02215 if (pri_setup(p->pri->pri, p->call, sr)) { 02216 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02217 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02218 pri_rel(p->pri); 02219 ast_mutex_unlock(&p->lock); 02220 pri_sr_free(sr); 02221 return -1; 02222 } 02223 pri_sr_free(sr); 02224 ast_setstate(ast, AST_STATE_DIALING); 02225 pri_rel(p->pri); 02226 } 02227 #endif 02228 ast_mutex_unlock(&p->lock); 02229 return 0; 02230 }
static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1764 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().
01765 { 01766 struct zt_pvt *p = ast->tech_pvt; 01767 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01768 if (p->cidspill) { 01769 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01770 free(p->cidspill); 01771 } 01772 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01773 return -1; 01774 save_conference(p); 01775 /* Silence */ 01776 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01777 if (!p->callwaitrings && p->callwaitingcallerid) { 01778 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01779 p->callwaitcas = 1; 01780 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01781 } else { 01782 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01783 p->callwaitcas = 0; 01784 p->cidlen = 2400 + READ_SIZE * 4; 01785 } 01786 p->cidpos = 0; 01787 send_callerid(p); 01788 01789 return 0; 01790 }
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 604 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().
00604 { 00605 /* recall that if a field is not included here it is initialized 00606 * to 0 or equivalent 00607 */ 00608 struct zt_chan_conf conf = { 00609 #ifdef HAVE_PRI 00610 .pri = { 00611 .nsf = PRI_NSF_NONE, 00612 .switchtype = PRI_SWITCH_NI2, 00613 .dialplan = PRI_NATIONAL_ISDN + 1, 00614 .localdialplan = PRI_NATIONAL_ISDN + 1, 00615 .nodetype = PRI_CPE, 00616 00617 .minunused = 2, 00618 .idleext = "", 00619 .idledial = "", 00620 .internationalprefix = "", 00621 .nationalprefix = "", 00622 .localprefix = "", 00623 .privateprefix = "", 00624 .unknownprefix = "", 00625 00626 .resetinterval = 3600 00627 }, 00628 #endif 00629 .chan = { 00630 .context = "default", 00631 .cid_num = "", 00632 .cid_name = "", 00633 .mohinterpret = "default", 00634 .mohsuggest = "", 00635 .transfertobusy = 1, 00636 00637 .cid_signalling = CID_SIG_BELL, 00638 .cid_start = CID_START_RING, 00639 .zaptrcallerid = 0, 00640 .use_callerid = 1, 00641 .sig = -1, 00642 .outsigmod = -1, 00643 00644 .tonezone = -1, 00645 00646 .echocancel = 1, 00647 00648 .busycount = 3, 00649 .busycompare = 0, 00650 .busytonelength = 0, 00651 .busyquietlength = 0, 00652 .busyfuzziness = 0, 00653 .silencethreshold = 0, 00654 00655 .accountcode = "", 00656 00657 .mailbox = "", 00658 00659 00660 .polarityonanswerdelay = 600, 00661 00662 .sendcalleridafter = DEFAULT_CIDRINGS 00663 }, 00664 .timing = { 00665 .prewinktime = -1, 00666 .preflashtime = -1, 00667 .winktime = -1, 00668 .flashtime = -1, 00669 .starttime = -1, 00670 .rxwinktime = -1, 00671 .rxflashtime = -1, 00672 .debouncetime = -1 00673 }, 00674 .smdi_port = "/dev/ttyS0", 00675 }; 00676 00677 return conf; 00678 }
static void zt_close | ( | int | fd | ) | [static] |
Definition at line 937 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 1649 of file chan_zap.c.
References ast_log(), zt_pvt::channel, errno, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, and zt_pvt::subs.
Referenced by zt_handle_dtmfup(), zt_handle_event(), zt_hangup(), and zt_new().
01650 { 01651 int x, y, res; 01652 x = muted; 01653 if (p->sig == SIG_PRI) { 01654 y = 1; 01655 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01656 if (res) 01657 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01658 } 01659 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01660 if (res < 0) 01661 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01662 return res; 01663 }
static int zt_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1024 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, and zt_get_index().
01025 { 01026 struct zt_pvt *pvt; 01027 int index; 01028 int dtmf = -1; 01029 01030 pvt = chan->tech_pvt; 01031 01032 ast_mutex_lock(&pvt->lock); 01033 01034 index = zt_get_index(chan, pvt, 0); 01035 01036 if ((index != SUB_REAL) || !pvt->owner) 01037 goto out; 01038 01039 #ifdef HAVE_PRI 01040 if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) { 01041 if (pvt->setup_ack) { 01042 if (!pri_grab(pvt, pvt->pri)) { 01043 pri_information(pvt->pri->pri, pvt->call, digit); 01044 pri_rel(pvt->pri); 01045 } else 01046 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span); 01047 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 01048 int res; 01049 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01050 res = strlen(pvt->dialdest); 01051 pvt->dialdest[res++] = digit; 01052 pvt->dialdest[res] = '\0'; 01053 } 01054 goto out; 01055 } 01056 #endif 01057 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 01058 goto out; 01059 01060 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) { 01061 int res; 01062 ZT_DIAL_OPERATION zo = { 01063 .op = ZT_DIAL_OP_APPEND, 01064 .dialstr[0] = 'T', 01065 .dialstr[1] = digit, 01066 .dialstr[2] = 0, 01067 }; 01068 if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01069 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01070 else 01071 pvt->dialing = 1; 01072 } else { 01073 ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit); 01074 pvt->dialing = 1; 01075 pvt->begindigit = digit; 01076 } 01077 01078 out: 01079 ast_mutex_unlock(&pvt->lock); 01080 01081 return 0; 01082 }
static int zt_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1084 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, and zt_get_index().
01085 { 01086 struct zt_pvt *pvt; 01087 int res = 0; 01088 int index; 01089 int x; 01090 01091 pvt = chan->tech_pvt; 01092 01093 ast_mutex_lock(&pvt->lock); 01094 01095 index = zt_get_index(chan, pvt, 0); 01096 01097 if ((index != SUB_REAL) || !pvt->owner || pvt->pulse) 01098 goto out; 01099 01100 #ifdef HAVE_PRI 01101 /* This means that the digit was already sent via PRI signalling */ 01102 if (pvt->sig == SIG_PRI && !pvt->begindigit) 01103 goto out; 01104 #endif 01105 01106 if (pvt->begindigit) { 01107 x = -1; 01108 ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit); 01109 res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x); 01110 pvt->dialing = 0; 01111 pvt->begindigit = 0; 01112 } 01113 01114 out: 01115 ast_mutex_unlock(&pvt->lock); 01116 01117 return res; 01118 }
static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1481 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, and zt_pvt::subs.
Referenced by __zt_exception(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01482 { 01483 int x; 01484 int res; 01485 if (p->echocancel) { 01486 x = 0; 01487 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01488 if (res) 01489 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01490 else if (option_debug) 01491 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01492 } 01493 p->echocanon = 0; 01494 }
static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1431 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::sig, SIG_PRI, SUB_REAL, and zt_pvt::subs.
Referenced by __zt_exception(), handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_setoption().
01432 { 01433 int x; 01434 int res; 01435 if (!p) 01436 return; 01437 if (p->echocanon) { 01438 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01439 return; 01440 } 01441 if (p->digital) { 01442 ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n"); 01443 return; 01444 } 01445 if (p->echocancel) { 01446 if (p->sig == SIG_PRI) { 01447 x = 1; 01448 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01449 if (res) 01450 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno)); 01451 } 01452 x = p->echocancel; 01453 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01454 if (res) 01455 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 01456 else { 01457 p->echocanon = 1; 01458 if (option_debug) 01459 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01460 } 01461 } else if (option_debug) 01462 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01463 }
static struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4638 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), f, zt_pvt::lock, and ast_channel::tech_pvt.
04639 { 04640 struct zt_pvt *p = ast->tech_pvt; 04641 struct ast_frame *f; 04642 ast_mutex_lock(&p->lock); 04643 f = __zt_exception(ast); 04644 ast_mutex_unlock(&p->lock); 04645 return f; 04646 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3457 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, and zt_unlink().
03458 { 03459 struct zt_pvt *p = newchan->tech_pvt; 03460 int x; 03461 ast_mutex_lock(&p->lock); 03462 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03463 if (p->owner == oldchan) { 03464 p->owner = newchan; 03465 } 03466 for (x = 0; x < 3; x++) 03467 if (p->subs[x].owner == oldchan) { 03468 if (!x) 03469 zt_unlink(NULL, p, 0); 03470 p->subs[x].owner = newchan; 03471 } 03472 if (newchan->_state == AST_STATE_RINGING) 03473 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03474 update_conf(p); 03475 ast_mutex_unlock(&p->lock); 03476 return 0; 03477 }
static int zt_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3029 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.
03030 { 03031 struct zt_pvt *p = chan->tech_pvt; 03032 03033 if (!strcasecmp(data, "rxgain")) { 03034 ast_mutex_lock(&p->lock); 03035 snprintf(buf, len, "%f", p->rxgain); 03036 ast_mutex_unlock(&p->lock); 03037 } else if (!strcasecmp(data, "txgain")) { 03038 ast_mutex_lock(&p->lock); 03039 snprintf(buf, len, "%f", p->txgain); 03040 ast_mutex_unlock(&p->lock); 03041 } else { 03042 ast_copy_string(buf, "", len); 03043 } 03044 return 0; 03045 }
static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 257 of file chan_zap.c.
Referenced by __zt_exception(), ss_thread(), and zt_handle_event().
00258 { 00259 int j; 00260 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00261 return -1; 00262 return j; 00263 }
static int zt_get_index | ( | struct ast_channel * | ast, | |
struct zt_pvt * | p, | |||
int | nullok | |||
) | [static] |
Definition at line 786 of file chan_zap.c.
References ast_log(), LOG_WARNING, zt_subchannel::owner, and zt_pvt::subs.
Referenced by __zt_exception(), ss_thread(), zt_answer(), zt_bridge(), zt_call(), zt_digit_begin(), zt_digit_end(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), zt_sendtext(), zt_setoption(), and zt_write().
00787 { 00788 int res; 00789 if (p->subs[0].owner == ast) 00790 res = 0; 00791 else if (p->subs[1].owner == ast) 00792 res = 1; 00793 else if (p->subs[2].owner == ast) 00794 res = 2; 00795 else { 00796 res = -1; 00797 if (!nullok) 00798 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00799 } 00800 return res; 00801 }
static void zt_handle_dtmfup | ( | struct ast_channel * | ast, | |
int | index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 3625 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().
03626 { 03627 struct zt_pvt *p = ast->tech_pvt; 03628 struct ast_frame *f = *dest; 03629 03630 if (option_debug) 03631 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03632 03633 if (p->confirmanswer) { 03634 if (option_debug) 03635 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03636 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03637 of a DTMF digit */ 03638 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03639 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03640 *dest = &p->subs[index].f; 03641 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03642 p->confirmanswer = 0; 03643 } else if (p->callwaitcas) { 03644 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03645 if (option_debug) 03646 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03647 if (p->cidspill) 03648 free(p->cidspill); 03649 send_cwcidspill(p); 03650 } 03651 if ((f->subclass != 'm') && (f->subclass != 'u')) 03652 p->callwaitcas = 0; 03653 p->subs[index].f.frametype = AST_FRAME_NULL; 03654 p->subs[index].f.subclass = 0; 03655 *dest = &p->subs[index].f; 03656 } else if (f->subclass == 'f') { 03657 /* Fax tone -- Handle and return NULL */ 03658 if ((p->callprogress & 0x6) && !p->faxhandled) { 03659 p->faxhandled++; 03660 if (strcmp(ast->exten, "fax")) { 03661 const char *target_context = S_OR(ast->macrocontext, ast->context); 03662 03663 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03664 if (option_verbose > 2) 03665 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03666 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03667 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03668 if (ast_async_goto(ast, target_context, "fax", 1)) 03669 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03670 } else 03671 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03672 } else if (option_debug) 03673 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03674 } else if (option_debug) 03675 ast_log(LOG_DEBUG, "Fax already handled\n"); 03676 zt_confmute(p, 0); 03677 p->subs[index].f.frametype = AST_FRAME_NULL; 03678 p->subs[index].f.subclass = 0; 03679 *dest = &p->subs[index].f; 03680 } else if (f->subclass == 'm') { 03681 /* Confmute request */ 03682 zt_confmute(p, 1); 03683 p->subs[index].f.frametype = AST_FRAME_NULL; 03684 p->subs[index].f.subclass = 0; 03685 *dest = &p->subs[index].f; 03686 } else if (f->subclass == 'u') { 03687 /* Unmute */ 03688 zt_confmute(p, 0); 03689 p->subs[index].f.frametype = AST_FRAME_NULL; 03690 p->subs[index].f.subclass = 0; 03691 *dest = &p->subs[index].f; 03692 } else 03693 zt_confmute(p, 0); 03694 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3696 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, ast_channel::lock, zt_pvt::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().
03697 { 03698 int res, x; 03699 int index, mysig; 03700 char *c; 03701 struct zt_pvt *p = ast->tech_pvt; 03702 pthread_t threadid; 03703 pthread_attr_t attr; 03704 struct ast_channel *chan; 03705 struct ast_frame *f; 03706 03707 index = zt_get_index(ast, p, 0); 03708 mysig = p->sig; 03709 if (p->outsigmod > -1) 03710 mysig = p->outsigmod; 03711 p->subs[index].f.frametype = AST_FRAME_NULL; 03712 p->subs[index].f.subclass = 0; 03713 p->subs[index].f.datalen = 0; 03714 p->subs[index].f.samples = 0; 03715 p->subs[index].f.mallocd = 0; 03716 p->subs[index].f.offset = 0; 03717 p->subs[index].f.src = "zt_handle_event"; 03718 p->subs[index].f.data = NULL; 03719 f = &p->subs[index].f; 03720 03721 if (index < 0) 03722 return &p->subs[index].f; 03723 if (p->fake_event) { 03724 res = p->fake_event; 03725 p->fake_event = 0; 03726 } else 03727 res = zt_get_event(p->subs[index].zfd); 03728 03729 if (option_debug) 03730 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03731 03732 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03733 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 03734 03735 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03736 #ifdef HAVE_PRI 03737 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03738 /* absorb event */ 03739 } else { 03740 #endif 03741 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 03742 p->subs[index].f.subclass = res & 0xff; 03743 #ifdef HAVE_PRI 03744 } 03745 #endif 03746 zt_handle_dtmfup(ast, index, &f); 03747 return f; 03748 } 03749 03750 if (res & ZT_EVENT_DTMFDOWN) { 03751 if (option_debug) 03752 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03753 /* Mute conference */ 03754 zt_confmute(p, 1); 03755 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 03756 p->subs[index].f.subclass = res & 0xff; 03757 return &p->subs[index].f; 03758 } 03759 03760 switch (res) { 03761 #ifdef ZT_EVENT_EC_DISABLED 03762 case ZT_EVENT_EC_DISABLED: 03763 if (option_verbose > 2) 03764 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 03765 p->echocanon = 0; 03766 break; 03767 #endif 03768 case ZT_EVENT_BITSCHANGED: 03769 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03770 case ZT_EVENT_PULSE_START: 03771 /* Stop tone if there's a pulse start and the PBX isn't started */ 03772 if (!ast->pbx) 03773 tone_zone_play_tone(p->subs[index].zfd, -1); 03774 break; 03775 case ZT_EVENT_DIALCOMPLETE: 03776 if (p->inalarm) break; 03777 if ((p->radio || (p->oprmode < 0))) break; 03778 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03779 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03780 return NULL; 03781 } 03782 if (!x) { /* if not still dialing in driver */ 03783 zt_enable_ec(p); 03784 if (p->echobreak) { 03785 zt_train_ec(p); 03786 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03787 p->dop.op = ZT_DIAL_OP_REPLACE; 03788 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03789 p->echobreak = 0; 03790 } else { 03791 p->dialing = 0; 03792 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 03793 /* if thru with dialing after offhook */ 03794 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03795 ast_setstate(ast, AST_STATE_UP); 03796 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03797 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03798 break; 03799 } else { /* if to state wait for offhook to dial rest */ 03800 /* we now wait for off hook */ 03801 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03802 } 03803 } 03804 if (ast->_state == AST_STATE_DIALING) { 03805 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03806 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03807 } 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)))) { 03808 ast_setstate(ast, AST_STATE_RINGING); 03809 } else if (!p->answeronpolarityswitch) { 03810 ast_setstate(ast, AST_STATE_UP); 03811 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03812 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03813 /* If aops=0 and hops=1, this is necessary */ 03814 p->polarity = POLARITY_REV; 03815 } else { 03816 /* Start clean, so we can catch the change to REV polarity when party answers */ 03817 p->polarity = POLARITY_IDLE; 03818 } 03819 } 03820 } 03821 } 03822 break; 03823 case ZT_EVENT_ALARM: 03824 #ifdef HAVE_PRI 03825 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 03826 /* T309 is not enabled : hangup calls when alarm occurs */ 03827 if (p->call) { 03828 if (p->pri && p->pri->pri) { 03829 if (!pri_grab(p, p->pri)) { 03830 pri_hangup(p->pri->pri, p->call, -1); 03831 pri_destroycall(p->pri->pri, p->call); 03832 p->call = NULL; 03833 pri_rel(p->pri); 03834 } else 03835 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03836 } else 03837 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 03838 } 03839 if (p->owner) 03840 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03841 } 03842 if (p->bearer) 03843 p->bearer->inalarm = 1; 03844 else 03845 #endif 03846 p->inalarm = 1; 03847 res = get_alarms(p); 03848 do { 03849 const char *alarm_str = alarm2str(res); 03850 03851 /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 03852 * doesn't know what to do with it. Don't confuse users with log messages. */ 03853 if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { 03854 p->unknown_alarm = 1; 03855 break; 03856 } else { 03857 p->unknown_alarm = 0; 03858 } 03859 03860 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 03861 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 03862 "Alarm: %s\r\n" 03863 "Channel: %d\r\n", 03864 alarm_str, p->channel); 03865 } while (0); 03866 #ifdef HAVE_LIBPRI 03867 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 03868 /* fall through intentionally */ 03869 } else { 03870 break; 03871 } 03872 #endif 03873 case ZT_EVENT_ONHOOK: 03874 if (p->radio) { 03875 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03876 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 03877 break; 03878 } 03879 if (p->oprmode < 0) 03880 { 03881 if (p->oprmode != -1) break; 03882 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03883 { 03884 /* Make sure it starts ringing */ 03885 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03886 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 03887 save_conference(p->oprpeer); 03888 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03889 } 03890 break; 03891 } 03892 switch (p->sig) { 03893 case SIG_FXOLS: 03894 case SIG_FXOGS: 03895 case SIG_FXOKS: 03896 p->onhooktime = time(NULL); 03897 p->msgstate = -1; 03898 /* Check for some special conditions regarding call waiting */ 03899 if (index == SUB_REAL) { 03900 /* The normal line was hung up */ 03901 if (p->subs[SUB_CALLWAIT].owner) { 03902 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 03903 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 03904 if (option_verbose > 2) 03905 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 03906 unalloc_sub(p, SUB_CALLWAIT); 03907 #if 0 03908 p->subs[index].needanswer = 0; 03909 p->subs[index].needringing = 0; 03910 #endif 03911 p->callwaitingrepeat = 0; 03912 p->cidcwexpire = 0; 03913 p->owner = NULL; 03914 /* Don't start streaming audio yet if the incoming call isn't up yet */ 03915 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 03916 p->dialing = 1; 03917 zt_ring_phone(p); 03918 } else if (p->subs[SUB_THREEWAY].owner) { 03919 unsigned int mssinceflash; 03920 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 03921 the private structure -- not especially easy or clean */ 03922 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 03923 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 03924 ast_mutex_unlock(&p->lock); 03925 DEADLOCK_AVOIDANCE(&ast->lock); 03926 /* We can grab ast and p in that order, without worry. We should make sure 03927 nothing seriously bad has happened though like some sort of bizarre double 03928 masquerade! */ 03929 ast_mutex_lock(&p->lock); 03930 if (p->owner != ast) { 03931 ast_log(LOG_WARNING, "This isn't good...\n"); 03932 return NULL; 03933 } 03934 } 03935 if (!p->subs[SUB_THREEWAY].owner) { 03936 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 03937 return NULL; 03938 } 03939 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 03940 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 03941 if (mssinceflash < MIN_MS_SINCE_FLASH) { 03942 /* It hasn't been long enough since the last flashook. This is probably a bounce on 03943 hanging up. Hangup both channels now */ 03944 if (p->subs[SUB_THREEWAY].owner) 03945 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 03946 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03947 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 03948 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03949 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 03950 if (p->transfer) { 03951 /* In any case this isn't a threeway call anymore */ 03952 p->subs[SUB_REAL].inthreeway = 0; 03953 p->subs[SUB_THREEWAY].inthreeway = 0; 03954 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 03955 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 03956 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03957 /* Swap subs and dis-own channel */ 03958 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03959 p->owner = NULL; 03960 /* Ring the phone */ 03961 zt_ring_phone(p); 03962 } else { 03963 if ((res = attempt_transfer(p)) < 0) { 03964 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03965 if (p->subs[SUB_THREEWAY].owner) 03966 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03967 } else if (res) { 03968 /* Don't actually hang up at this point */ 03969 if (p->subs[SUB_THREEWAY].owner) 03970 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03971 break; 03972 } 03973 } 03974 } else { 03975 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03976 if (p->subs[SUB_THREEWAY].owner) 03977 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03978 } 03979 } else { 03980 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03981 /* Swap subs and dis-own channel */ 03982 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03983 p->owner = NULL; 03984 /* Ring the phone */ 03985 zt_ring_phone(p); 03986 } 03987 } 03988 } else { 03989 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 03990 } 03991 /* Fall through */ 03992 default: 03993 zt_disable_ec(p); 03994 return NULL; 03995 } 03996 break; 03997 case ZT_EVENT_RINGOFFHOOK: 03998 if (p->inalarm) break; 03999 if (p->oprmode < 0) 04000 { 04001 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04002 { 04003 /* Make sure it stops ringing */ 04004 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04005 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 04006 restore_conference(p->oprpeer); 04007 } 04008 break; 04009 } 04010 if (p->radio) 04011 { 04012 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04013 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04014 break; 04015 } 04016 /* for E911, its supposed to wait for offhook then dial 04017 the second half of the dial string */ 04018 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 04019 c = strchr(p->dialdest, '/'); 04020 if (c) 04021 c++; 04022 else 04023 c = p->dialdest; 04024 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 04025 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 04026 if (strlen(p->dop.dialstr) > 4) { 04027 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 04028 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 04029 p->echorest[sizeof(p->echorest) - 1] = '\0'; 04030 p->echobreak = 1; 04031 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 04032 } else 04033 p->echobreak = 0; 04034 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 04035 x = ZT_ONHOOK; 04036 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 04037 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 04038 return NULL; 04039 } 04040 p->dialing = 1; 04041 return &p->subs[index].f; 04042 } 04043 switch (p->sig) { 04044 case SIG_FXOLS: 04045 case SIG_FXOGS: 04046 case SIG_FXOKS: 04047 switch (ast->_state) { 04048 case AST_STATE_RINGING: 04049 zt_enable_ec(p); 04050 zt_train_ec(p); 04051 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04052 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04053 /* Make sure it stops ringing */ 04054 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04055 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 04056 if (p->cidspill) { 04057 /* Cancel any running CallerID spill */ 04058 free(p->cidspill); 04059 p->cidspill = NULL; 04060 } 04061 p->dialing = 0; 04062 p->callwaitcas = 0; 04063 if (p->confirmanswer) { 04064 /* Ignore answer if "confirm answer" is enabled */ 04065 p->subs[index].f.frametype = AST_FRAME_NULL; 04066 p->subs[index].f.subclass = 0; 04067 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04068 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04069 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04070 if (res < 0) { 04071 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04072 p->dop.dialstr[0] = '\0'; 04073 return NULL; 04074 } else { 04075 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04076 p->subs[index].f.frametype = AST_FRAME_NULL; 04077 p->subs[index].f.subclass = 0; 04078 p->dialing = 1; 04079 } 04080 p->dop.dialstr[0] = '\0'; 04081 ast_setstate(ast, AST_STATE_DIALING); 04082 } else 04083 ast_setstate(ast, AST_STATE_UP); 04084 return &p->subs[index].f; 04085 case AST_STATE_DOWN: 04086 ast_setstate(ast, AST_STATE_RING); 04087 ast->rings = 1; 04088 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04089 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04090 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04091 return &p->subs[index].f; 04092 case AST_STATE_UP: 04093 /* Make sure it stops ringing */ 04094 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04095 /* Okay -- probably call waiting*/ 04096 if (ast_bridged_channel(p->owner)) 04097 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04098 p->subs[index].needunhold = 1; 04099 break; 04100 case AST_STATE_RESERVED: 04101 /* Start up dialtone */ 04102 if (has_voicemail(p)) 04103 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04104 else 04105 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04106 break; 04107 default: 04108 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04109 } 04110 break; 04111 case SIG_FXSLS: 04112 case SIG_FXSGS: 04113 case SIG_FXSKS: 04114 if (ast->_state == AST_STATE_RING) { 04115 p->ringt = p->ringt_base; 04116 } 04117 04118 /* Fall through */ 04119 case SIG_EM: 04120 case SIG_EM_E1: 04121 case SIG_EMWINK: 04122 case SIG_FEATD: 04123 case SIG_FEATDMF: 04124 case SIG_FEATDMF_TA: 04125 case SIG_E911: 04126 case SIG_FGC_CAMA: 04127 case SIG_FGC_CAMAMF: 04128 case SIG_FEATB: 04129 case SIG_SF: 04130 case SIG_SFWINK: 04131 case SIG_SF_FEATD: 04132 case SIG_SF_FEATDMF: 04133 case SIG_SF_FEATB: 04134 if (ast->_state == AST_STATE_PRERING) 04135 ast_setstate(ast, AST_STATE_RING); 04136 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04137 if (option_debug) 04138 ast_log(LOG_DEBUG, "Ring detected\n"); 04139 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04140 p->subs[index].f.subclass = AST_CONTROL_RING; 04141 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04142 if (option_debug) 04143 ast_log(LOG_DEBUG, "Line answered\n"); 04144 if (p->confirmanswer) { 04145 p->subs[index].f.frametype = AST_FRAME_NULL; 04146 p->subs[index].f.subclass = 0; 04147 } else { 04148 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04149 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04150 ast_setstate(ast, AST_STATE_UP); 04151 } 04152 } else if (ast->_state != AST_STATE_RING) 04153 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04154 break; 04155 default: 04156 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04157 } 04158 break; 04159 #ifdef ZT_EVENT_RINGBEGIN 04160 case ZT_EVENT_RINGBEGIN: 04161 switch (p->sig) { 04162 case SIG_FXSLS: 04163 case SIG_FXSGS: 04164 case SIG_FXSKS: 04165 if (ast->_state == AST_STATE_RING) { 04166 p->ringt = p->ringt_base; 04167 } 04168 break; 04169 } 04170 break; 04171 #endif 04172 case ZT_EVENT_RINGEROFF: 04173 if (p->inalarm) break; 04174 if ((p->radio || (p->oprmode < 0))) break; 04175 ast->rings++; 04176 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04177 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04178 free(p->cidspill); 04179 p->cidspill = NULL; 04180 p->callwaitcas = 0; 04181 } 04182 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04183 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04184 break; 04185 case ZT_EVENT_RINGERON: 04186 break; 04187 case ZT_EVENT_NOALARM: 04188 p->inalarm = 0; 04189 #ifdef HAVE_PRI 04190 /* Extremely unlikely but just in case */ 04191 if (p->bearer) 04192 p->bearer->inalarm = 0; 04193 #endif 04194 if (!p->unknown_alarm) { 04195 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04196 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04197 "Channel: %d\r\n", p->channel); 04198 } else { 04199 p->unknown_alarm = 0; 04200 } 04201 break; 04202 case ZT_EVENT_WINKFLASH: 04203 if (p->inalarm) break; 04204 if (p->radio) break; 04205 if (p->oprmode < 0) break; 04206 if (p->oprmode > 1) 04207 { 04208 struct zt_params par; 04209 04210 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04211 { 04212 if (!par.rxisoffhook) 04213 { 04214 /* Make sure it stops ringing */ 04215 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04216 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04217 save_conference(p); 04218 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04219 } 04220 } 04221 break; 04222 } 04223 /* Remember last time we got a flash-hook */ 04224 gettimeofday(&p->flashtime, NULL); 04225 switch (mysig) { 04226 case SIG_FXOLS: 04227 case SIG_FXOGS: 04228 case SIG_FXOKS: 04229 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04230 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04231 p->callwaitcas = 0; 04232 04233 if (index != SUB_REAL) { 04234 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04235 goto winkflashdone; 04236 } 04237 04238 if (p->subs[SUB_CALLWAIT].owner) { 04239 /* Swap to call-wait */ 04240 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04241 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04242 p->owner = p->subs[SUB_REAL].owner; 04243 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04244 if (p->owner->_state == AST_STATE_RINGING) { 04245 ast_setstate(p->owner, AST_STATE_UP); 04246 p->subs[SUB_REAL].needanswer = 1; 04247 } 04248 p->callwaitingrepeat = 0; 04249 p->cidcwexpire = 0; 04250 /* Start music on hold if appropriate */ 04251 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04252 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04253 S_OR(p->mohsuggest, NULL), 04254 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04255 } 04256 p->subs[SUB_CALLWAIT].needhold = 1; 04257 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04258 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04259 S_OR(p->mohsuggest, NULL), 04260 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04261 } 04262 p->subs[SUB_REAL].needunhold = 1; 04263 } else if (!p->subs[SUB_THREEWAY].owner) { 04264 char cid_num[256]; 04265 char cid_name[256]; 04266 04267 if (!p->threewaycalling) { 04268 /* Just send a flash if no 3-way calling */ 04269 p->subs[SUB_REAL].needflash = 1; 04270 goto winkflashdone; 04271 } else if (!check_for_conference(p)) { 04272 if (p->zaptrcallerid && p->owner) { 04273 if (p->owner->cid.cid_num) 04274 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04275 if (p->owner->cid.cid_name) 04276 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04277 } 04278 /* XXX This section needs much more error checking!!! XXX */ 04279 /* Start a 3-way call if feasible */ 04280 if (!((ast->pbx) || 04281 (ast->_state == AST_STATE_UP) || 04282 (ast->_state == AST_STATE_RING))) { 04283 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04284 goto winkflashdone; 04285 } 04286 if (alloc_sub(p, SUB_THREEWAY)) { 04287 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04288 goto winkflashdone; 04289 } 04290 /* Make new channel */ 04291 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04292 if (p->zaptrcallerid) { 04293 if (!p->origcid_num) 04294 p->origcid_num = ast_strdup(p->cid_num); 04295 if (!p->origcid_name) 04296 p->origcid_name = ast_strdup(p->cid_name); 04297 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04298 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04299 } 04300 /* Swap things around between the three-way and real call */ 04301 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04302 /* Disable echo canceller for better dialing */ 04303 zt_disable_ec(p); 04304 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04305 if (res) 04306 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04307 p->owner = chan; 04308 pthread_attr_init(&attr); 04309 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04310 if (!chan) { 04311 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04312 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04313 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04314 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04315 zt_enable_ec(p); 04316 ast_hangup(chan); 04317 } else { 04318 if (option_verbose > 2) 04319 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04320 /* Start music on hold if appropriate */ 04321 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04322 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04323 S_OR(p->mohsuggest, NULL), 04324 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04325 } 04326 p->subs[SUB_THREEWAY].needhold = 1; 04327 } 04328 pthread_attr_destroy(&attr); 04329 } 04330 } else { 04331 /* Already have a 3 way call */ 04332 if (p->subs[SUB_THREEWAY].inthreeway) { 04333 /* Call is already up, drop the last person */ 04334 if (option_debug) 04335 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04336 /* If the primary call isn't answered yet, use it */ 04337 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04338 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04339 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04340 p->owner = p->subs[SUB_REAL].owner; 04341 } 04342 /* Drop the last call and stop the conference */ 04343 if (option_verbose > 2) 04344 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04345 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04346 p->subs[SUB_REAL].inthreeway = 0; 04347 p->subs[SUB_THREEWAY].inthreeway = 0; 04348 } else { 04349 /* Lets see what we're up to */ 04350 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04351 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04352 int otherindex = SUB_THREEWAY; 04353 04354 if (option_verbose > 2) 04355 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); 04356 /* Put them in the threeway, and flip */ 04357 p->subs[SUB_THREEWAY].inthreeway = 1; 04358 p->subs[SUB_REAL].inthreeway = 1; 04359 if (ast->_state == AST_STATE_UP) { 04360 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04361 otherindex = SUB_REAL; 04362 } 04363 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04364 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04365 p->subs[otherindex].needunhold = 1; 04366 p->owner = p->subs[SUB_REAL].owner; 04367 if (ast->_state == AST_STATE_RINGING) { 04368 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04369 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04370 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04371 } 04372 } else { 04373 if (option_verbose > 2) 04374 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04375 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04376 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04377 p->owner = p->subs[SUB_REAL].owner; 04378 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04379 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04380 p->subs[SUB_REAL].needunhold = 1; 04381 zt_enable_ec(p); 04382 } 04383 04384 } 04385 } 04386 winkflashdone: 04387 update_conf(p); 04388 break; 04389 case SIG_EM: 04390 case SIG_EM_E1: 04391 case SIG_EMWINK: 04392 case SIG_FEATD: 04393 case SIG_SF: 04394 case SIG_SFWINK: 04395 case SIG_SF_FEATD: 04396 case SIG_FXSLS: 04397 case SIG_FXSGS: 04398 if (p->dialing) 04399 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04400 else 04401 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04402 break; 04403 case SIG_FEATDMF_TA: 04404 switch (p->whichwink) { 04405 case 0: 04406 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04407 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04408 break; 04409 case 1: 04410 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04411 break; 04412 case 2: 04413 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04414 return NULL; 04415 } 04416 p->whichwink++; 04417 /* Fall through */ 04418 case SIG_FEATDMF: 04419 case SIG_E911: 04420 case SIG_FGC_CAMAMF: 04421 case SIG_FGC_CAMA: 04422 case SIG_FEATB: 04423 case SIG_SF_FEATDMF: 04424 case SIG_SF_FEATB: 04425 /* FGD MF *Must* wait for wink */ 04426 if (!ast_strlen_zero(p->dop.dialstr)) { 04427 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04428 if (res < 0) { 04429 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04430 p->dop.dialstr[0] = '\0'; 04431 return NULL; 04432 } else 04433 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04434 } 04435 p->dop.dialstr[0] = '\0'; 04436 break; 04437 default: 04438 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04439 } 04440 break; 04441 case ZT_EVENT_HOOKCOMPLETE: 04442 if (p->inalarm) break; 04443 if ((p->radio || (p->oprmode < 0))) break; 04444 switch (mysig) { 04445 case SIG_FXSLS: /* only interesting for FXS */ 04446 case SIG_FXSGS: 04447 case SIG_FXSKS: 04448 case SIG_EM: 04449 case SIG_EM_E1: 04450 case SIG_EMWINK: 04451 case SIG_FEATD: 04452 case SIG_SF: 04453 case SIG_SFWINK: 04454 case SIG_SF_FEATD: 04455 if (!ast_strlen_zero(p->dop.dialstr)) { 04456 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04457 if (res < 0) { 04458 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04459 p->dop.dialstr[0] = '\0'; 04460 return NULL; 04461 } else 04462 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04463 } 04464 p->dop.dialstr[0] = '\0'; 04465 p->dop.op = ZT_DIAL_OP_REPLACE; 04466 break; 04467 case SIG_FEATDMF: 04468 case SIG_FEATDMF_TA: 04469 case SIG_E911: 04470 case SIG_FGC_CAMA: 04471 case SIG_FGC_CAMAMF: 04472 case SIG_FEATB: 04473 case SIG_SF_FEATDMF: 04474 case SIG_SF_FEATB: 04475 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04476 break; 04477 default: 04478 break; 04479 } 04480 break; 04481 case ZT_EVENT_POLARITY: 04482 /* 04483 * If we get a Polarity Switch event, check to see 04484 * if we should change the polarity state and 04485 * mark the channel as UP or if this is an indication 04486 * of remote end disconnect. 04487 */ 04488 if (p->polarity == POLARITY_IDLE) { 04489 p->polarity = POLARITY_REV; 04490 if (p->answeronpolarityswitch && 04491 ((ast->_state == AST_STATE_DIALING) || 04492 (ast->_state == AST_STATE_RINGING))) { 04493 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04494 ast_setstate(p->owner, AST_STATE_UP); 04495 if (p->hanguponpolarityswitch) { 04496 gettimeofday(&p->polaritydelaytv, NULL); 04497 } 04498 } else 04499 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04500 } 04501 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04502 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04503 if (p->hanguponpolarityswitch && 04504 (p->polarityonanswerdelay > 0) && 04505 (p->polarity == POLARITY_REV) && 04506 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04507 /* Added log_debug information below to provide a better indication of what is going on */ 04508 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) ); 04509 04510 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04511 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04512 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04513 p->polarity = POLARITY_IDLE; 04514 } else { 04515 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); 04516 } 04517 } else { 04518 p->polarity = POLARITY_IDLE; 04519 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04520 } 04521 /* Added more log_debug information below to provide a better indication of what is going on */ 04522 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) ); 04523 break; 04524 default: 04525 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04526 } 04527 return &p->subs[index].f; 04528 }
static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2431 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), ast_channel_setoption(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_dsp_digitmode(), ast_dsp_free(), ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), zt_pvt::callwaitcas, zt_pvt::callwaiting, zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, zt_pvt::destroy, destroy_channel(), zt_pvt::dialing, zt_pvt::didtdd, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::exten, zt_pvt::faxhandled, free, zt_pvt::guardtime, ast_channel::hangupcause, zt_pvt::hidecallerid, iflist, zt_pvt::ignoredtmf, zt_subchannel::inthreeway, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::mohsuggest, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::oprmode, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_getvar_helper(), zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::prev, zt_pvt::pulsedial, zt_pvt::radio, zt_pvt::rdnis, reset_conf(), restart_monitor(), restore_gains(), zt_pvt::ringt, S_OR, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().
02432 { 02433 int res; 02434 int index,x, law; 02435 /*static int restore_gains(struct zt_pvt *p);*/ 02436 struct zt_pvt *p = ast->tech_pvt; 02437 struct zt_pvt *tmp = NULL; 02438 struct zt_pvt *prev = NULL; 02439 ZT_PARAMS par; 02440 02441 if (option_debug) 02442 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02443 if (!ast->tech_pvt) { 02444 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02445 return 0; 02446 } 02447 02448 ast_mutex_lock(&p->lock); 02449 02450 index = zt_get_index(ast, p, 1); 02451 02452 if (p->sig == SIG_PRI) { 02453 x = 1; 02454 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02455 } 02456 02457 x = 0; 02458 zt_confmute(p, 0); 02459 restore_gains(p); 02460 if (p->origcid_num) { 02461 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02462 free(p->origcid_num); 02463 p->origcid_num = NULL; 02464 } 02465 if (p->origcid_name) { 02466 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02467 free(p->origcid_name); 02468 p->origcid_name = NULL; 02469 } 02470 if (p->dsp) 02471 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02472 if (p->exten) 02473 p->exten[0] = '\0'; 02474 02475 if (option_debug) 02476 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02477 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02478 p->ignoredtmf = 0; 02479 02480 if (index > -1) { 02481 /* Real channel, do some fixup */ 02482 p->subs[index].owner = NULL; 02483 p->subs[index].needanswer = 0; 02484 p->subs[index].needflash = 0; 02485 p->subs[index].needringing = 0; 02486 p->subs[index].needbusy = 0; 02487 p->subs[index].needcongestion = 0; 02488 p->subs[index].linear = 0; 02489 p->subs[index].needcallerid = 0; 02490 p->polarity = POLARITY_IDLE; 02491 zt_setlinear(p->subs[index].zfd, 0); 02492 if (index == SUB_REAL) { 02493 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02494 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02495 if (p->subs[SUB_CALLWAIT].inthreeway) { 02496 /* We had flipped over to answer a callwait and now it's gone */ 02497 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02498 /* Move to the call-wait, but un-own us until they flip back. */ 02499 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02500 unalloc_sub(p, SUB_CALLWAIT); 02501 p->owner = NULL; 02502 } else { 02503 /* The three way hung up, but we still have a call wait */ 02504 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02505 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02506 unalloc_sub(p, SUB_THREEWAY); 02507 if (p->subs[SUB_REAL].inthreeway) { 02508 /* This was part of a three way call. Immediately make way for 02509 another call */ 02510 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02511 p->owner = p->subs[SUB_REAL].owner; 02512 } else { 02513 /* This call hasn't been completed yet... Set owner to NULL */ 02514 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02515 p->owner = NULL; 02516 } 02517 p->subs[SUB_REAL].inthreeway = 0; 02518 } 02519 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02520 /* Move to the call-wait and switch back to them. */ 02521 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02522 unalloc_sub(p, SUB_CALLWAIT); 02523 p->owner = p->subs[SUB_REAL].owner; 02524 if (p->owner->_state != AST_STATE_UP) 02525 p->subs[SUB_REAL].needanswer = 1; 02526 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02527 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 02528 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02529 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02530 unalloc_sub(p, SUB_THREEWAY); 02531 if (p->subs[SUB_REAL].inthreeway) { 02532 /* This was part of a three way call. Immediately make way for 02533 another call */ 02534 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02535 p->owner = p->subs[SUB_REAL].owner; 02536 } else { 02537 /* This call hasn't been completed yet... Set owner to NULL */ 02538 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02539 p->owner = NULL; 02540 } 02541 p->subs[SUB_REAL].inthreeway = 0; 02542 } 02543 } else if (index == SUB_CALLWAIT) { 02544 /* Ditch the holding callwait call, and immediately make it availabe */ 02545 if (p->subs[SUB_CALLWAIT].inthreeway) { 02546 /* This is actually part of a three way, placed on hold. Place the third part 02547 on music on hold now */ 02548 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 02549 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02550 S_OR(p->mohsuggest, NULL), 02551 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02552 } 02553 p->subs[SUB_THREEWAY].inthreeway = 0; 02554 /* Make it the call wait now */ 02555 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02556 unalloc_sub(p, SUB_THREEWAY); 02557 } else 02558 unalloc_sub(p, SUB_CALLWAIT); 02559 } else if (index == SUB_THREEWAY) { 02560 if (p->subs[SUB_CALLWAIT].inthreeway) { 02561 /* The other party of the three way call is currently in a call-wait state. 02562 Start music on hold for them, and take the main guy out of the third call */ 02563 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 02564 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02565 S_OR(p->mohsuggest, NULL), 02566 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02567 } 02568 p->subs[SUB_CALLWAIT].inthreeway = 0; 02569 } 02570 p->subs[SUB_REAL].inthreeway = 0; 02571 /* If this was part of a three way call index, let us make 02572 another three way call */ 02573 unalloc_sub(p, SUB_THREEWAY); 02574 } else { 02575 /* This wasn't any sort of call, but how are we an index? */ 02576 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02577 } 02578 } 02579 02580 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02581 p->owner = NULL; 02582 p->ringt = 0; 02583 p->distinctivering = 0; 02584 p->confirmanswer = 0; 02585 p->cidrings = 1; 02586 p->outgoing = 0; 02587 p->digital = 0; 02588 p->faxhandled = 0; 02589 p->pulsedial = 0; 02590 p->onhooktime = time(NULL); 02591 #ifdef HAVE_PRI 02592 p->proceeding = 0; 02593 p->progress = 0; 02594 p->alerting = 0; 02595 p->setup_ack = 0; 02596 #endif 02597 if (p->dsp) { 02598 ast_dsp_free(p->dsp); 02599 p->dsp = NULL; 02600 } 02601 02602 law = ZT_LAW_DEFAULT; 02603 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02604 if (res < 0) 02605 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02606 /* Perform low level hangup if no owner left */ 02607 #ifdef HAVE_PRI 02608 if (p->pri) { 02609 #ifdef SUPPORT_USERUSER 02610 const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02611 #endif 02612 02613 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02614 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02615 if (!pri_grab(p, p->pri)) { 02616 if (p->alreadyhungup) { 02617 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02618 02619 #ifdef SUPPORT_USERUSER 02620 pri_call_set_useruser(p->call, useruser); 02621 #endif 02622 02623 pri_hangup(p->pri->pri, p->call, -1); 02624 p->call = NULL; 02625 if (p->bearer) 02626 p->bearer->call = NULL; 02627 } else { 02628 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02629 int icause = ast->hangupcause ? ast->hangupcause : -1; 02630 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02631 02632 #ifdef SUPPORT_USERUSER 02633 pri_call_set_useruser(p->call, useruser); 02634 #endif 02635 02636 p->alreadyhungup = 1; 02637 if (p->bearer) 02638 p->bearer->alreadyhungup = 1; 02639 if (cause) { 02640 if (atoi(cause)) 02641 icause = atoi(cause); 02642 } 02643 pri_hangup(p->pri->pri, p->call, icause); 02644 } 02645 if (res < 0) 02646 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02647 pri_rel(p->pri); 02648 } else { 02649 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02650 res = -1; 02651 } 02652 } else { 02653 if (p->bearer) 02654 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02655 p->call = NULL; 02656 res = 0; 02657 } 02658 } 02659 #endif 02660 if (p->sig && (p->sig != SIG_PRI)) 02661 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02662 if (res < 0) { 02663 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02664 } 02665 switch (p->sig) { 02666 case SIG_FXOGS: 02667 case SIG_FXOLS: 02668 case SIG_FXOKS: 02669 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02670 if (!res) { 02671 #if 0 02672 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02673 #endif 02674 /* If they're off hook, try playing congestion */ 02675 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02676 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02677 else 02678 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02679 } 02680 break; 02681 case SIG_FXSGS: 02682 case SIG_FXSLS: 02683 case SIG_FXSKS: 02684 /* Make sure we're not made available for at least two seconds assuming 02685 we were actually used for an inbound or outbound call. */ 02686 if (ast->_state != AST_STATE_RESERVED) { 02687 time(&p->guardtime); 02688 p->guardtime += 2; 02689 } 02690 break; 02691 default: 02692 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02693 } 02694 if (p->cidspill) 02695 free(p->cidspill); 02696 if (p->sig) 02697 zt_disable_ec(p); 02698 x = 0; 02699 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02700 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02701 p->didtdd = 0; 02702 p->cidspill = NULL; 02703 p->callwaitcas = 0; 02704 p->callwaiting = p->permcallwaiting; 02705 p->hidecallerid = p->permhidecallerid; 02706 p->dialing = 0; 02707 p->rdnis[0] = '\0'; 02708 update_conf(p); 02709 reset_conf(p); 02710 /* Restore data mode */ 02711 if (p->sig == SIG_PRI) { 02712 x = 0; 02713 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02714 } 02715 #ifdef HAVE_PRI 02716 if (p->bearer) { 02717 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02718 /* Free up the bearer channel as well, and 02719 don't use its file descriptor anymore */ 02720 update_conf(p->bearer); 02721 reset_conf(p->bearer); 02722 p->bearer->owner = NULL; 02723 p->bearer->realcall = NULL; 02724 p->bearer = NULL; 02725 p->subs[SUB_REAL].zfd = -1; 02726 p->pri = NULL; 02727 } 02728 #endif 02729 restart_monitor(); 02730 } 02731 02732 p->callwaitingrepeat = 0; 02733 p->cidcwexpire = 0; 02734 p->oprmode = 0; 02735 ast->tech_pvt = NULL; 02736 ast_mutex_unlock(&p->lock); 02737 ast_module_unref(ast_module_info->self); 02738 if (option_verbose > 2) 02739 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02740 02741 ast_mutex_lock(&iflock); 02742 tmp = iflist; 02743 prev = NULL; 02744 if (p->destroy) { 02745 while (tmp) { 02746 if (tmp == p) { 02747 destroy_channel(prev, tmp, 0); 02748 break; 02749 } else { 02750 prev = tmp; 02751 tmp = tmp->next; 02752 } 02753 } 02754 } 02755 ast_mutex_unlock(&iflock); 02756 return 0; 02757 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5043 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().
05044 { 05045 struct zt_pvt *p = chan->tech_pvt; 05046 int res=-1; 05047 int index; 05048 int func = ZT_FLASH; 05049 ast_mutex_lock(&p->lock); 05050 index = zt_get_index(chan, p, 0); 05051 if (option_debug) 05052 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 05053 if (index == SUB_REAL) { 05054 switch (condition) { 05055 case AST_CONTROL_BUSY: 05056 #ifdef HAVE_PRI 05057 if (p->priindication_oob && p->sig == SIG_PRI) { 05058 chan->hangupcause = AST_CAUSE_USER_BUSY; 05059 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05060 res = 0; 05061 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05062 if (p->pri->pri) { 05063 if (!pri_grab(p, p->pri)) { 05064 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05065 pri_rel(p->pri); 05066 } 05067 else 05068 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05069 } 05070 p->progress = 1; 05071 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05072 } else 05073 #endif 05074 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05075 break; 05076 case AST_CONTROL_RINGING: 05077 #ifdef HAVE_PRI 05078 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05079 if (p->pri->pri) { 05080 if (!pri_grab(p, p->pri)) { 05081 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05082 pri_rel(p->pri); 05083 } 05084 else 05085 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05086 } 05087 p->alerting = 1; 05088 } 05089 #endif 05090 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05091 if (chan->_state != AST_STATE_UP) { 05092 if ((chan->_state != AST_STATE_RING) || 05093 ((p->sig != SIG_FXSKS) && 05094 (p->sig != SIG_FXSLS) && 05095 (p->sig != SIG_FXSGS))) 05096 ast_setstate(chan, AST_STATE_RINGING); 05097 } 05098 break; 05099 case AST_CONTROL_PROCEEDING: 05100 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05101 #ifdef HAVE_PRI 05102 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05103 if (p->pri->pri) { 05104 if (!pri_grab(p, p->pri)) { 05105 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05106 pri_rel(p->pri); 05107 } 05108 else 05109 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05110 } 05111 p->proceeding = 1; 05112 } 05113 #endif 05114 /* don't continue in ast_indicate */ 05115 res = 0; 05116 break; 05117 case AST_CONTROL_PROGRESS: 05118 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05119 #ifdef HAVE_PRI 05120 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05121 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05122 if (p->pri->pri) { 05123 if (!pri_grab(p, p->pri)) { 05124 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05125 pri_rel(p->pri); 05126 } 05127 else 05128 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05129 } 05130 p->progress = 1; 05131 } 05132 #endif 05133 /* don't continue in ast_indicate */ 05134 res = 0; 05135 break; 05136 case AST_CONTROL_CONGESTION: 05137 chan->hangupcause = AST_CAUSE_CONGESTION; 05138 #ifdef HAVE_PRI 05139 if (p->priindication_oob && p->sig == SIG_PRI) { 05140 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05141 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05142 res = 0; 05143 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05144 if (p->pri) { 05145 if (!pri_grab(p, p->pri)) { 05146 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05147 pri_rel(p->pri); 05148 } else 05149 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05150 } 05151 p->progress = 1; 05152 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05153 } else 05154 #endif 05155 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05156 break; 05157 case AST_CONTROL_HOLD: 05158 #ifdef HAVE_PRI 05159 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05160 if (!pri_grab(p, p->pri)) { 05161 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05162 pri_rel(p->pri); 05163 } else 05164 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05165 } else 05166 #endif 05167 ast_moh_start(chan, data, p->mohinterpret); 05168 break; 05169 case AST_CONTROL_UNHOLD: 05170 #ifdef HAVE_PRI 05171 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05172 if (!pri_grab(p, p->pri)) { 05173 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05174 pri_rel(p->pri); 05175 } else 05176 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05177 } else 05178 #endif 05179 ast_moh_stop(chan); 05180 break; 05181 case AST_CONTROL_RADIO_KEY: 05182 if (p->radio) 05183 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05184 res = 0; 05185 break; 05186 case AST_CONTROL_RADIO_UNKEY: 05187 if (p->radio) 05188 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05189 res = 0; 05190 break; 05191 case AST_CONTROL_FLASH: 05192 /* flash hookswitch */ 05193 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05194 /* Clear out the dial buffer */ 05195 p->dop.dialstr[0] = '\0'; 05196 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05197 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05198 chan->name, strerror(errno)); 05199 } else 05200 res = 0; 05201 } else 05202 res = 0; 05203 break; 05204 case AST_CONTROL_SRCUPDATE: 05205 res = 0; 05206 break; 05207 case -1: 05208 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05209 break; 05210 } 05211 } else 05212 res = 0; 05213 ast_mutex_unlock(&p->lock); 05214 return res; 05215 }
Definition at line 3104 of file chan_zap.c.
References ast_log(), LOG_WARNING, and master.
Referenced by zt_bridge().
03104 { 03105 int x; 03106 if (!slave || !master) { 03107 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03108 return; 03109 } 03110 for (x = 0; x < MAX_SLAVES; x++) { 03111 if (!master->slaves[x]) { 03112 master->slaves[x] = slave; 03113 break; 03114 } 03115 } 03116 if (x >= MAX_SLAVES) { 03117 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03118 master->slaves[MAX_SLAVES - 1] = slave; 03119 } 03120 if (slave->master) 03121 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03122 slave->master = master; 03123 03124 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03125 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | , | |
int | , | |||
int | , | |||
int | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5217 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_compare(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), ast_dsp_set_threshold(), 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::busycompare, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::busyfuzziness, zt_pvt::busyquietlength, zt_pvt::busytonelength, 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, zt_pvt::silencethreshold, 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().
05218 { 05219 struct ast_channel *tmp; 05220 int deflaw; 05221 int res; 05222 int x,y; 05223 int features; 05224 char *b2 = NULL; 05225 ZT_PARAMS ps; 05226 if (i->subs[index].owner) { 05227 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05228 return NULL; 05229 } 05230 y = 1; 05231 do { 05232 if (b2) 05233 free(b2); 05234 #ifdef HAVE_PRI 05235 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05236 b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05237 else 05238 #endif 05239 if (i->channel == CHAN_PSEUDO) 05240 b2 = ast_safe_string_alloc("pseudo-%ld", ast_random()); 05241 else 05242 b2 = ast_safe_string_alloc("%d-%d", i->channel, y); 05243 for (x = 0; x < 3; x++) { 05244 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05245 break; 05246 } 05247 y++; 05248 } while (x < 3); 05249 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2); 05250 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05251 free(b2); 05252 if (!tmp) 05253 return NULL; 05254 tmp->tech = &zap_tech; 05255 ps.channo = i->channel; 05256 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05257 if (res) { 05258 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05259 ps.curlaw = ZT_LAW_MULAW; 05260 } 05261 if (ps.curlaw == ZT_LAW_ALAW) 05262 deflaw = AST_FORMAT_ALAW; 05263 else 05264 deflaw = AST_FORMAT_ULAW; 05265 if (law) { 05266 if (law == ZT_LAW_ALAW) 05267 deflaw = AST_FORMAT_ALAW; 05268 else 05269 deflaw = AST_FORMAT_ULAW; 05270 } 05271 tmp->fds[0] = i->subs[index].zfd; 05272 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05273 /* Start out assuming ulaw since it's smaller :) */ 05274 tmp->rawreadformat = deflaw; 05275 tmp->readformat = deflaw; 05276 tmp->rawwriteformat = deflaw; 05277 tmp->writeformat = deflaw; 05278 i->subs[index].linear = 0; 05279 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05280 features = 0; 05281 if (index == SUB_REAL) { 05282 if (i->busydetect && CANBUSYDETECT(i)) 05283 features |= DSP_FEATURE_BUSY_DETECT; 05284 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05285 features |= DSP_FEATURE_CALL_PROGRESS; 05286 if ((!i->outgoing && (i->callprogress & 4)) || 05287 (i->outgoing && (i->callprogress & 2))) { 05288 features |= DSP_FEATURE_FAX_DETECT; 05289 } 05290 #ifdef ZT_TONEDETECT 05291 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05292 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05293 #endif 05294 i->hardwaredtmf = 0; 05295 features |= DSP_FEATURE_DTMF_DETECT; 05296 #ifdef ZT_TONEDETECT 05297 } else if (NEED_MFDETECT(i)) { 05298 i->hardwaredtmf = 1; 05299 features |= DSP_FEATURE_DTMF_DETECT; 05300 } 05301 #endif 05302 } 05303 if (features) { 05304 if (i->dsp) { 05305 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05306 } else { 05307 if (i->channel != CHAN_PSEUDO) 05308 i->dsp = ast_dsp_new(); 05309 else 05310 i->dsp = NULL; 05311 if (i->dsp) { 05312 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05313 #ifdef HAVE_PRI 05314 /* We cannot do progress detection until receives PROGRESS message */ 05315 if (i->outgoing && (i->sig == SIG_PRI)) { 05316 /* Remember requested DSP features, don't treat 05317 talking as ANSWER */ 05318 features = 0; 05319 } 05320 #endif 05321 ast_dsp_set_features(i->dsp, features); 05322 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05323 if (!ast_strlen_zero(progzone)) 05324 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05325 if (i->busydetect && CANBUSYDETECT(i)) { 05326 if(i->silencethreshold > 0) 05327 ast_dsp_set_threshold(i->dsp, i->silencethreshold); 05328 ast_dsp_set_busy_count(i->dsp, i->busycount); 05329 if(i->busytonelength > 0) 05330 ast_dsp_set_busy_pattern(i->dsp, i->busytonelength, i->busyquietlength, i->busyfuzziness); 05331 if((i->busytonelength == i->busyquietlength) && i->busycompare) 05332 ast_dsp_set_busy_compare(i->dsp, i->busycompare); 05333 } 05334 } 05335 } 05336 } 05337 05338 if (state == AST_STATE_RING) 05339 tmp->rings = 1; 05340 tmp->tech_pvt = i; 05341 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05342 /* Only FXO signalled stuff can be picked up */ 05343 tmp->callgroup = i->callgroup; 05344 tmp->pickupgroup = i->pickupgroup; 05345 } 05346 if (!ast_strlen_zero(i->language)) 05347 ast_string_field_set(tmp, language, i->language); 05348 if (!i->owner) 05349 i->owner = tmp; 05350 if (!ast_strlen_zero(i->accountcode)) 05351 ast_string_field_set(tmp, accountcode, i->accountcode); 05352 if (i->amaflags) 05353 tmp->amaflags = i->amaflags; 05354 i->subs[index].owner = tmp; 05355 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05356 ast_string_field_set(tmp, call_forward, i->call_forward); 05357 /* If we've been told "no ADSI" then enforce it */ 05358 if (!i->adsi) 05359 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05360 if (!ast_strlen_zero(i->exten)) 05361 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05362 if (!ast_strlen_zero(i->rdnis)) 05363 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05364 if (!ast_strlen_zero(i->dnid)) 05365 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05366 05367 /* Don't use ast_set_callerid() here because it will 05368 * generate a needless NewCallerID event */ 05369 #ifdef PRI_ANI 05370 if (!ast_strlen_zero(i->cid_ani)) 05371 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05372 else 05373 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05374 #else 05375 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05376 #endif 05377 tmp->cid.cid_pres = i->callingpres; 05378 tmp->cid.cid_ton = i->cid_ton; 05379 #ifdef HAVE_PRI 05380 tmp->transfercapability = transfercapability; 05381 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05382 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05383 i->digital = 1; 05384 /* Assume calls are not idle calls unless we're told differently */ 05385 i->isidlecall = 0; 05386 i->alreadyhungup = 0; 05387 #endif 05388 /* clear the fake event in case we posted one before we had ast_channel */ 05389 i->fake_event = 0; 05390 /* Assure there is no confmute on this channel */ 05391 zt_confmute(i, 0); 05392 /* Configure the new channel jb */ 05393 ast_jb_configure(tmp, &global_jbconf); 05394 if (startpbx) { 05395 if (ast_pbx_start(tmp)) { 05396 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05397 ast_hangup(tmp); 05398 i->owner = NULL; 05399 return NULL; 05400 } 05401 } 05402 05403 ast_module_ref(ast_module_info->self); 05404 05405 return tmp; 05406 }
static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 890 of file chan_zap.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
00891 { 00892 int fd; 00893 int isnum; 00894 int chan = 0; 00895 int bs; 00896 int x; 00897 isnum = 1; 00898 for (x = 0; x < strlen(fn); x++) { 00899 if (!isdigit(fn[x])) { 00900 isnum = 0; 00901 break; 00902 } 00903 } 00904 if (isnum) { 00905 chan = atoi(fn); 00906 if (chan < 1) { 00907 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 00908 return -1; 00909 } 00910 fn = "/dev/zap/channel"; 00911 } 00912 fd = open(fn, O_RDWR | O_NONBLOCK); 00913 if (fd < 0) { 00914 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 00915 return -1; 00916 } 00917 if (chan) { 00918 if (ioctl(fd, ZT_SPECIFY, &chan)) { 00919 x = errno; 00920 close(fd); 00921 errno = x; 00922 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 00923 return -1; 00924 } 00925 } 00926 bs = READ_SIZE; 00927 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) { 00928 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 00929 x = errno; 00930 close(fd); 00931 errno = x; 00932 return -1; 00933 } 00934 return fd; 00935 }
static struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4648 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_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().
04649 { 04650 struct zt_pvt *p = ast->tech_pvt; 04651 int res; 04652 int index; 04653 void *readbuf; 04654 struct ast_frame *f; 04655 04656 04657 ast_mutex_lock(&p->lock); 04658 04659 index = zt_get_index(ast, p, 0); 04660 04661 /* Hang up if we don't really exist */ 04662 if (index < 0) { 04663 ast_log(LOG_WARNING, "We dont exist?\n"); 04664 ast_mutex_unlock(&p->lock); 04665 return NULL; 04666 } 04667 04668 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04669 04670 p->subs[index].f.frametype = AST_FRAME_NULL; 04671 p->subs[index].f.datalen = 0; 04672 p->subs[index].f.samples = 0; 04673 p->subs[index].f.mallocd = 0; 04674 p->subs[index].f.offset = 0; 04675 p->subs[index].f.subclass = 0; 04676 p->subs[index].f.delivery = ast_tv(0,0); 04677 p->subs[index].f.src = "zt_read"; 04678 p->subs[index].f.data = NULL; 04679 04680 /* make sure it sends initial key state as first frame */ 04681 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04682 { 04683 ZT_PARAMS ps; 04684 04685 ps.channo = p->channel; 04686 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04687 ast_mutex_unlock(&p->lock); 04688 return NULL; 04689 } 04690 p->firstradio = 1; 04691 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04692 if (ps.rxisoffhook) 04693 { 04694 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04695 } 04696 else 04697 { 04698 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04699 } 04700 ast_mutex_unlock(&p->lock); 04701 return &p->subs[index].f; 04702 } 04703 if (p->ringt == 1) { 04704 ast_mutex_unlock(&p->lock); 04705 return NULL; 04706 } 04707 else if (p->ringt > 0) 04708 p->ringt--; 04709 04710 if (p->subs[index].needringing) { 04711 /* Send ringing frame if requested */ 04712 p->subs[index].needringing = 0; 04713 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04714 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04715 ast_setstate(ast, AST_STATE_RINGING); 04716 ast_mutex_unlock(&p->lock); 04717 return &p->subs[index].f; 04718 } 04719 04720 if (p->subs[index].needbusy) { 04721 /* Send busy frame if requested */ 04722 p->subs[index].needbusy = 0; 04723 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04724 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04725 ast_mutex_unlock(&p->lock); 04726 return &p->subs[index].f; 04727 } 04728 04729 if (p->subs[index].needcongestion) { 04730 /* Send congestion frame if requested */ 04731 p->subs[index].needcongestion = 0; 04732 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04733 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04734 ast_mutex_unlock(&p->lock); 04735 return &p->subs[index].f; 04736 } 04737 04738 if (p->subs[index].needcallerid) { 04739 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04740 S_OR(p->lastcid_name, NULL), 04741 S_OR(p->lastcid_num, NULL) 04742 ); 04743 p->subs[index].needcallerid = 0; 04744 } 04745 04746 if (p->subs[index].needanswer) { 04747 /* Send answer frame if requested */ 04748 p->subs[index].needanswer = 0; 04749 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04750 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04751 ast_mutex_unlock(&p->lock); 04752 return &p->subs[index].f; 04753 } 04754 04755 if (p->subs[index].needflash) { 04756 /* Send answer frame if requested */ 04757 p->subs[index].needflash = 0; 04758 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04759 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04760 ast_mutex_unlock(&p->lock); 04761 return &p->subs[index].f; 04762 } 04763 04764 if (p->subs[index].needhold) { 04765 /* Send answer frame if requested */ 04766 p->subs[index].needhold = 0; 04767 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04768 p->subs[index].f.subclass = AST_CONTROL_HOLD; 04769 ast_mutex_unlock(&p->lock); 04770 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 04771 return &p->subs[index].f; 04772 } 04773 04774 if (p->subs[index].needunhold) { 04775 /* Send answer frame if requested */ 04776 p->subs[index].needunhold = 0; 04777 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04778 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 04779 ast_mutex_unlock(&p->lock); 04780 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 04781 return &p->subs[index].f; 04782 } 04783 04784 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04785 if (!p->subs[index].linear) { 04786 p->subs[index].linear = 1; 04787 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04788 if (res) 04789 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04790 } 04791 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04792 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04793 if (p->subs[index].linear) { 04794 p->subs[index].linear = 0; 04795 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04796 if (res) 04797 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04798 } 04799 } else { 04800 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04801 ast_mutex_unlock(&p->lock); 04802 return NULL; 04803 } 04804 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04805 CHECK_BLOCKING(ast); 04806 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04807 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04808 /* Check for hangup */ 04809 if (res < 0) { 04810 f = NULL; 04811 if (res == -1) { 04812 if (errno == EAGAIN) { 04813 /* Return "NULL" frame if there is nobody there */ 04814 ast_mutex_unlock(&p->lock); 04815 return &p->subs[index].f; 04816 } else if (errno == ELAST) { 04817 f = __zt_exception(ast); 04818 } else 04819 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04820 } 04821 ast_mutex_unlock(&p->lock); 04822 return f; 04823 } 04824 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04825 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04826 f = __zt_exception(ast); 04827 ast_mutex_unlock(&p->lock); 04828 return f; 04829 } 04830 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04831 int c; 04832 04833 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04834 if (c < 0) { 04835 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04836 ast_mutex_unlock(&p->lock); 04837 return NULL; 04838 } 04839 if (c) { /* if a char to return */ 04840 p->subs[index].f.subclass = 0; 04841 p->subs[index].f.frametype = AST_FRAME_TEXT; 04842 p->subs[index].f.mallocd = 0; 04843 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04844 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04845 p->subs[index].f.datalen = 1; 04846 *((char *) p->subs[index].f.data) = c; 04847 ast_mutex_unlock(&p->lock); 04848 return &p->subs[index].f; 04849 } 04850 } 04851 /* Ensure the CW timer decrements only on a single subchannel */ 04852 if (p->callwaitingrepeat && zt_get_index(ast, p, 1) == SUB_REAL) { 04853 p->callwaitingrepeat--; 04854 } 04855 if (p->cidcwexpire) 04856 p->cidcwexpire--; 04857 /* Repeat callwaiting */ 04858 if (p->callwaitingrepeat == 1) { 04859 p->callwaitrings++; 04860 zt_callwait(ast); 04861 } 04862 /* Expire CID/CW */ 04863 if (p->cidcwexpire == 1) { 04864 if (option_verbose > 2) 04865 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 04866 restore_conference(p); 04867 } 04868 if (p->subs[index].linear) { 04869 p->subs[index].f.datalen = READ_SIZE * 2; 04870 } else 04871 p->subs[index].f.datalen = READ_SIZE; 04872 04873 /* Handle CallerID Transmission */ 04874 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 04875 send_callerid(p); 04876 } 04877 04878 p->subs[index].f.frametype = AST_FRAME_VOICE; 04879 p->subs[index].f.subclass = ast->rawreadformat; 04880 p->subs[index].f.samples = READ_SIZE; 04881 p->subs[index].f.mallocd = 0; 04882 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04883 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 04884 #if 0 04885 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 04886 #endif 04887 if (p->dialing || /* Transmitting something */ 04888 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 04889 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 04890 ) { 04891 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 04892 don't send anything */ 04893 p->subs[index].f.frametype = AST_FRAME_NULL; 04894 p->subs[index].f.subclass = 0; 04895 p->subs[index].f.samples = 0; 04896 p->subs[index].f.mallocd = 0; 04897 p->subs[index].f.offset = 0; 04898 p->subs[index].f.data = NULL; 04899 p->subs[index].f.datalen= 0; 04900 } 04901 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 04902 /* Perform busy detection. etc on the zap line */ 04903 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 04904 if (f) { 04905 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 04906 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 04907 /* Treat this as a "hangup" instead of a "busy" on the assumption that 04908 a busy */ 04909 f = NULL; 04910 } 04911 } else if (f->frametype == AST_FRAME_DTMF) { 04912 #ifdef HAVE_PRI 04913 if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { 04914 /* Don't accept in-band DTMF when in overlap dial mode */ 04915 f->frametype = AST_FRAME_NULL; 04916 f->subclass = 0; 04917 } 04918 #endif 04919 /* DSP clears us of being pulse */ 04920 p->pulsedial = 0; 04921 } 04922 } 04923 } else 04924 f = &p->subs[index].f; 04925 04926 if (f && (f->frametype == AST_FRAME_DTMF)) 04927 zt_handle_dtmfup(ast, index, &f); 04928 04929 /* If we have a fake_event, trigger exception to handle it */ 04930 if (p->fake_event) 04931 ast_set_flag(ast, AST_FLAG_EXCEPTION); 04932 04933 ast_mutex_unlock(&p->lock); 04934 return f; 04935 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 7814 of file chan_zap.c.
References alloc_sub(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CDR_CALLWAIT, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), busy, ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_NOTICE, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, pri_assign_bearer(), restart_monitor(), round_robin, s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, and zt_new().
07815 { 07816 ast_group_t groupmatch = 0; 07817 int channelmatch = -1; 07818 int roundrobin = 0; 07819 int callwait = 0; 07820 int busy = 0; 07821 struct zt_pvt *p; 07822 struct ast_channel *tmp = NULL; 07823 char *dest=NULL; 07824 int x; 07825 char *s; 07826 char opt=0; 07827 int res=0, y=0; 07828 int backwards = 0; 07829 #ifdef HAVE_PRI 07830 int crv; 07831 int bearer = -1; 07832 int trunkgroup; 07833 struct zt_pri *pri=NULL; 07834 #endif 07835 struct zt_pvt *exit, *start, *end; 07836 ast_mutex_t *lock; 07837 int channelmatched = 0; 07838 int groupmatched = 0; 07839 07840 /* Assume we're locking the iflock */ 07841 lock = &iflock; 07842 start = iflist; 07843 end = ifend; 07844 if (data) { 07845 dest = ast_strdupa((char *)data); 07846 } else { 07847 ast_log(LOG_WARNING, "Channel requested with no data\n"); 07848 return NULL; 07849 } 07850 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 07851 /* Retrieve the group number */ 07852 char *stringp=NULL; 07853 stringp=dest + 1; 07854 s = strsep(&stringp, "/"); 07855 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07856 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 07857 return NULL; 07858 } 07859 groupmatch = ((ast_group_t) 1 << x); 07860 if (toupper(dest[0]) == 'G') { 07861 if (dest[0] == 'G') { 07862 backwards = 1; 07863 p = ifend; 07864 } else 07865 p = iflist; 07866 } else { 07867 if (dest[0] == 'R') { 07868 backwards = 1; 07869 p = round_robin[x]?round_robin[x]->prev:ifend; 07870 if (!p) 07871 p = ifend; 07872 } else { 07873 p = round_robin[x]?round_robin[x]->next:iflist; 07874 if (!p) 07875 p = iflist; 07876 } 07877 roundrobin = 1; 07878 } 07879 } else { 07880 char *stringp=NULL; 07881 stringp=dest; 07882 s = strsep(&stringp, "/"); 07883 p = iflist; 07884 if (!strcasecmp(s, "pseudo")) { 07885 /* Special case for pseudo */ 07886 x = CHAN_PSEUDO; 07887 channelmatch = x; 07888 } 07889 #ifdef HAVE_PRI 07890 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 07891 if ((trunkgroup < 1) || (crv < 1)) { 07892 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 07893 return NULL; 07894 } 07895 res--; 07896 for (x = 0; x < NUM_SPANS; x++) { 07897 if (pris[x].trunkgroup == trunkgroup) { 07898 pri = pris + x; 07899 lock = &pri->lock; 07900 start = pri->crvs; 07901 end = pri->crvend; 07902 break; 07903 } 07904 } 07905 if (!pri) { 07906 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 07907 return NULL; 07908 } 07909 channelmatch = crv; 07910 p = pris[x].crvs; 07911 } 07912 #endif 07913 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07914 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 07915 return NULL; 07916 } else { 07917 channelmatch = x; 07918 } 07919 } 07920 /* Search for an unowned channel */ 07921 ast_mutex_lock(lock); 07922 exit = p; 07923 while (p && !tmp) { 07924 if (roundrobin) 07925 round_robin[x] = p; 07926 #if 0 07927 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 07928 #endif 07929 07930 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 07931 if (option_debug) 07932 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 07933 if (p->inalarm) 07934 goto next; 07935 07936 callwait = (p->owner != NULL); 07937 #ifdef HAVE_PRI 07938 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 07939 if (p->sig != SIG_FXSKS) { 07940 /* Gotta find an actual channel to use for this 07941 CRV if this isn't a callwait */ 07942 bearer = pri_find_empty_chan(pri, 0); 07943 if (bearer < 0) { 07944 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 07945 p = NULL; 07946 break; 07947 } 07948 pri_assign_bearer(p, pri, pri->pvts[bearer]); 07949 } else { 07950 if (alloc_sub(p, 0)) { 07951 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 07952 p = NULL; 07953 break; 07954 } else 07955 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 07956 p->pri = pri; 07957 } 07958 } 07959 #endif 07960 if (p->channel == CHAN_PSEUDO) { 07961 p = chandup(p); 07962 if (!p) { 07963 break; 07964 } 07965 } 07966 if (p->owner) { 07967 if (alloc_sub(p, SUB_CALLWAIT)) { 07968 p = NULL; 07969 break; 07970 } 07971 } 07972 p->outgoing = 1; 07973 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 07974 #ifdef HAVE_PRI 07975 if (p->bearer) { 07976 /* Log owner to bearer channel, too */ 07977 p->bearer->owner = tmp; 07978 } 07979 #endif 07980 /* Make special notes */ 07981 if (res > 1) { 07982 if (opt == 'c') { 07983 /* Confirm answer */ 07984 p->confirmanswer = 1; 07985 } else if (opt == 'r') { 07986 /* Distinctive ring */ 07987 if (res < 3) 07988 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 07989 else 07990 p->distinctivering = y; 07991 } else if (opt == 'd') { 07992 /* If this is an ISDN call, make it digital */ 07993 p->digital = 1; 07994 if (tmp) 07995 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 07996 } else { 07997 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 07998 } 07999 } 08000 /* Note if the call is a call waiting call */ 08001 if (tmp && callwait) 08002 tmp->cdrflags |= AST_CDR_CALLWAIT; 08003 break; 08004 } 08005 next: 08006 if (backwards) { 08007 p = p->prev; 08008 if (!p) 08009 p = end; 08010 } else { 08011 p = p->next; 08012 if (!p) 08013 p = start; 08014 } 08015 /* stop when you roll to the one that we started from */ 08016 if (p == exit) 08017 break; 08018 } 08019 ast_mutex_unlock(lock); 08020 restart_monitor(); 08021 if (callwait) 08022 *cause = AST_CAUSE_BUSY; 08023 else if (!tmp) { 08024 if (channelmatched) { 08025 if (busy) 08026 *cause = AST_CAUSE_BUSY; 08027 } else if (groupmatched) { 08028 *cause = AST_CAUSE_CONGESTION; 08029 } 08030 } 08031 08032 return tmp; 08033 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3479 of file chan_zap.c.
References ast_log(), errno, SUB_REAL, and zt_pvt::subs.
Referenced by __zt_exception(), and zt_handle_event().
03480 { 03481 int x; 03482 int res; 03483 /* Make sure our transmit state is on hook */ 03484 x = 0; 03485 x = ZT_ONHOOK; 03486 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03487 do { 03488 x = ZT_RING; 03489 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03490 if (res) { 03491 switch (errno) { 03492 case EBUSY: 03493 case EINTR: 03494 /* Wait just in case */ 03495 usleep(10000); 03496 continue; 03497 case EINPROGRESS: 03498 res = 0; 03499 break; 03500 default: 03501 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03502 res = 0; 03503 } 03504 } 03505 } while (res); 03506 return res; 03507 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 11511 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().
11512 { 11513 #define END_SILENCE_LEN 400 11514 #define HEADER_MS 50 11515 #define TRAILER_MS 5 11516 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 11517 #define ASCII_BYTES_PER_CHAR 80 11518 11519 unsigned char *buf,*mybuf; 11520 struct zt_pvt *p = c->tech_pvt; 11521 struct pollfd fds[1]; 11522 int size,res,fd,len,x; 11523 int bytes=0; 11524 /* Initial carrier (imaginary) */ 11525 float cr = 1.0; 11526 float ci = 0.0; 11527 float scont = 0.0; 11528 int index; 11529 11530 index = zt_get_index(c, p, 0); 11531 if (index < 0) { 11532 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 11533 return -1; 11534 } 11535 if (!text[0]) return(0); /* if nothing to send, dont */ 11536 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 11537 if (p->mate) 11538 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 11539 else 11540 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 11541 if (!buf) 11542 return -1; 11543 mybuf = buf; 11544 if (p->mate) { 11545 int codec = AST_LAW(p); 11546 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 11547 PUT_CLID_MARKMS; 11548 } 11549 /* Put actual message */ 11550 for (x = 0; text[x]; x++) { 11551 PUT_CLID(text[x]); 11552 } 11553 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 11554 PUT_CLID_MARKMS; 11555 } 11556 len = bytes; 11557 buf = mybuf; 11558 } else { 11559 len = tdd_generate(p->tdd, buf, text); 11560 if (len < 1) { 11561 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 11562 free(mybuf); 11563 return -1; 11564 } 11565 } 11566 memset(buf + len, 0x7f, END_SILENCE_LEN); 11567 len += END_SILENCE_LEN; 11568 fd = p->subs[index].zfd; 11569 while (len) { 11570 if (ast_check_hangup(c)) { 11571 free(mybuf); 11572 return -1; 11573 } 11574 size = len; 11575 if (size > READ_SIZE) 11576 size = READ_SIZE; 11577 fds[0].fd = fd; 11578 fds[0].events = POLLOUT | POLLPRI; 11579 fds[0].revents = 0; 11580 res = poll(fds, 1, -1); 11581 if (!res) { 11582 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 11583 continue; 11584 } 11585 /* if got exception */ 11586 if (fds[0].revents & POLLPRI) { 11587 ast_free(mybuf); 11588 return -1; 11589 } 11590 if (!(fds[0].revents & POLLOUT)) { 11591 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 11592 continue; 11593 } 11594 res = write(fd, buf, size); 11595 if (res != size) { 11596 if (res == -1) { 11597 free(mybuf); 11598 return -1; 11599 } 11600 if (option_debug) 11601 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 11602 break; 11603 } 11604 len -= size; 11605 buf += size; 11606 } 11607 free(mybuf); 11608 return(0); 11609 }
static int zt_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 1633 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().
01634 { 01635 int x, res; 01636 01637 x = hs; 01638 res = ioctl(fd, ZT_HOOK, &x); 01639 01640 if (res < 0) { 01641 if (errno == EINPROGRESS) 01642 return 0; 01643 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01644 } 01645 01646 return res; 01647 }
static int zt_setlaw | ( | int | zfd, | |
int | law | |||
) | [static] |
static int zt_setlinear | ( | int | zfd, | |
int | linear | |||
) | [static] |
Definition at line 943 of file chan_zap.c.
Referenced by send_callerid(), ss_thread(), zt_hangup(), zt_new(), zt_read(), and zt_write().
00944 { 00945 int res; 00946 res = ioctl(zfd, ZT_SETLINEAR, &linear); 00947 if (res) 00948 return res; 00949 return 0; 00950 }
static int zt_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2844 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().
02845 { 02846 char *cp; 02847 signed char *scp; 02848 int x; 02849 int index; 02850 struct zt_pvt *p = chan->tech_pvt, *pp; 02851 struct oprmode *oprmode; 02852 02853 02854 /* all supported options require data */ 02855 if (!data || (datalen < 1)) { 02856 errno = EINVAL; 02857 return -1; 02858 } 02859 02860 switch (option) { 02861 case AST_OPTION_TXGAIN: 02862 scp = (signed char *) data; 02863 index = zt_get_index(chan, p, 0); 02864 if (index < 0) { 02865 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02866 return -1; 02867 } 02868 if (option_debug) 02869 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02870 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02871 case AST_OPTION_RXGAIN: 02872 scp = (signed char *) data; 02873 index = zt_get_index(chan, p, 0); 02874 if (index < 0) { 02875 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 02876 return -1; 02877 } 02878 if (option_debug) 02879 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 02880 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 02881 case AST_OPTION_TONE_VERIFY: 02882 if (!p->dsp) 02883 break; 02884 cp = (char *) data; 02885 switch (*cp) { 02886 case 1: 02887 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 02888 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 02889 break; 02890 case 2: 02891 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 02892 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 02893 break; 02894 default: 02895 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 02896 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 02897 break; 02898 } 02899 break; 02900 case AST_OPTION_TDD: 02901 /* turn on or off TDD */ 02902 cp = (char *) data; 02903 p->mate = 0; 02904 if (!*cp) { /* turn it off */ 02905 if (option_debug) 02906 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 02907 if (p->tdd) 02908 tdd_free(p->tdd); 02909 p->tdd = 0; 02910 break; 02911 } 02912 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 02913 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 02914 zt_disable_ec(p); 02915 /* otherwise, turn it on */ 02916 if (!p->didtdd) { /* if havent done it yet */ 02917 unsigned char mybuf[41000], *buf; 02918 int size, res, fd, len; 02919 struct pollfd fds[1]; 02920 02921 buf = mybuf; 02922 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 02923 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 02924 len = 40000; 02925 index = zt_get_index(chan, p, 0); 02926 if (index < 0) { 02927 ast_log(LOG_WARNING, "No index in TDD?\n"); 02928 return -1; 02929 } 02930 fd = p->subs[index].zfd; 02931 while (len) { 02932 if (ast_check_hangup(chan)) 02933 return -1; 02934 size = len; 02935 if (size > READ_SIZE) 02936 size = READ_SIZE; 02937 fds[0].fd = fd; 02938 fds[0].events = POLLPRI | POLLOUT; 02939 fds[0].revents = 0; 02940 res = poll(fds, 1, -1); 02941 if (!res) { 02942 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 02943 continue; 02944 } 02945 /* if got exception */ 02946 if (fds[0].revents & POLLPRI) 02947 return -1; 02948 if (!(fds[0].revents & POLLOUT)) { 02949 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 02950 continue; 02951 } 02952 res = write(fd, buf, size); 02953 if (res != size) { 02954 if (res == -1) return -1; 02955 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 02956 break; 02957 } 02958 len -= size; 02959 buf += size; 02960 } 02961 p->didtdd = 1; /* set to have done it now */ 02962 } 02963 if (*cp == 2) { /* Mate mode */ 02964 if (p->tdd) 02965 tdd_free(p->tdd); 02966 p->tdd = 0; 02967 p->mate = 1; 02968 break; 02969 } 02970 if (!p->tdd) { /* if we dont have one yet */ 02971 p->tdd = tdd_new(); /* allocate one */ 02972 } 02973 break; 02974 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 02975 if (!p->dsp) 02976 break; 02977 cp = (char *) data; 02978 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 02979 *cp ? "ON" : "OFF", (int) *cp, chan->name); 02980 p->dtmfrelax = 0; 02981 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 02982 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 02983 break; 02984 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 02985 cp = (char *) data; 02986 if (!*cp) { 02987 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 02988 x = 0; 02989 zt_disable_ec(p); 02990 } else { 02991 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 02992 x = 1; 02993 } 02994 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 02995 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 02996 break; 02997 case AST_OPTION_OPRMODE: /* Operator services mode */ 02998 oprmode = (struct oprmode *) data; 02999 pp = oprmode->peer->tech_pvt; 03000 p->oprmode = pp->oprmode = 0; 03001 /* setup peers */ 03002 p->oprpeer = pp; 03003 pp->oprpeer = p; 03004 /* setup modes, if any */ 03005 if (oprmode->mode) 03006 { 03007 pp->oprmode = oprmode->mode; 03008 p->oprmode = -oprmode->mode; 03009 } 03010 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 03011 oprmode->mode, chan->name,oprmode->peer->name);; 03012 break; 03013 case AST_OPTION_ECHOCAN: 03014 cp = (char *) data; 03015 if (*cp) { 03016 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 03017 zt_enable_ec(p); 03018 } else { 03019 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 03020 zt_disable_ec(p); 03021 } 03022 break; 03023 } 03024 errno = 0; 03025 03026 return 0; 03027 }
static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1465 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echotraining, LOG_DEBUG, LOG_WARNING, SUB_REAL, and zt_pvt::subs.
Referenced by zt_answer(), and zt_handle_event().
01466 { 01467 int x; 01468 int res; 01469 if (p && p->echocancel && p->echotraining) { 01470 x = p->echotraining; 01471 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01472 if (res) 01473 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01474 else { 01475 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01476 } 01477 } else 01478 ast_log(LOG_DEBUG, "No echo training requested\n"); 01479 }
Definition at line 3048 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().
03049 { 03050 /* Unlink a specific slave or all slaves/masters from a given master */ 03051 int x; 03052 int hasslaves; 03053 if (!master) 03054 return; 03055 if (needlock) { 03056 ast_mutex_lock(&master->lock); 03057 if (slave) { 03058 while (ast_mutex_trylock(&slave->lock)) { 03059 DEADLOCK_AVOIDANCE(&master->lock); 03060 } 03061 } 03062 } 03063 hasslaves = 0; 03064 for (x = 0; x < MAX_SLAVES; x++) { 03065 if (master->slaves[x]) { 03066 if (!slave || (master->slaves[x] == slave)) { 03067 /* Take slave out of the conference */ 03068 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03069 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03070 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03071 master->slaves[x]->master = NULL; 03072 master->slaves[x] = NULL; 03073 } else 03074 hasslaves = 1; 03075 } 03076 if (!hasslaves) 03077 master->inconference = 0; 03078 } 03079 if (!slave) { 03080 if (master->master) { 03081 /* Take master out of the conference */ 03082 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03083 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03084 hasslaves = 0; 03085 for (x = 0; x < MAX_SLAVES; x++) { 03086 if (master->master->slaves[x] == master) 03087 master->master->slaves[x] = NULL; 03088 else if (master->master->slaves[x]) 03089 hasslaves = 1; 03090 } 03091 if (!hasslaves) 03092 master->master->inconference = 0; 03093 } 03094 master->master = NULL; 03095 } 03096 update_conf(master); 03097 if (needlock) { 03098 if (slave) 03099 ast_mutex_unlock(&slave->lock); 03100 ast_mutex_unlock(&master->lock); 03101 } 03102 }
static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 266 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00267 { 00268 int i, j = 0; 00269 i = ZT_IOMUX_SIGEVENT; 00270 if (ioctl(fd, ZT_IOMUX, &i) == -1) 00271 return -1; 00272 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00273 return -1; 00274 return j; 00275 }
static int zt_wink | ( | struct zt_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 5428 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05429 { 05430 int j; 05431 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05432 for (;;) 05433 { 05434 /* set bits of interest */ 05435 j = ZT_IOMUX_SIGEVENT; 05436 /* wait for some happening */ 05437 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05438 /* exit loop if we have it */ 05439 if (j & ZT_IOMUX_SIGEVENT) break; 05440 } 05441 /* get the event info */ 05442 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05443 return 0; 05444 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4960 of file chan_zap.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, zt_pvt::dialing, zt_pvt::digital, errno, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, my_zt_write(), option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_setlinear().
04961 { 04962 struct zt_pvt *p = ast->tech_pvt; 04963 int res; 04964 int index; 04965 index = zt_get_index(ast, p, 0); 04966 if (index < 0) { 04967 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 04968 return -1; 04969 } 04970 04971 #if 0 04972 #ifdef HAVE_PRI 04973 ast_mutex_lock(&p->lock); 04974 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04975 if (p->pri->pri) { 04976 if (!pri_grab(p, p->pri)) { 04977 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04978 pri_rel(p->pri); 04979 } else 04980 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04981 } 04982 p->proceeding=1; 04983 } 04984 ast_mutex_unlock(&p->lock); 04985 #endif 04986 #endif 04987 /* Write a frame of (presumably voice) data */ 04988 if (frame->frametype != AST_FRAME_VOICE) { 04989 if (frame->frametype != AST_FRAME_IMAGE) 04990 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 04991 return 0; 04992 } 04993 if ((frame->subclass != AST_FORMAT_SLINEAR) && 04994 (frame->subclass != AST_FORMAT_ULAW) && 04995 (frame->subclass != AST_FORMAT_ALAW)) { 04996 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 04997 return -1; 04998 } 04999 if (p->dialing) { 05000 if (option_debug) 05001 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 05002 return 0; 05003 } 05004 if (!p->owner) { 05005 if (option_debug) 05006 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 05007 return 0; 05008 } 05009 if (p->cidspill) { 05010 if (option_debug) 05011 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 05012 return 0; 05013 } 05014 /* Return if it's not valid data */ 05015 if (!frame->data || !frame->datalen) 05016 return 0; 05017 05018 if (frame->subclass == AST_FORMAT_SLINEAR) { 05019 if (!p->subs[index].linear) { 05020 p->subs[index].linear = 1; 05021 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05022 if (res) 05023 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 05024 } 05025 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 05026 } else { 05027 /* x-law already */ 05028 if (p->subs[index].linear) { 05029 p->subs[index].linear = 0; 05030 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05031 if (res) 05032 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 05033 } 05034 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 05035 } 05036 if (res < 0) { 05037 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05038 return -1; 05039 } 05040 return 0; 05041 }
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 762 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 773 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 166 of file chan_zap.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 110 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 205 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 206 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 10261 of file chan_zap.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 210 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 117 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 236 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 230 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 248 of file chan_zap.c.
char* name |
Definition at line 1144 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 759 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 212 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 208 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 291 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 10253 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 10249 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 160 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 760 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
char zap_restart_usage[] [static] |
Definition at line 10265 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 10157 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 10257 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 712 of file chan_zap.c.
Referenced by __unload_module(), load_module(), ss_thread(), and zt_new().